diff --git a/DEPS b/DEPS index 042d826..b14694d8 100644 --- a/DEPS +++ b/DEPS
@@ -39,11 +39,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'c988d2c1c840689e89a7bbcf39cf10ff818708ae', + 'skia_revision': 'bf90520f63415f539cd5792a18efbd79cb86be0a', # 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': '6c1ae369aed18a148e0062adf7203b905d78a1d2', + 'v8_revision': '8ec2f9cfc4a1852fdcb5b1965637c258bc22ba66', # 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. @@ -181,13 +181,13 @@ Var('chromium_git') + '/external/bidichecker/lib.git' + '@' + '97f2aa645b74c28c57eca56992235c79850fa9e0', 'src/third_party/webgl/src': - Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '397fdf9245912ce37a01611b7a0ad02cd80de89f', + Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '421bc6095d1065bb6057e33fbab737b35d39930d', 'src/third_party/webdriver/pylib': Var('chromium_git') + '/external/selenium/py.git' + '@' + '5fd78261a75fe08d27ca4835fb6c5ce4b42275bd', 'src/third_party/libvpx_new/source/libvpx': - Var('chromium_git') + '/webm/libvpx.git' + '@' + '7d28d12ef34f6cbb6b1e18f3b23b71392fd3ddf5', + Var('chromium_git') + '/webm/libvpx.git' + '@' + 'ce3f4ade670cf02e05998f4ca50e08736802f5e7', 'src/third_party/ffmpeg': Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '525a71ab8ee3b61da48138f7e1c406989d2879fc',
diff --git a/WATCHLISTS b/WATCHLISTS index 5082c5f..75b4273 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -1230,7 +1230,9 @@ 'blimp' : ['dtrainor+watch-blimp@chromium.org', 'kmarshall+watch-blimp@chromium.org', 'maniscalco+watch-blimp@chromium.org', - 'nyquist+watch-blimp@chromium.org'], + 'marcinjb+watch-blimp@chromium.org', + 'nyquist+watch-blimp@chromium.org', + 'sriramsr+watch-blimp@chromium.org'], 'bookmarks': ['noyau+watch@chromium.org', 'tfarina@chromium.org'], 'browser_chromeos': ['davemoore+watch@chromium.org'], 'browser_components': ['browser-components-watch@chromium.org'],
diff --git a/base/profiler/native_stack_sampler_win.cc b/base/profiler/native_stack_sampler_win.cc index bc935c0..80121b2 100644 --- a/base/profiler/native_stack_sampler_win.cc +++ b/base/profiler/native_stack_sampler_win.cc
@@ -4,11 +4,17 @@ #include <objbase.h> #include <windows.h> +#include <winternl.h> +#include <cstdlib> #include <map> #include <utility> +#include <vector> +#include "base/lazy_instance.h" #include "base/logging.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" #include "base/profiler/native_stack_sampler.h" #include "base/profiler/win32_stack_frame_unwinder.h" #include "base/strings/string_util.h" @@ -24,17 +30,121 @@ namespace { +// The thread environment block internal type. +struct TEB { + NT_TIB Tib; + // Rest of struct is ignored. +}; + +// Returns the thread environment block pointer for |thread_handle|. +const TEB* GetThreadEnvironmentBlock(HANDLE thread_handle) { + // Define the internal types we need to invoke NtQueryInformationThread. + enum THREAD_INFORMATION_CLASS { ThreadBasicInformation }; + + struct CLIENT_ID { + HANDLE UniqueProcess; + HANDLE UniqueThread; + }; + + struct THREAD_BASIC_INFORMATION { + NTSTATUS ExitStatus; + TEB* Teb; + CLIENT_ID ClientId; + KAFFINITY AffinityMask; + LONG Priority; + LONG BasePriority; + }; + + using NtQueryInformationThreadFunction = + NTSTATUS (WINAPI*)(HANDLE, THREAD_INFORMATION_CLASS, PVOID, ULONG, + PULONG); + + const NtQueryInformationThreadFunction nt_query_information_thread = + reinterpret_cast<NtQueryInformationThreadFunction>( + ::GetProcAddress(::GetModuleHandle(L"ntdll.dll"), + "NtQueryInformationThread")); + if (!nt_query_information_thread) + return nullptr; + + THREAD_BASIC_INFORMATION basic_info = {0}; + NTSTATUS status = + nt_query_information_thread(thread_handle, ThreadBasicInformation, + &basic_info, sizeof(THREAD_BASIC_INFORMATION), + nullptr); + if (status != 0) + return nullptr; + + return basic_info.Teb; +} + +// If the value at |pointer| points to the original stack, rewrite it to point +// to the corresponding location in the copied stack. +void RewritePointerIfInOriginalStack(uintptr_t top, uintptr_t bottom, + void* stack_copy, const void** pointer) { + const uintptr_t value = reinterpret_cast<uintptr_t>(*pointer); + if (value >= bottom && value < top) { + *pointer = reinterpret_cast<const void*>( + static_cast<unsigned char*>(stack_copy) + (value - bottom)); + } +} + +// Rewrites possible pointers to locations within the stack to point to the +// corresponding locations in the copy, and rewrites the non-volatile registers +// in |context| likewise. This is necessary to handle stack frames with dynamic +// stack allocation, where a pointer to the beginning of the dynamic allocation +// area is stored on the stack and/or in a non-volatile register. +// +// Eager rewriting of anything that looks like a pointer to the stack, as done +// in this function, does not adversely affect the stack unwinding. The only +// other values on the stack the unwinding depends on are return addresses, +// which should not point within the stack memory. The rewriting is guaranteed +// to catch all pointers because the stacks are guaranteed by the ABI to be +// sizeof(void*) aligned. +// +// Note: this function must not access memory in the original stack as it may +// have been changed or deallocated by this point. This is why |top| and +// |bottom| are passed as uintptr_t. +void RewritePointersToStackMemory(uintptr_t top, uintptr_t bottom, + CONTEXT* context, void* stack_copy) { +#if defined(_WIN64) + DWORD64 CONTEXT::* const nonvolatile_registers[] = { + &CONTEXT::R12, + &CONTEXT::R13, + &CONTEXT::R14, + &CONTEXT::R15, + &CONTEXT::Rdi, + &CONTEXT::Rsi, + &CONTEXT::Rbx, + &CONTEXT::Rbp, + &CONTEXT::Rsp + }; + + // Rewrite pointers in the context. + for (size_t i = 0; i < arraysize(nonvolatile_registers); ++i) { + DWORD64* const reg = &(context->*nonvolatile_registers[i]); + RewritePointerIfInOriginalStack(top, bottom, stack_copy, + reinterpret_cast<const void**>(reg)); + } + + // Rewrite pointers on the stack. + const void** start = reinterpret_cast<const void**>(stack_copy); + const void** end = reinterpret_cast<const void**>( + reinterpret_cast<char*>(stack_copy) + (top - bottom)); + for (const void** loc = start; loc < end; ++loc) + RewritePointerIfInOriginalStack(top, bottom, stack_copy, loc); +#endif +} + // Walks the stack represented by |context| from the current frame downwards, // recording the instruction pointers for each frame in |instruction_pointers|. -int RecordStack(CONTEXT* context, - int max_stack_size, - const void* instruction_pointers[], - Win32StackFrameUnwinder* frame_unwinder) { +int RecordStack(CONTEXT* context, int max_stack_size, + const void* instruction_pointers[]) { #ifdef _WIN64 + Win32StackFrameUnwinder frame_unwinder; int i = 0; for (; (i < max_stack_size) && context->Rip; ++i) { instruction_pointers[i] = reinterpret_cast<const void*>(context->Rip); - if (!frame_unwinder->TryUnwind(context)) + if (!frame_unwinder.TryUnwind(context)) return i + 1; } return i; @@ -133,29 +243,31 @@ ::SetThreadPriorityBoost(thread_handle_, boost_state_was_disabled_); } -// Suspends the thread with |thread_handle|, records the stack into -// |instruction_pointers|, then resumes the thread. Returns the size of the -// stack. -// -// IMPORTANT NOTE: No heap allocations may occur between SuspendThread and -// ResumeThread. Otherwise this code can deadlock on heap locks acquired by the -// target thread before it was suspended. This is why we pass instruction -// pointers and module handles as preallocated arrays rather than vectors, since -// vectors make it too easy to subtly allocate memory. -int SuspendThreadAndRecordStack(HANDLE thread_handle, int max_stack_size, - const void* instruction_pointers[]) { - Win32StackFrameUnwinder frame_unwinder; +// ScopedSuspendThread -------------------------------------------------------- - if (::SuspendThread(thread_handle) == -1) - return 0; +// Suspends a thread for the lifetime of the object. +class ScopedSuspendThread { + public: + ScopedSuspendThread(HANDLE thread_handle); + ~ScopedSuspendThread(); - int stack_depth = 0; - CONTEXT thread_context = {0}; - thread_context.ContextFlags = CONTEXT_FULL; - if (::GetThreadContext(thread_handle, &thread_context)) { - stack_depth = RecordStack(&thread_context, max_stack_size, - instruction_pointers, &frame_unwinder); - } + bool was_successful() const { return was_successful_; } + + private: + HANDLE thread_handle_; + bool was_successful_; + + DISALLOW_COPY_AND_ASSIGN(ScopedSuspendThread); +}; + +ScopedSuspendThread::ScopedSuspendThread(HANDLE thread_handle) + : thread_handle_(thread_handle), + was_successful_(::SuspendThread(thread_handle) != -1) { +} + +ScopedSuspendThread::~ScopedSuspendThread() { + if (!was_successful_) + return; // Disable the priority boost that the thread would otherwise receive on // resume. We do this to avoid artificially altering the dynamics of the @@ -167,11 +279,58 @@ // conditions at the time of SuspendThread and those conditions are satisfied // before priority boost is reenabled. The measured length of this window is // ~100us, so this should occur fairly rarely. - ScopedDisablePriorityBoost disable_priority_boost(thread_handle); - bool resume_thread_succeeded = ::ResumeThread(thread_handle) != -1; + ScopedDisablePriorityBoost disable_priority_boost(thread_handle_); + bool resume_thread_succeeded = ::ResumeThread(thread_handle_) != -1; CHECK(resume_thread_succeeded) << "ResumeThread failed: " << GetLastError(); +} - return stack_depth; +// Suspends the thread with |thread_handle|, copies its stack and resumes the +// thread, then records the stack into |instruction_pointers|. Returns the size +// of the stack. +// +// IMPORTANT NOTE: No allocations from the default heap may occur in the +// ScopedSuspendThread scope, including indirectly via use of DCHECK/CHECK or +// other logging statements. Otherwise this code can deadlock on heap locks in +// the default heap acquired by the target thread before it was suspended. This +// is why we pass instruction pointers as preallocated arrays. +int SuspendThreadAndRecordStack(HANDLE thread_handle, + const void* base_address, + void* stack_copy_buffer, + size_t stack_copy_buffer_size, + int max_stack_size, + const void* instruction_pointers[]) { + CONTEXT thread_context = {0}; + thread_context.ContextFlags = CONTEXT_FULL; + // The stack bounds are saved to uintptr_ts for use outside + // ScopedSuspendThread, as the thread's memory is not safe to dereference + // beyond that point. + const uintptr_t top = reinterpret_cast<uintptr_t>(base_address); + uintptr_t bottom = 0u; + + { + ScopedSuspendThread suspend_thread(thread_handle); + + if (!suspend_thread.was_successful()) + return 0; + + if (!::GetThreadContext(thread_handle, &thread_context)) + return 0; +#if defined(_WIN64) + bottom = thread_context.Rsp; +#else + bottom = thread_context.Esp; +#endif + + if ((top - bottom) > stack_copy_buffer_size) + return 0; + + std::memcpy(stack_copy_buffer, reinterpret_cast<const void*>(bottom), + top - bottom); + } + + RewritePointersToStackMemory(top, bottom, &thread_context, stack_copy_buffer); + + return RecordStack(&thread_context, max_stack_size, instruction_pointers); } // NativeStackSamplerWin ------------------------------------------------------ @@ -188,6 +347,15 @@ void ProfileRecordingStopped() override; private: + enum { + // Intended to hold the largest stack used by Chrome. The default Win32 + // reserved stack size is 1 MB and Chrome Windows threads currently always + // use the default, but this allows for expansion if it occurs. The size + // beyond the actual stack size consists of unallocated virtual memory pages + // so carries little cost (just a bit of wated address space). + kStackCopyBufferSize = 2 * 1024 * 1024 + }; + // Attempts to query the module filename, base address, and id for // |module_handle|, and store them in |module|. Returns true if it succeeded. static bool GetModuleForHandle(HMODULE module_handle, @@ -209,9 +377,18 @@ std::vector<StackSamplingProfiler::Module>* modules); win::ScopedHandle thread_handle_; + + // The stack base address corresponding to |thread_handle_|. + const void* const thread_stack_base_address_; + + // Buffer to use for copies of the stack. We use the same buffer for all the + // samples to avoid the overhead of multiple allocations and frees. + const scoped_ptr<unsigned char[]> stack_copy_buffer_; + // Weak. Points to the modules associated with the profile being recorded // between ProfileRecordingStarting() and ProfileRecordingStopped(). std::vector<StackSamplingProfiler::Module>* current_modules_; + // Maps a module handle to the corresponding Module's index within // current_modules_. std::map<HMODULE, size_t> profile_module_index_; @@ -220,7 +397,10 @@ }; NativeStackSamplerWin::NativeStackSamplerWin(win::ScopedHandle thread_handle) - : thread_handle_(thread_handle.Take()) { + : thread_handle_(thread_handle.Take()), + thread_stack_base_address_( + GetThreadEnvironmentBlock(thread_handle_.Get())->Tib.StackBase), + stack_copy_buffer_(new unsigned char[kStackCopyBufferSize]) { } NativeStackSamplerWin::~NativeStackSamplerWin() { @@ -236,11 +416,17 @@ StackSamplingProfiler::Sample* sample) { DCHECK(current_modules_); + if (!stack_copy_buffer_) + return; + const int max_stack_size = 64; const void* instruction_pointers[max_stack_size] = {0}; HMODULE module_handles[max_stack_size] = {0}; int stack_depth = SuspendThreadAndRecordStack(thread_handle_.Get(), + thread_stack_base_address_, + stack_copy_buffer_.get(), + kStackCopyBufferSize, max_stack_size, instruction_pointers); FindModuleHandlesForAddresses(instruction_pointers, module_handles,
diff --git a/base/profiler/stack_sampling_profiler_unittest.cc b/base/profiler/stack_sampling_profiler_unittest.cc index 41aa693..10f11e1 100644 --- a/base/profiler/stack_sampling_profiler_unittest.cc +++ b/base/profiler/stack_sampling_profiler_unittest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <cstdlib> + #include "base/bind.h" #include "base/compiler_specific.h" #include "base/memory/scoped_vector.h" @@ -13,14 +15,26 @@ #include "base/synchronization/waitable_event.h" #include "base/threading/platform_thread.h" #include "base/time/time.h" +#include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" +#if defined(OS_WIN) +#include <intrin.h> +#include <malloc.h> +#else +#include <alloca.h> +#endif + // STACK_SAMPLING_PROFILER_SUPPORTED is used to conditionally enable the tests // below for supported platforms (currently Win x64). #if defined(_WIN64) #define STACK_SAMPLING_PROFILER_SUPPORTED 1 #endif +#if defined(OS_WIN) +#pragma intrinsic(_ReturnAddress) +#endif + namespace base { using SamplingParams = StackSamplingProfiler::SamplingParams; @@ -32,11 +46,19 @@ namespace { +// Configuration for whether to allocate dynamic stack memory. +enum DynamicStackAllocationConfig { USE_ALLOCA, NO_ALLOCA }; + +// Signature for a target function that is expected to appear in the stack. See +// SignalAndWaitUntilSignaled() below. The return value should be a program +// counter pointer near the end of the function. +using TargetFunction = const void*(*)(WaitableEvent*, WaitableEvent*); + // A thread to target for profiling, whose stack is guaranteed to contain // SignalAndWaitUntilSignaled() when coordinated with the main thread. class TargetThread : public PlatformThread::Delegate { public: - TargetThread(); + TargetThread(DynamicStackAllocationConfig allocation_config); // PlatformThread::Delegate: void ThreadMain() override; @@ -50,30 +72,53 @@ void SignalThreadToFinish(); // This function is guaranteed to be executing between calls to - // WaitForThreadStart() and SignalThreadToFinish(). This function is static so - // that we can get a straightforward address for it in one of the tests below, - // rather than dealing with the complexity of a member function pointer - // representation. - static void SignalAndWaitUntilSignaled(WaitableEvent* thread_started_event, - WaitableEvent* finish_event); + // WaitForThreadStart() and SignalThreadToFinish() when invoked with + // |thread_started_event_| and |finish_event_|. Returns a program counter + // value near the end of the function. May be invoked with null WaitableEvents + // to just return the program counter. + // + // This function is static so that we can get a straightforward address + // for it in one of the tests below, rather than dealing with the complexity + // of a member function pointer representation. + static const void* SignalAndWaitUntilSignaled( + WaitableEvent* thread_started_event, + WaitableEvent* finish_event); + + // Works like SignalAndWaitUntilSignaled() but additionally allocates memory + // on the stack with alloca. Note that this must be a separate function from + // SignalAndWaitUntilSignaled because on Windows x64 the compiler sets up + // dynamic frame handling whenever alloca appears in a function, even if only + // conditionally invoked. + static const void* SignalAndWaitUntilSignaledWithAlloca( + WaitableEvent* thread_started_event, + WaitableEvent* finish_event); PlatformThreadId id() const { return id_; } private: + // Returns the current program counter, or a value very close to it. + static const void* GetProgramCounter(); + WaitableEvent thread_started_event_; WaitableEvent finish_event_; PlatformThreadId id_; + const DynamicStackAllocationConfig allocation_config_; DISALLOW_COPY_AND_ASSIGN(TargetThread); }; -TargetThread::TargetThread() +TargetThread::TargetThread(DynamicStackAllocationConfig allocation_config) : thread_started_event_(false, false), finish_event_(false, false), - id_(0) {} + id_(0), allocation_config_(allocation_config) {} void TargetThread::ThreadMain() { id_ = PlatformThread::CurrentId(); - SignalAndWaitUntilSignaled(&thread_started_event_, &finish_event_); + if (allocation_config_ == USE_ALLOCA) { + SignalAndWaitUntilSignaledWithAlloca(&thread_started_event_, + &finish_event_); + } else { + SignalAndWaitUntilSignaled(&thread_started_event_, &finish_event_); + } } void TargetThread::WaitForThreadStart() { @@ -86,16 +131,49 @@ // static // Disable inlining for this function so that it gets its own stack frame. -NOINLINE void TargetThread::SignalAndWaitUntilSignaled( +NOINLINE const void* TargetThread::SignalAndWaitUntilSignaled( WaitableEvent* thread_started_event, WaitableEvent* finish_event) { - thread_started_event->Signal(); - volatile int x = 1; - finish_event->Wait(); - x = 0; // Prevent tail call to WaitableEvent::Wait(). - ALLOW_UNUSED_LOCAL(x); + if (thread_started_event && finish_event) { + thread_started_event->Signal(); + finish_event->Wait(); + } + + // Volatile to prevent a tail call to GetProgramCounter(). + const void* volatile program_counter = GetProgramCounter(); + return program_counter; } +// static +// Disable inlining for this function so that it gets its own stack frame. +NOINLINE const void* TargetThread::SignalAndWaitUntilSignaledWithAlloca( + WaitableEvent* thread_started_event, + WaitableEvent* finish_event) { + const size_t alloca_size = 100; + // Memset to 0 to generate a clean failure. + std::memset(alloca(alloca_size), 0, alloca_size); + + if (thread_started_event && finish_event) { + thread_started_event->Signal(); + finish_event->Wait(); + } + + // Volatile to prevent a tail call to GetProgramCounter(). + const void* volatile program_counter = GetProgramCounter(); + return program_counter; +} + +// static +// Disable inlining for this function so that it gets its own stack frame. +NOINLINE const void* TargetThread::GetProgramCounter() { +#if defined(OS_WIN) + return _ReturnAddress(); +#else + return __builtin_return_address(0); +#endif +} + + // Called on the profiler thread when complete, to collect profiles. void SaveProfiles(CallStackProfiles* profiles, const CallStackProfiles& pending_profiles) { @@ -113,11 +191,13 @@ } // Executes the function with the target thread running and executing within -// SignalAndWaitUntilSignaled(). Performs all necessary target thread startup -// and shutdown work before and afterward. +// SignalAndWaitUntilSignaled() or SignalAndWaitUntilSignaledWithAlloca(), +// depending on the value of |allocation_config|. Performs all necessary target +// thread startup and shutdown work before and afterward. template <class Function> -void WithTargetThread(Function function) { - TargetThread target_thread; +void WithTargetThread(Function function, + DynamicStackAllocationConfig allocation_config) { + TargetThread target_thread(allocation_config); PlatformThreadHandle target_thread_handle; EXPECT_TRUE(PlatformThread::Create(0, &target_thread, &target_thread_handle)); @@ -130,6 +210,11 @@ PlatformThread::Join(target_thread_handle); } +template <class Function> +void WithTargetThread(Function function) { + WithTargetThread(function, NO_ALLOCA); +} + // Captures profiles as specified by |params| on the TargetThread, and returns // them in |profiles|. Waits up to |profiler_wait_time| for the profiler to // complete. @@ -174,19 +259,19 @@ } // Searches through the frames in |sample|, returning an iterator to the first -// frame that has an instruction pointer between |function_address| and -// |function_address| + |size|. Returns sample.end() if no such frames are -// found. +// frame that has an instruction pointer within |target_function|. Returns +// sample.end() if no such frames are found. Sample::const_iterator FindFirstFrameWithinFunction( const Sample& sample, - const void* function_address, - int function_size) { - function_address = MaybeFixupFunctionAddressForILT(function_address); + TargetFunction target_function) { + uintptr_t function_start = reinterpret_cast<uintptr_t>( + MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( + target_function))); + uintptr_t function_end = + reinterpret_cast<uintptr_t>(target_function(nullptr, nullptr)); for (auto it = sample.begin(); it != sample.end(); ++it) { - if ((reinterpret_cast<const void*>(it->instruction_pointer) >= - function_address) && - (reinterpret_cast<const void*>(it->instruction_pointer) < - (static_cast<const unsigned char*>(function_address) + function_size))) + if ((it->instruction_pointer >= function_start) && + (it->instruction_pointer <= function_end)) return it; } return sample.end(); @@ -241,18 +326,13 @@ // Check that the stack contains a frame for // TargetThread::SignalAndWaitUntilSignaled() and that the frame has this // executable's module. - // - // Since we don't have a good way to know the function size, use 100 bytes as - // a reasonable window to locate the instruction pointer. Sample::const_iterator loc = FindFirstFrameWithinFunction( sample, - reinterpret_cast<const void*>(&TargetThread::SignalAndWaitUntilSignaled), - 100); + &TargetThread::SignalAndWaitUntilSignaled); ASSERT_TRUE(loc != sample.end()) << "Function at " - << MaybeFixupFunctionAddressForILT( - reinterpret_cast<const void*>( - &TargetThread::SignalAndWaitUntilSignaled)) + << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( + &TargetThread::SignalAndWaitUntilSignaled)) << " was not found in stack:\n" << FormatSampleForDiagnosticOutput(sample, profile.modules); FilePath executable_path; @@ -260,6 +340,49 @@ EXPECT_EQ(executable_path, profile.modules[loc->module_index].filename); } +// Checks that the profiler handles stacks containing dynamically-allocated +// stack memory. +#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) +#define MAYBE_Alloca Alloca +#else +#define MAYBE_Alloca DISABLED_Alloca +#endif +TEST(StackSamplingProfilerTest, MAYBE_Alloca) { + SamplingParams params; + params.sampling_interval = TimeDelta::FromMilliseconds(0); + params.samples_per_burst = 1; + + std::vector<CallStackProfile> profiles; + WithTargetThread([¶ms, &profiles]( + PlatformThreadId target_thread_id) { + WaitableEvent sampling_thread_completed(true, false); + const StackSamplingProfiler::CompletedCallback callback = + Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles), + Unretained(&sampling_thread_completed)); + StackSamplingProfiler profiler(target_thread_id, params, callback); + profiler.Start(); + sampling_thread_completed.Wait(); + }, USE_ALLOCA); + + // Look up the sample. + ASSERT_EQ(1u, profiles.size()); + const CallStackProfile& profile = profiles[0]; + ASSERT_EQ(1u, profile.samples.size()); + const Sample& sample = profile.samples[0]; + + // Check that the stack contains a frame for + // TargetThread::SignalAndWaitUntilSignaledWithAlloca(). + Sample::const_iterator loc = FindFirstFrameWithinFunction( + sample, + &TargetThread::SignalAndWaitUntilSignaledWithAlloca); + ASSERT_TRUE(loc != sample.end()) + << "Function at " + << MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>( + &TargetThread::SignalAndWaitUntilSignaledWithAlloca)) + << " was not found in stack:\n" + << FormatSampleForDiagnosticOutput(sample, profile.modules); +} + // Checks that the fire-and-forget interface works. #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) #define MAYBE_StartAndRunAsync StartAndRunAsync
diff --git a/base/profiler/win32_stack_frame_unwinder.cc b/base/profiler/win32_stack_frame_unwinder.cc index 4ab3a3e..3bdd288 100644 --- a/base/profiler/win32_stack_frame_unwinder.cc +++ b/base/profiler/win32_stack_frame_unwinder.cc
@@ -10,10 +10,61 @@ namespace base { -// LeafUnwindBlacklist -------------------------------------------------------- +// Win32UnwindFunctions ------------------------------------------------------- namespace { +// Implements the UnwindFunctions interface for the corresponding Win32 +// functions. +class Win32UnwindFunctions : public Win32StackFrameUnwinder::UnwindFunctions { +public: + Win32UnwindFunctions(); + ~Win32UnwindFunctions() override; + + PRUNTIME_FUNCTION LookupFunctionEntry(DWORD64 program_counter, + PDWORD64 image_base) override; + + void VirtualUnwind(DWORD64 image_base, + DWORD64 program_counter, + PRUNTIME_FUNCTION runtime_function, + CONTEXT* context) override; + +private: + DISALLOW_COPY_AND_ASSIGN(Win32UnwindFunctions); +}; + +Win32UnwindFunctions::Win32UnwindFunctions() {} +Win32UnwindFunctions::~Win32UnwindFunctions() {} + +PRUNTIME_FUNCTION Win32UnwindFunctions::LookupFunctionEntry( + DWORD64 program_counter, + PDWORD64 image_base) { +#ifdef _WIN64 + return RtlLookupFunctionEntry(program_counter, image_base, nullptr); +#else + NOTREACHED(); + return nullptr; +#endif +} + +void Win32UnwindFunctions::VirtualUnwind(DWORD64 image_base, + DWORD64 program_counter, + PRUNTIME_FUNCTION runtime_function, + CONTEXT* context) { +#ifdef _WIN64 + void* handler_data; + ULONG64 establisher_frame; + KNONVOLATILE_CONTEXT_POINTERS nvcontext = {}; + RtlVirtualUnwind(UNW_FLAG_NHANDLER, image_base, program_counter, + runtime_function, context, &handler_data, + &establisher_frame, &nvcontext); +#else + NOTREACHED(); +#endif +} + +// LeafUnwindBlacklist -------------------------------------------------------- + // Records modules that are known to have functions that violate the Microsoft // x64 calling convention and would be dangerous to manually unwind if // encountered as the last frame on the call stack. Functions like these have @@ -26,13 +77,11 @@ public: static LeafUnwindBlacklist* GetInstance(); - // This function does not allocate memory and is safe to call between - // SuspendThread and ResumeThread. + // Returns true if |module| has been blacklisted. bool IsBlacklisted(const void* module) const; - // Allocates memory. Must be invoked only after ResumeThread, otherwise we - // risk deadlocking on a heap lock held by a suspended thread. - void AddModuleToBlacklist(const void* module); + // Records |module| for blacklisting. + void BlacklistModule(const void* module); private: friend struct DefaultSingletonTraits<LeafUnwindBlacklist>; @@ -49,7 +98,7 @@ // static LeafUnwindBlacklist* LeafUnwindBlacklist::GetInstance() { - // Leaky for shutdown performance. + // Leaky for performance reasons. return Singleton<LeafUnwindBlacklist, LeakySingletonTraits<LeafUnwindBlacklist>>::get(); } @@ -58,7 +107,7 @@ return ContainsKey(blacklisted_modules_, module); } -void LeafUnwindBlacklist::AddModuleToBlacklist(const void* module) { +void LeafUnwindBlacklist::BlacklistModule(const void* module) { CHECK(module); blacklisted_modules_.insert(module); } @@ -73,50 +122,15 @@ Win32StackFrameUnwinder::UnwindFunctions::~UnwindFunctions() {} Win32StackFrameUnwinder::UnwindFunctions::UnwindFunctions() {} -Win32StackFrameUnwinder::Win32UnwindFunctions::Win32UnwindFunctions() {} - -PRUNTIME_FUNCTION Win32StackFrameUnwinder::Win32UnwindFunctions:: -LookupFunctionEntry(DWORD64 program_counter, PDWORD64 image_base) { -#ifdef _WIN64 - return RtlLookupFunctionEntry(program_counter, image_base, nullptr); -#else - NOTREACHED(); - return nullptr; -#endif -} - -void Win32StackFrameUnwinder::Win32UnwindFunctions::VirtualUnwind( - DWORD64 image_base, - DWORD64 program_counter, - PRUNTIME_FUNCTION runtime_function, - CONTEXT* context) { -#ifdef _WIN64 - void* handler_data; - ULONG64 establisher_frame; - KNONVOLATILE_CONTEXT_POINTERS nvcontext = {}; - RtlVirtualUnwind(0, image_base, program_counter, runtime_function, - context, &handler_data, &establisher_frame, &nvcontext); -#else - NOTREACHED(); -#endif -} - - Win32StackFrameUnwinder::Win32StackFrameUnwinder() - : Win32StackFrameUnwinder(&win32_unwind_functions_) { + : Win32StackFrameUnwinder(make_scoped_ptr(new Win32UnwindFunctions)) { } -Win32StackFrameUnwinder::~Win32StackFrameUnwinder() { - if (pending_blacklisted_module_) { - LeafUnwindBlacklist::GetInstance()->AddModuleToBlacklist( - pending_blacklisted_module_); - } -} +Win32StackFrameUnwinder::~Win32StackFrameUnwinder() {} bool Win32StackFrameUnwinder::TryUnwind(CONTEXT* context) { #ifdef _WIN64 CHECK(!at_top_frame_ || unwind_info_present_for_all_frames_); - CHECK(!pending_blacklisted_module_); ULONG64 image_base; // Try to look up unwind metadata for the current function. @@ -179,8 +193,8 @@ if (unwind_info_present_for_all_frames_) { // Unwind information was present for all previous frames, so we can // be confident this is case 2. Record the module to be blacklisted. - pending_blacklisted_module_ = - reinterpret_cast<const void *>(image_base); + LeafUnwindBlacklist::GetInstance()->BlacklistModule( + reinterpret_cast<const void *>(image_base)); } else { // We started off on a function without unwind information. It's very // likely that all frames up to this point have been good, and this @@ -202,11 +216,10 @@ } Win32StackFrameUnwinder::Win32StackFrameUnwinder( - UnwindFunctions* unwind_functions) + scoped_ptr<UnwindFunctions> unwind_functions) : at_top_frame_(true), unwind_info_present_for_all_frames_(true), - pending_blacklisted_module_(nullptr), - unwind_functions_(unwind_functions) { + unwind_functions_(unwind_functions.Pass()) { } } // namespace base
diff --git a/base/profiler/win32_stack_frame_unwinder.h b/base/profiler/win32_stack_frame_unwinder.h index a45d577..4ddf76e 100644 --- a/base/profiler/win32_stack_frame_unwinder.h +++ b/base/profiler/win32_stack_frame_unwinder.h
@@ -9,6 +9,7 @@ #include "base/base_export.h" #include "base/macros.h" +#include "base/memory/scoped_ptr.h" namespace base { @@ -19,7 +20,8 @@ #endif // !defined(_WIN64) // Instances of this class are expected to be created and destroyed for each -// stack unwinding, outside of SuspendThread/ResumeThread. +// stack unwinding. This class is not used while the target thread is suspended, +// so may allocate from the default heap. class BASE_EXPORT Win32StackFrameUnwinder { public: // Interface for Win32 unwind-related functionality this class depends @@ -41,39 +43,21 @@ DISALLOW_COPY_AND_ASSIGN(UnwindFunctions); }; - class BASE_EXPORT Win32UnwindFunctions : public UnwindFunctions { - public: - Win32UnwindFunctions(); - - PRUNTIME_FUNCTION LookupFunctionEntry(DWORD64 program_counter, - PDWORD64 image_base) override; - - void VirtualUnwind(DWORD64 image_base, - DWORD64 program_counter, - PRUNTIME_FUNCTION runtime_function, - CONTEXT* context) override; - - private: - DISALLOW_COPY_AND_ASSIGN(Win32UnwindFunctions); - }; - Win32StackFrameUnwinder(); ~Win32StackFrameUnwinder(); bool TryUnwind(CONTEXT* context); private: - // This function is for test purposes only. - Win32StackFrameUnwinder(UnwindFunctions* unwind_functions); + // This function is for internal and test purposes only. + Win32StackFrameUnwinder(scoped_ptr<UnwindFunctions> unwind_functions); friend class Win32StackFrameUnwinderTest; // State associated with each stack unwinding. bool at_top_frame_; bool unwind_info_present_for_all_frames_; - const void* pending_blacklisted_module_; - Win32UnwindFunctions win32_unwind_functions_; - UnwindFunctions* const unwind_functions_; + scoped_ptr<UnwindFunctions> unwind_functions_; DISALLOW_COPY_AND_ASSIGN(Win32StackFrameUnwinder); };
diff --git a/base/profiler/win32_stack_frame_unwinder_unittest.cc b/base/profiler/win32_stack_frame_unwinder_unittest.cc index a273793..c9d1c42 100644 --- a/base/profiler/win32_stack_frame_unwinder_unittest.cc +++ b/base/profiler/win32_stack_frame_unwinder_unittest.cc
@@ -97,7 +97,8 @@ // with a single friend declaration of this test fixture. scoped_ptr<Win32StackFrameUnwinder> CreateUnwinder(); - TestUnwindFunctions unwind_functions_; + // Weak pointer to the unwind functions used by last created unwinder. + TestUnwindFunctions* unwind_functions_; private: DISALLOW_COPY_AND_ASSIGN(Win32StackFrameUnwinderTest); @@ -105,7 +106,9 @@ scoped_ptr<Win32StackFrameUnwinder> Win32StackFrameUnwinderTest::CreateUnwinder() { - return make_scoped_ptr(new Win32StackFrameUnwinder(&unwind_functions_)); + scoped_ptr<TestUnwindFunctions> unwind_functions(new TestUnwindFunctions); + unwind_functions_ = unwind_functions.get(); + return make_scoped_ptr(new Win32StackFrameUnwinder(unwind_functions.Pass())); } // Checks the case where all frames have unwind information. @@ -124,7 +127,7 @@ CONTEXT context = {0}; const DWORD64 original_rsp = 128; context.Rsp = original_rsp; - unwind_functions_.SetNoUnwindInfoForNextFrame(); + unwind_functions_->SetNoUnwindInfoForNextFrame(); EXPECT_TRUE(unwinder->TryUnwind(&context)); EXPECT_EQ(original_rsp, context.Rip); EXPECT_EQ(original_rsp + 8, context.Rsp); @@ -143,8 +146,8 @@ CONTEXT context = {0}; EXPECT_TRUE(unwinder->TryUnwind(&context)); - unwind_functions_.SetNoUnwindInfoForNextFrame(); - unwind_functions_.SetImageBaseForNextFrame( + unwind_functions_->SetNoUnwindInfoForNextFrame(); + unwind_functions_->SetImageBaseForNextFrame( image_base_for_module_with_bad_function); EXPECT_FALSE(unwinder->TryUnwind(&context)); } @@ -154,8 +157,8 @@ // unwind info from the previously-seen module is blacklisted. scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder(); CONTEXT context = {0}; - unwind_functions_.SetNoUnwindInfoForNextFrame(); - unwind_functions_.SetImageBaseForNextFrame( + unwind_functions_->SetNoUnwindInfoForNextFrame(); + unwind_functions_->SetImageBaseForNextFrame( image_base_for_module_with_bad_function); EXPECT_FALSE(unwinder->TryUnwind(&context)); } @@ -168,13 +171,13 @@ // module. scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder(); CONTEXT context = {0}; - unwind_functions_.SetImageBaseForNextFrame( + unwind_functions_->SetImageBaseForNextFrame( image_base_for_module_with_bad_function); EXPECT_TRUE(unwinder->TryUnwind(&context)); EXPECT_TRUE(unwinder->TryUnwind(&context)); - unwind_functions_.SetImageBaseForNextFrame( + unwind_functions_->SetImageBaseForNextFrame( image_base_for_module_with_bad_function); EXPECT_TRUE(unwinder->TryUnwind(&context)); } @@ -187,12 +190,12 @@ // previously-seen module. scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder(); CONTEXT context = {0}; - unwind_functions_.SetNoUnwindInfoForNextFrame(); + unwind_functions_->SetNoUnwindInfoForNextFrame(); EXPECT_TRUE(unwinder->TryUnwind(&context)); EXPECT_TRUE(unwinder->TryUnwind(&context)); - unwind_functions_.SetImageBaseForNextFrame( + unwind_functions_->SetImageBaseForNextFrame( image_base_for_module_with_bad_function); EXPECT_TRUE(unwinder->TryUnwind(&context)); } @@ -208,11 +211,11 @@ // First stack, with both the first and second frames missing unwind info. scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder(); CONTEXT context = {0}; - unwind_functions_.SetNoUnwindInfoForNextFrame(); + unwind_functions_->SetNoUnwindInfoForNextFrame(); EXPECT_TRUE(unwinder->TryUnwind(&context)); - unwind_functions_.SetNoUnwindInfoForNextFrame(); - unwind_functions_.SetImageBaseForNextFrame( + unwind_functions_->SetNoUnwindInfoForNextFrame(); + unwind_functions_->SetImageBaseForNextFrame( image_base_for_questionable_module); EXPECT_FALSE(unwinder->TryUnwind(&context)); } @@ -221,8 +224,8 @@ // Second stack; check that the questionable module was not blacklisted. scoped_ptr<Win32StackFrameUnwinder> unwinder = CreateUnwinder(); CONTEXT context = {0}; - unwind_functions_.SetNoUnwindInfoForNextFrame(); - unwind_functions_.SetImageBaseForNextFrame( + unwind_functions_->SetNoUnwindInfoForNextFrame(); + unwind_functions_->SetImageBaseForNextFrame( image_base_for_questionable_module); EXPECT_TRUE(unwinder->TryUnwind(&context)); }
diff --git a/base/time/time.h b/base/time/time.h index e0a6ea3..e0435d0 100644 --- a/base/time/time.h +++ b/base/time/time.h
@@ -685,12 +685,14 @@ static TimeTicks FromQPCValue(LONGLONG qpc_value); #endif - // Get the TimeTick value at the time of the UnixEpoch. This is useful when - // you need to relate the value of TimeTicks to a real time and date. - // Note: Upon first invocation, this function takes a snapshot of the realtime - // clock to establish a reference point. This function will return the same - // value for the duration of the application, but will be different in future - // application runs. + // Get an estimate of the TimeTick value at the time of the UnixEpoch. Because + // Time and TimeTicks respond differently to user-set time and NTP + // adjustments, this number is only an estimate. Nevertheless, this can be + // useful when you need to relate the value of TimeTicks to a real time and + // date. Note: Upon first invocation, this function takes a snapshot of the + // realtime clock to establish a reference point. This function will return + // the same value for the duration of the application, but will be different + // in future application runs. static TimeTicks UnixEpoch(); // Returns |this| snapped to the next tick, given a |tick_phase| and
diff --git a/blimp/BUILD.gn b/blimp/BUILD.gn index 13b8e29e..8c71748 100644 --- a/blimp/BUILD.gn +++ b/blimp/BUILD.gn
@@ -3,9 +3,6 @@ # found in the LICENSE file. group("blimp") { - # TODO(maniscalco): Remove the testonly attribute once blimp_engine no longer - # depends on content_shell (crbug.com/538353). - testonly = true deps = [ "//blimp/client:blimp_client", "//blimp/common:blimp_common",
diff --git a/blimp/engine/BUILD.gn b/blimp/engine/BUILD.gn index 849b3cee..ecc1f61 100644 --- a/blimp/engine/BUILD.gn +++ b/blimp/engine/BUILD.gn
@@ -2,16 +2,65 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/features.gni") +import("//build/config/sanitizers/sanitizers.gni") +import("//build/config/ui.gni") +import("//tools/grit/repack.gni") +import("//tools/grit/grit_rule.gni") + +repack("pak") { + sources = [ + "$root_gen_dir/blink/public/resources/blink_image_resources_100_percent.pak", + "$root_gen_dir/blink/public/resources/blink_resources.pak", + "$root_gen_dir/content/app/resources/content_resources_100_percent.pak", + "$root_gen_dir/content/app/strings/content_strings_en-US.pak", + "$root_gen_dir/content/browser/tracing/tracing_resources.pak", + "$root_gen_dir/content/content_resources.pak", + "$root_gen_dir/net/net_resources.pak", + "$root_gen_dir/ui/resources/ui_resources_100_percent.pak", + "$root_gen_dir/ui/resources/webui_resources.pak", + "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak", + "$root_gen_dir/ui/strings/ui_strings_en-US.pak", + ] + + deps = [ + "//content:resources", + "//content/app/resources", + "//content/app/strings", + "//content/browser/tracing:resources", + "//net:net_resources", + "//third_party/WebKit/public:image_resources", + "//third_party/WebKit/public:resources", + "//ui/resources", + "//ui/strings", + ] + + if (toolkit_views) { + deps += [ "//ui/views/resources" ] + sources += + [ "$root_gen_dir/ui/views/resources/views_resources_100_percent.pak" ] + } + + output = "$root_out_dir/blimp_engine.pak" +} + if (is_linux) { + executable("blimp_engine_app") { + sources = [ + "app/blimp_main.cc", + ] + + deps = [ + ":pak", + "//blimp/engine/app", + ] + } + # A stand-in for the Blimp Engine so we can get the Docker packaging working. - # - # TODO(maniscalco): Update to use the real engine once it's ready and remove - # the testonly attribute (crbug.com/538353). group("blimp_engine") { - testonly = true data_deps = [ - "//content/shell:content_shell", - "//content/shell:pak", + ":blimp_engine_app", + ":pak", ] } }
diff --git a/blimp/engine/DEPS b/blimp/engine/DEPS new file mode 100644 index 0000000..0d8bb180 --- /dev/null +++ b/blimp/engine/DEPS
@@ -0,0 +1,10 @@ +include_rules = [ + "+base", + "-chrome", + "+components/web_cache/renderer", + "+content/public", + "+net", + "+ui/base", + "+ui/resources", + "+ui/gfx", +]
diff --git a/blimp/engine/app/BUILD.gn b/blimp/engine/app/BUILD.gn new file mode 100644 index 0000000..48fb0257 --- /dev/null +++ b/blimp/engine/app/BUILD.gn
@@ -0,0 +1,19 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("app") { + sources = [ + "blimp_content_main_delegate.cc", + "blimp_content_main_delegate.h", + ] + + deps = [ + "//base", + "//blimp/engine/browser", + "//blimp/engine/common", + "//blimp/engine/renderer", + "//content/public/app:both", + "//ui/base", + ] +}
diff --git a/blimp/engine/app/blimp_content_main_delegate.cc b/blimp/engine/app/blimp_content_main_delegate.cc new file mode 100644 index 0000000..a3efeffe --- /dev/null +++ b/blimp/engine/app/blimp_content_main_delegate.cc
@@ -0,0 +1,53 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "blimp/engine/app/blimp_content_main_delegate.h" + +#include "base/files/file.h" +#include "base/files/file_path.h" +#include "base/path_service.h" +#include "blimp/engine/browser/blimp_content_browser_client.h" +#include "blimp/engine/renderer/blimp_content_renderer_client.h" +#include "ui/base/resource/resource_bundle.h" + +namespace blimp { +namespace engine { + +BlimpContentMainDelegate::BlimpContentMainDelegate() {} + +BlimpContentMainDelegate::~BlimpContentMainDelegate() {} + +bool BlimpContentMainDelegate::BasicStartupComplete(int* exit_code) { + content::SetContentClient(&content_client_); + return false; +} + +void BlimpContentMainDelegate::PreSandboxStartup() { + InitializeResourceBundle(); +} + +void BlimpContentMainDelegate::InitializeResourceBundle() { + base::FilePath pak_file; + bool pak_file_valid = PathService::Get(base::DIR_MODULE, &pak_file); + CHECK(pak_file_valid); + pak_file = pak_file.Append(FILE_PATH_LITERAL("blimp_engine.pak")); + ui::ResourceBundle::InitSharedInstanceWithPakPath(pak_file); +} + +content::ContentBrowserClient* +BlimpContentMainDelegate::CreateContentBrowserClient() { + DCHECK(!browser_client_); + browser_client_.reset(new BlimpContentBrowserClient); + return browser_client_.get(); +} + +content::ContentRendererClient* +BlimpContentMainDelegate::CreateContentRendererClient() { + DCHECK(!renderer_client_); + renderer_client_.reset(new BlimpContentRendererClient); + return renderer_client_.get(); +} + +} // namespace engine +} // namespace blimp
diff --git a/blimp/engine/app/blimp_content_main_delegate.h b/blimp/engine/app/blimp_content_main_delegate.h new file mode 100644 index 0000000..24aa4c3d --- /dev/null +++ b/blimp/engine/app/blimp_content_main_delegate.h
@@ -0,0 +1,43 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BLIMP_ENGINE_APP_BLIMP_CONTENT_MAIN_DELEGATE_H_ +#define BLIMP_ENGINE_APP_BLIMP_CONTENT_MAIN_DELEGATE_H_ + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "blimp/engine/common/blimp_content_client.h" +#include "content/public/app/content_main_delegate.h" + +namespace blimp { +namespace engine { + +class BlimpContentBrowserClient; +class BlimpContentRendererClient; + +class BlimpContentMainDelegate : public content::ContentMainDelegate { + public: + BlimpContentMainDelegate(); + ~BlimpContentMainDelegate() override; + + // content::ContentMainDelegate implementation. + bool BasicStartupComplete(int* exit_code) override; + void PreSandboxStartup() override; + content::ContentBrowserClient* CreateContentBrowserClient() override; + content::ContentRendererClient* CreateContentRendererClient() override; + + private: + void InitializeResourceBundle(); + + scoped_ptr<BlimpContentBrowserClient> browser_client_; + scoped_ptr<BlimpContentRendererClient> renderer_client_; + BlimpContentClient content_client_; + + DISALLOW_COPY_AND_ASSIGN(BlimpContentMainDelegate); +}; + +} // namespace engine +} // namespace blimp + +#endif // BLIMP_ENGINE_APP_BLIMP_CONTENT_MAIN_DELEGATE_H_
diff --git a/blimp/engine/app/blimp_main.cc b/blimp/engine/app/blimp_main.cc new file mode 100644 index 0000000..64e3e53 --- /dev/null +++ b/blimp/engine/app/blimp_main.cc
@@ -0,0 +1,14 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "blimp/engine/app/blimp_content_main_delegate.h" +#include "content/public/app/content_main.h" + +int main(int argc, const char** argv) { + blimp::engine::BlimpContentMainDelegate delegate; + content::ContentMainParams params(&delegate); + params.argc = argc; + params.argv = argv; + return content::ContentMain(params); +}
diff --git a/blimp/engine/browser/BUILD.gn b/blimp/engine/browser/BUILD.gn new file mode 100644 index 0000000..dc7ac4ae --- /dev/null +++ b/blimp/engine/browser/BUILD.gn
@@ -0,0 +1,34 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("browser") { + sources = [ + "blimp_browser_context.cc", + "blimp_browser_context.h", + "blimp_browser_main_parts.cc", + "blimp_browser_main_parts.h", + "blimp_content_browser_client.cc", + "blimp_content_browser_client.h", + "blimp_network_delegate.cc", + "blimp_network_delegate.h", + "blimp_permission_manager.cc", + "blimp_permission_manager.h", + "blimp_url_request_context_getter.cc", + "blimp_url_request_context_getter.h", + "blimp_window.cc", + "blimp_window.h", + ] + + deps = [ + "//base", + "//blimp/engine/ui", + "//content", + "//content/public/browser", + "//content/public/common", + "//content/public/utility", + "//net", + "//ui/base", + "//ui/resources", + ] +}
diff --git a/blimp/engine/browser/blimp_browser_context.cc b/blimp/engine/browser/blimp_browser_context.cc new file mode 100644 index 0000000..caee89b0 --- /dev/null +++ b/blimp/engine/browser/blimp_browser_context.cc
@@ -0,0 +1,176 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "blimp/engine/browser/blimp_browser_context.h" + +#include "base/bind.h" +#include "base/environment.h" +#include "base/files/file_util.h" +#include "base/nix/xdg_util.h" +#include "base/path_service.h" +#include "blimp/engine/browser/blimp_permission_manager.h" +#include "content/public/browser/background_sync_controller.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/common/content_switches.h" + +namespace blimp { +namespace engine { + +// Contains URLRequestContextGetter required for resource loading. +class BlimpResourceContext : public content::ResourceContext { + public: + BlimpResourceContext() {} + ~BlimpResourceContext() override {} + + void set_url_request_context_getter( + const scoped_refptr<BlimpURLRequestContextGetter>& getter) { + getter_ = getter; + } + + const scoped_refptr<BlimpURLRequestContextGetter>& + url_request_context_getter() { + return getter_; + } + + // content::ResourceContext implementation. + net::HostResolver* GetHostResolver() override; + net::URLRequestContext* GetRequestContext() override; + + private: + scoped_refptr<BlimpURLRequestContextGetter> getter_; + + DISALLOW_COPY_AND_ASSIGN(BlimpResourceContext); +}; + +net::HostResolver* BlimpResourceContext::GetHostResolver() { + return getter_->host_resolver(); +} + +net::URLRequestContext* BlimpResourceContext::GetRequestContext() { + return getter_->GetURLRequestContext(); +} + +BlimpBrowserContext::BlimpBrowserContext(bool off_the_record, + net::NetLog* net_log) + : resource_context_(new BlimpResourceContext), + ignore_certificate_errors_(false), + off_the_record_(off_the_record), + net_log_(net_log) { + InitWhileIOAllowed(); +} + +BlimpBrowserContext::~BlimpBrowserContext() { + if (resource_context_) { + content::BrowserThread::DeleteSoon(content::BrowserThread::IO, FROM_HERE, + resource_context_.release()); + } +} + +void BlimpBrowserContext::InitWhileIOAllowed() { + // Ensures ~/.config/blimp_engine directory exists. + scoped_ptr<base::Environment> env(base::Environment::Create()); + base::FilePath config_dir(base::nix::GetXDGDirectory( + env.get(), base::nix::kXdgConfigHomeEnvVar, base::nix::kDotConfigDir)); + path_ = config_dir.Append("blimp_engine"); + if (!base::PathExists(path_)) + base::CreateDirectory(path_); +} + +scoped_ptr<content::ZoomLevelDelegate> +BlimpBrowserContext::CreateZoomLevelDelegate(const base::FilePath&) { + return nullptr; +} + +base::FilePath BlimpBrowserContext::GetPath() const { + return path_; +} + +bool BlimpBrowserContext::IsOffTheRecord() const { + return off_the_record_; +} + +content::DownloadManagerDelegate* +BlimpBrowserContext::GetDownloadManagerDelegate() { + return nullptr; +} + +net::URLRequestContextGetter* BlimpBrowserContext::GetRequestContext() { + return GetDefaultStoragePartition(this)->GetURLRequestContext(); +} + +const scoped_refptr<BlimpURLRequestContextGetter>& +BlimpBrowserContext::CreateRequestContext( + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors) { + DCHECK(!resource_context_->url_request_context_getter()); + // net_log_ is owned by BrowserMainParts. + resource_context_->set_url_request_context_getter( + new BlimpURLRequestContextGetter( + ignore_certificate_errors_, GetPath(), + content::BrowserThread::UnsafeGetMessageLoopForThread( + content::BrowserThread::IO) + ->task_runner(), + content::BrowserThread::UnsafeGetMessageLoopForThread( + content::BrowserThread::FILE) + ->task_runner(), + protocol_handlers, request_interceptors.Pass(), net_log_)); + return resource_context_->url_request_context_getter(); +} + +net::URLRequestContextGetter* +BlimpBrowserContext::GetRequestContextForRenderProcess(int renderer_child_id) { + return GetRequestContext(); +} + +net::URLRequestContextGetter* BlimpBrowserContext::GetMediaRequestContext() { + return GetRequestContext(); +} + +net::URLRequestContextGetter* +BlimpBrowserContext::GetMediaRequestContextForRenderProcess( + int renderer_child_id) { + return GetRequestContext(); +} + +net::URLRequestContextGetter* +BlimpBrowserContext::GetMediaRequestContextForStoragePartition( + const base::FilePath& partition_path, + bool in_memory) { + return GetRequestContext(); +} + +content::ResourceContext* BlimpBrowserContext::GetResourceContext() { + return resource_context_.get(); +} + +content::BrowserPluginGuestManager* BlimpBrowserContext::GetGuestManager() { + return nullptr; +} + +storage::SpecialStoragePolicy* BlimpBrowserContext::GetSpecialStoragePolicy() { + return nullptr; +} + +content::PushMessagingService* BlimpBrowserContext::GetPushMessagingService() { + return nullptr; +} + +content::SSLHostStateDelegate* BlimpBrowserContext::GetSSLHostStateDelegate() { + return nullptr; +} + +content::PermissionManager* BlimpBrowserContext::GetPermissionManager() { + if (!permission_manager_) + permission_manager_.reset(new BlimpPermissionManager()); + return permission_manager_.get(); +} + +content::BackgroundSyncController* +BlimpBrowserContext::GetBackgroundSyncController() { + return nullptr; +} + +} // namespace engine +} // namespace blimp
diff --git a/blimp/engine/browser/blimp_browser_context.h b/blimp/engine/browser/blimp_browser_context.h new file mode 100644 index 0000000..558e3eb --- /dev/null +++ b/blimp/engine/browser/blimp_browser_context.h
@@ -0,0 +1,80 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BLIMP_ENGINE_BROWSER_BLIMP_BROWSER_CONTEXT_H_ +#define BLIMP_ENGINE_BROWSER_BLIMP_BROWSER_CONTEXT_H_ + +#include "base/files/file_path.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "blimp/engine/browser/blimp_url_request_context_getter.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/content_browser_client.h" +#include "content/public/browser/resource_context.h" +#include "net/url_request/url_request_job_factory.h" + +namespace net { +class NetLog; +} + +namespace blimp { +namespace engine { + +class BlimpResourceContext; +class PermissionManager; + +class BlimpBrowserContext : public content::BrowserContext { + public: + // Caller owns |net_log| and ensures it out-lives this browser context. + BlimpBrowserContext(bool off_the_record, net::NetLog* net_log); + ~BlimpBrowserContext() override; + + // content::BrowserContext implementation. + scoped_ptr<content::ZoomLevelDelegate> CreateZoomLevelDelegate( + const base::FilePath& partition_path) override; + base::FilePath GetPath() const override; + bool IsOffTheRecord() const override; + net::URLRequestContextGetter* GetRequestContext() override; + net::URLRequestContextGetter* GetRequestContextForRenderProcess( + int renderer_child_id) override; + net::URLRequestContextGetter* GetMediaRequestContext() override; + net::URLRequestContextGetter* GetMediaRequestContextForRenderProcess( + int renderer_child_id) override; + net::URLRequestContextGetter* GetMediaRequestContextForStoragePartition( + const base::FilePath& partition_path, + bool in_memory) override; + content::ResourceContext* GetResourceContext() override; + content::DownloadManagerDelegate* GetDownloadManagerDelegate() override; + content::BrowserPluginGuestManager* GetGuestManager() override; + storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override; + content::PushMessagingService* GetPushMessagingService() override; + content::SSLHostStateDelegate* GetSSLHostStateDelegate() override; + content::PermissionManager* GetPermissionManager() override; + content::BackgroundSyncController* GetBackgroundSyncController() override; + + // The content of |protocol_handlers| is swapped into the returned instance. + // Caller should take a reference to the returned instance via scoped_refptr. + const scoped_refptr<BlimpURLRequestContextGetter>& CreateRequestContext( + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors); + + private: + // Performs initialization of the BlimpBrowserContext while IO is still + // allowed on the current thread. + void InitWhileIOAllowed(); + + scoped_ptr<BlimpResourceContext> resource_context_; + bool ignore_certificate_errors_; + scoped_ptr<content::PermissionManager> permission_manager_; + bool off_the_record_; + net::NetLog* net_log_; + base::FilePath path_; + + DISALLOW_COPY_AND_ASSIGN(BlimpBrowserContext); +}; + +} // namespace engine +} // namespace blimp + +#endif // BLIMP_ENGINE_BROWSER_BLIMP_BROWSER_CONTEXT_H_
diff --git a/blimp/engine/browser/blimp_browser_main_parts.cc b/blimp/engine/browser/blimp_browser_main_parts.cc new file mode 100644 index 0000000..a1c0474 --- /dev/null +++ b/blimp/engine/browser/blimp_browser_main_parts.cc
@@ -0,0 +1,61 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "blimp/engine/browser/blimp_browser_main_parts.h" + +#include "base/command_line.h" +#include "blimp/engine/browser/blimp_window.h" +#include "blimp/engine/ui/blimp_screen.h" +#include "content/public/browser/browser_thread.h" +#include "net/base/net_module.h" +#include "net/log/net_log.h" +#include "url/gurl.h" + +namespace blimp { +namespace engine { + +namespace { + +const char kDefaultURL[] = "https://www.google.com/"; + +GURL GetStartupURL() { + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + const base::CommandLine::StringVector& args = command_line->GetArgs(); + if (args.empty()) + return GURL(kDefaultURL); + + GURL url(args[0]); + if (url.is_valid() && url.has_scheme()) + return url; + + return GURL(kDefaultURL); +} + +} // namespace + +BlimpBrowserMainParts::BlimpBrowserMainParts( + const content::MainFunctionParams& parameters) {} + +BlimpBrowserMainParts::~BlimpBrowserMainParts() {} + +void BlimpBrowserMainParts::PreMainMessageLoopRun() { + net_log_.reset(new net::NetLog()); + browser_context_.reset(new BlimpBrowserContext(false, net_log_.get())); + BlimpWindow::Create(browser_context_.get(), GetStartupURL(), nullptr, + gfx::Size()); +} + +int BlimpBrowserMainParts::PreCreateThreads() { + screen_.reset(new BlimpScreen); + DCHECK(!gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE)); + gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get()); + return 0; +} + +void BlimpBrowserMainParts::PostMainMessageLoopRun() { + browser_context_.reset(); +} + +} // namespace engine +} // namespace blimp
diff --git a/blimp/engine/browser/blimp_browser_main_parts.h b/blimp/engine/browser/blimp_browser_main_parts.h new file mode 100644 index 0000000..5c2e991a --- /dev/null +++ b/blimp/engine/browser/blimp_browser_main_parts.h
@@ -0,0 +1,45 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BLIMP_ENGINE_BROWSER_BLIMP_BROWSER_MAIN_PARTS_H_ +#define BLIMP_ENGINE_BROWSER_BLIMP_BROWSER_MAIN_PARTS_H_ + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "blimp/engine/browser/blimp_browser_context.h" +#include "content/public/browser/browser_main_parts.h" + +namespace net { +class NetLog; +} + +namespace blimp { +namespace engine { + +class BlimpScreen; + +class BlimpBrowserMainParts : public content::BrowserMainParts { + public: + explicit BlimpBrowserMainParts(const content::MainFunctionParams& parameters); + ~BlimpBrowserMainParts() override; + + // content::BrowserMainParts implementation. + void PreMainMessageLoopRun() override; + void PostMainMessageLoopRun() override; + int PreCreateThreads() override; + + BlimpBrowserContext* browser_context() { return browser_context_.get(); } + + private: + scoped_ptr<net::NetLog> net_log_; + scoped_ptr<BlimpBrowserContext> browser_context_; + scoped_ptr<BlimpScreen> screen_; + + DISALLOW_COPY_AND_ASSIGN(BlimpBrowserMainParts); +}; + +} // namespace engine +} // namespace blimp + +#endif // BLIMP_ENGINE_BROWSER_BLIMP_BROWSER_MAIN_PARTS_H_
diff --git a/blimp/engine/browser/blimp_content_browser_client.cc b/blimp/engine/browser/blimp_content_browser_client.cc new file mode 100644 index 0000000..1023fbb --- /dev/null +++ b/blimp/engine/browser/blimp_content_browser_client.cc
@@ -0,0 +1,39 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "blimp/engine/browser/blimp_content_browser_client.h" +#include "blimp/engine/browser/blimp_browser_context.h" +#include "blimp/engine/browser/blimp_browser_main_parts.h" + +namespace blimp { +namespace engine { + +BlimpContentBrowserClient::BlimpContentBrowserClient() {} + +BlimpContentBrowserClient::~BlimpContentBrowserClient() {} + +content::BrowserMainParts* BlimpContentBrowserClient::CreateBrowserMainParts( + const content::MainFunctionParams& parameters) { + blimp_browser_main_parts_ = new BlimpBrowserMainParts(parameters); + // BrowserMainLoop takes ownership of the returned BrowserMainParts. + return blimp_browser_main_parts_; +} + +net::URLRequestContextGetter* BlimpContentBrowserClient::CreateRequestContext( + content::BrowserContext* content_browser_context, + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors) { + BlimpBrowserContext* blimp_context = + static_cast<BlimpBrowserContext*>(content_browser_context); + return blimp_context->CreateRequestContext(protocol_handlers, + request_interceptors.Pass()) + .get(); +} + +BlimpBrowserContext* BlimpContentBrowserClient::browser_context() { + return blimp_browser_main_parts_->browser_context(); +} + +} // namespace engine +} // namespace blimp
diff --git a/blimp/engine/browser/blimp_content_browser_client.h b/blimp/engine/browser/blimp_content_browser_client.h new file mode 100644 index 0000000..aa566cdc --- /dev/null +++ b/blimp/engine/browser/blimp_content_browser_client.h
@@ -0,0 +1,42 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BLIMP_ENGINE_BROWSER_BLIMP_CONTENT_BROWSER_CLIENT_H_ +#define BLIMP_ENGINE_BROWSER_BLIMP_CONTENT_BROWSER_CLIENT_H_ + +#include "base/macros.h" +#include "content/public/browser/content_browser_client.h" + +namespace blimp { +namespace engine { + +class BlimpBrowserMainParts; +class BlimpBrowserContext; + +class BlimpContentBrowserClient : public content::ContentBrowserClient { + public: + BlimpContentBrowserClient(); + ~BlimpContentBrowserClient() override; + + // content::ContentBrowserClient implementation. + content::BrowserMainParts* CreateBrowserMainParts( + const content::MainFunctionParams& parameters) override; + net::URLRequestContextGetter* CreateRequestContext( + content::BrowserContext* browser_context, + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors) override; + + BlimpBrowserContext* browser_context(); + + private: + // Owned by BrowserMainLoop + BlimpBrowserMainParts* blimp_browser_main_parts_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(BlimpContentBrowserClient); +}; + +} // namespace engine +} // namespace blimp + +#endif // BLIMP_ENGINE_BROWSER_BLIMP_CONTENT_BROWSER_CLIENT_H_
diff --git a/blimp/engine/browser/blimp_network_delegate.cc b/blimp/engine/browser/blimp_network_delegate.cc new file mode 100644 index 0000000..c22da118 --- /dev/null +++ b/blimp/engine/browser/blimp_network_delegate.cc
@@ -0,0 +1,51 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "blimp/engine/browser/blimp_network_delegate.h" + +#include "net/base/net_errors.h" +#include "net/base/static_cookie_policy.h" +#include "net/url_request/url_request.h" + +namespace blimp { +namespace engine { + +namespace { +bool g_accept_all_cookies = true; + +net::StaticCookiePolicy::Type GetPolicyType() { + return g_accept_all_cookies + ? net::StaticCookiePolicy::ALLOW_ALL_COOKIES + : net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES; +} + +} // namespace + +BlimpNetworkDelegate::BlimpNetworkDelegate() {} + +BlimpNetworkDelegate::~BlimpNetworkDelegate() {} + +void BlimpNetworkDelegate::SetAcceptAllCookies(bool accept) { + g_accept_all_cookies = accept; +} + +bool BlimpNetworkDelegate::OnCanGetCookies(const net::URLRequest& request, + const net::CookieList& cookie_list) { + net::StaticCookiePolicy policy(GetPolicyType()); + int rv = + policy.CanGetCookies(request.url(), request.first_party_for_cookies()); + return rv == net::OK; +} + +bool BlimpNetworkDelegate::OnCanSetCookie(const net::URLRequest& request, + const std::string& cookie_line, + net::CookieOptions* options) { + net::StaticCookiePolicy policy(GetPolicyType()); + int rv = + policy.CanSetCookie(request.url(), request.first_party_for_cookies()); + return rv == net::OK; +} + +} // namespace engine +} // namespace blimp
diff --git a/blimp/engine/browser/blimp_network_delegate.h b/blimp/engine/browser/blimp_network_delegate.h new file mode 100644 index 0000000..e8b0e2c --- /dev/null +++ b/blimp/engine/browser/blimp_network_delegate.h
@@ -0,0 +1,38 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BLIMP_ENGINE_BROWSER_BLIMP_NETWORK_DELEGATE_H_ +#define BLIMP_ENGINE_BROWSER_BLIMP_NETWORK_DELEGATE_H_ + +#include <string> + +#include "base/macros.h" +#include "net/base/network_delegate_impl.h" + +namespace blimp { +namespace engine { + +class BlimpNetworkDelegate : public net::NetworkDelegateImpl { + public: + BlimpNetworkDelegate(); + ~BlimpNetworkDelegate() override; + + // Affects subsequent cookie retrieval and setting. + static void SetAcceptAllCookies(bool accept); + + private: + // net::NetworkDelegate implementation. + bool OnCanGetCookies(const net::URLRequest& request, + const net::CookieList& cookie_list) override; + bool OnCanSetCookie(const net::URLRequest& request, + const std::string& cookie_line, + net::CookieOptions* options) override; + + DISALLOW_COPY_AND_ASSIGN(BlimpNetworkDelegate); +}; + +} // namespace engine +} // namespace blimp + +#endif // BLIMP_ENGINE_BROWSER_BLIMP_NETWORK_DELEGATE_H_
diff --git a/blimp/engine/browser/blimp_permission_manager.cc b/blimp/engine/browser/blimp_permission_manager.cc new file mode 100644 index 0000000..6cace1b --- /dev/null +++ b/blimp/engine/browser/blimp_permission_manager.cc
@@ -0,0 +1,58 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "blimp/engine/browser/blimp_permission_manager.h" + +#include "base/callback.h" +#include "content/public/browser/permission_type.h" + +namespace blimp { +namespace engine { + +BlimpPermissionManager::BlimpPermissionManager() + : content::PermissionManager() {} + +BlimpPermissionManager::~BlimpPermissionManager() {} + +int BlimpPermissionManager::RequestPermission( + content::PermissionType permission, + content::RenderFrameHost* render_frame_host, + const GURL& origin, + bool user_gesture, + const base::Callback<void(content::PermissionStatus)>& callback) { + callback.Run(content::PermissionStatus::PERMISSION_STATUS_DENIED); + return kNoPendingOperation; +} + +void BlimpPermissionManager::CancelPermissionRequest(int request_id) {} + +void BlimpPermissionManager::ResetPermission(content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin) {} + +content::PermissionStatus BlimpPermissionManager::GetPermissionStatus( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin) { + return content::PermissionStatus::PERMISSION_STATUS_DENIED; +} + +void BlimpPermissionManager::RegisterPermissionUsage( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin) {} + +int BlimpPermissionManager::SubscribePermissionStatusChange( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin, + const base::Callback<void(content::PermissionStatus)>& callback) { + return -1; +} + +void BlimpPermissionManager::UnsubscribePermissionStatusChange( + int subscription_id) {} + +} // namespace engine +} // namespace blimp
diff --git a/blimp/engine/browser/blimp_permission_manager.h b/blimp/engine/browser/blimp_permission_manager.h new file mode 100644 index 0000000..b9f0eb8 --- /dev/null +++ b/blimp/engine/browser/blimp_permission_manager.h
@@ -0,0 +1,52 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BLIMP_ENGINE_BROWSER_BLIMP_PERMISSION_MANAGER_H_ +#define BLIMP_ENGINE_BROWSER_BLIMP_PERMISSION_MANAGER_H_ + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "content/public/browser/permission_manager.h" + +namespace blimp { +namespace engine { + +class BlimpPermissionManager : public content::PermissionManager { + public: + BlimpPermissionManager(); + ~BlimpPermissionManager() override; + + // content::PermissionManager implementation: + int RequestPermission( + content::PermissionType permission, + content::RenderFrameHost* render_frame_host, + const GURL& requesting_origin, + bool user_gesture, + const base::Callback<void(content::PermissionStatus)>& callback) override; + void CancelPermissionRequest(int request_id) override; + void ResetPermission(content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin) override; + content::PermissionStatus GetPermissionStatus( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin) override; + void RegisterPermissionUsage(content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin) override; + int SubscribePermissionStatusChange( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin, + const base::Callback<void(content::PermissionStatus)>& callback) override; + void UnsubscribePermissionStatusChange(int subscription_id) override; + + private: + DISALLOW_COPY_AND_ASSIGN(BlimpPermissionManager); +}; + +} // namespace engine +} // namespace blimp + +#endif // BLIMP_ENGINE_BROWSER_BLIMP_PERMISSION_MANAGER_H_
diff --git a/blimp/engine/browser/blimp_url_request_context_getter.cc b/blimp/engine/browser/blimp_url_request_context_getter.cc new file mode 100644 index 0000000..e49c5f2 --- /dev/null +++ b/blimp/engine/browser/blimp_url_request_context_getter.cc
@@ -0,0 +1,224 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "blimp/engine/browser/blimp_url_request_context_getter.h" + +#include <algorithm> + +#include "base/command_line.h" +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/single_thread_task_runner.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/threading/sequenced_worker_pool.h" +#include "base/threading/worker_pool.h" +#include "blimp/engine/browser/blimp_network_delegate.h" +#include "blimp/engine/common/blimp_content_client.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/cookie_store_factory.h" +#include "content/public/common/content_switches.h" +#include "net/base/cache_type.h" +#include "net/cert/cert_verifier.h" +#include "net/cookies/cookie_monster.h" +#include "net/dns/host_resolver.h" +#include "net/dns/mapped_host_resolver.h" +#include "net/http/http_auth_handler_factory.h" +#include "net/http/http_cache.h" +#include "net/http/http_network_session.h" +#include "net/http/http_server_properties_impl.h" +#include "net/http/transport_security_state.h" +#include "net/proxy/proxy_config_service.h" +#include "net/proxy/proxy_service.h" +#include "net/ssl/channel_id_service.h" +#include "net/ssl/default_channel_id_store.h" +#include "net/ssl/ssl_config_service_defaults.h" +#include "net/url_request/data_protocol_handler.h" +#include "net/url_request/file_protocol_handler.h" +#include "net/url_request/static_http_user_agent_settings.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_storage.h" +#include "net/url_request/url_request_intercepting_job_factory.h" +#include "net/url_request/url_request_job_factory_impl.h" +#include "url/url_constants.h" + +namespace blimp { +namespace engine { + +namespace { + +void InstallProtocolHandlers(net::URLRequestJobFactoryImpl* job_factory, + content::ProtocolHandlerMap* protocol_handlers) { + for (content::ProtocolHandlerMap::iterator it = protocol_handlers->begin(); + it != protocol_handlers->end(); ++it) { + bool set_protocol = job_factory->SetProtocolHandler( + it->first, make_scoped_ptr(it->second.release())); + DCHECK(set_protocol); + } + protocol_handlers->clear(); +} + +} // namespace + +BlimpURLRequestContextGetter::BlimpURLRequestContextGetter( + bool ignore_certificate_errors, + const base::FilePath& base_path, + const scoped_refptr<base::SingleThreadTaskRunner>& io_loop_task_runner, + const scoped_refptr<base::SingleThreadTaskRunner>& file_loop_task_runner, + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors, + net::NetLog* net_log) + : ignore_certificate_errors_(ignore_certificate_errors), + base_path_(base_path), + io_loop_task_runner_(io_loop_task_runner), + file_loop_task_runner_(file_loop_task_runner), + net_log_(net_log), + request_interceptors_(request_interceptors.Pass()) { + // Must first be created on the UI thread. + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + std::swap(protocol_handlers_, *protocol_handlers); + + // We must create the proxy config service on the UI loop on Linux because it + // must synchronously run on the glib message loop. This will be passed to + // the URLRequestContextStorage on the IO thread in GetURLRequestContext(). + proxy_config_service_ = GetProxyConfigService(); +} + +BlimpURLRequestContextGetter::~BlimpURLRequestContextGetter() {} + +scoped_ptr<net::NetworkDelegate> +BlimpURLRequestContextGetter::CreateNetworkDelegate() { + return make_scoped_ptr(new BlimpNetworkDelegate).Pass(); +} + +scoped_ptr<net::ProxyConfigService> +BlimpURLRequestContextGetter::GetProxyConfigService() { + return net::ProxyService::CreateSystemProxyConfigService( + io_loop_task_runner_, file_loop_task_runner_); +} + +scoped_ptr<net::ProxyService> BlimpURLRequestContextGetter::GetProxyService() { + return net::ProxyService::CreateUsingSystemProxyResolver( + proxy_config_service_.Pass(), 0, url_request_context_->net_log()); +} + +net::URLRequestContext* BlimpURLRequestContextGetter::GetURLRequestContext() { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + + if (!url_request_context_) { + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + + url_request_context_.reset(new net::URLRequestContext()); + url_request_context_->set_net_log(net_log_); + network_delegate_ = CreateNetworkDelegate(); + url_request_context_->set_network_delegate(network_delegate_.get()); + storage_.reset( + new net::URLRequestContextStorage(url_request_context_.get())); + storage_->set_cookie_store( + content::CreateCookieStore(content::CookieStoreConfig())); + storage_->set_channel_id_service(make_scoped_ptr( + new net::ChannelIDService(new net::DefaultChannelIDStore(NULL), + base::WorkerPool::GetTaskRunner(true)))); + storage_->set_http_user_agent_settings( + make_scoped_ptr(new net::StaticHttpUserAgentSettings( + "en-us,en", GetBlimpEngineUserAgent()))); + + scoped_ptr<net::HostResolver> host_resolver( + net::HostResolver::CreateDefaultResolver( + url_request_context_->net_log())); + + storage_->set_cert_verifier(net::CertVerifier::CreateDefault()); + storage_->set_transport_security_state( + make_scoped_ptr(new net::TransportSecurityState)); + storage_->set_proxy_service(GetProxyService()); + storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults); + storage_->set_http_auth_handler_factory( + net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get())); + storage_->set_http_server_properties( + make_scoped_ptr(new net::HttpServerPropertiesImpl())); + + base::FilePath cache_path = base_path_.Append(FILE_PATH_LITERAL("Cache")); + net::HttpCache::DefaultBackend* main_backend = + new net::HttpCache::DefaultBackend( + net::DISK_CACHE, net::CACHE_BACKEND_DEFAULT, cache_path, 0, + content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::CACHE)); + + net::HttpNetworkSession::Params network_session_params; + network_session_params.cert_verifier = + url_request_context_->cert_verifier(); + network_session_params.transport_security_state = + url_request_context_->transport_security_state(); + network_session_params.channel_id_service = + url_request_context_->channel_id_service(); + network_session_params.proxy_service = + url_request_context_->proxy_service(); + network_session_params.ssl_config_service = + url_request_context_->ssl_config_service(); + network_session_params.http_auth_handler_factory = + url_request_context_->http_auth_handler_factory(); + network_session_params.network_delegate = network_delegate_.get(); + network_session_params.http_server_properties = + url_request_context_->http_server_properties(); + network_session_params.net_log = url_request_context_->net_log(); + network_session_params.ignore_certificate_errors = + ignore_certificate_errors_; + if (command_line.HasSwitch(switches::kHostResolverRules)) { + scoped_ptr<net::MappedHostResolver> mapped_host_resolver( + new net::MappedHostResolver(host_resolver.Pass())); + mapped_host_resolver->SetRulesFromString( + command_line.GetSwitchValueASCII(switches::kHostResolverRules)); + host_resolver = mapped_host_resolver.Pass(); + } + + // Give |storage_| ownership at the end in case it's |mapped_host_resolver|. + storage_->set_host_resolver(host_resolver.Pass()); + network_session_params.host_resolver = + url_request_context_->host_resolver(); + + storage_->set_http_transaction_factory( + make_scoped_ptr( + new net::HttpCache(network_session_params, main_backend)) + .Pass()); + + scoped_ptr<net::URLRequestJobFactoryImpl> job_factory( + new net::URLRequestJobFactoryImpl()); + // Keep ProtocolHandlers added in sync with + // BlimpContentBrowserClient::IsHandledURL(). + InstallProtocolHandlers(job_factory.get(), &protocol_handlers_); + bool set_protocol = job_factory->SetProtocolHandler( + url::kDataScheme, make_scoped_ptr(new net::DataProtocolHandler)); + DCHECK(set_protocol); + + // Set up interceptors in the reverse order so that the last inceptor is at + // the end of the linked list of job factories. + scoped_ptr<net::URLRequestJobFactory> top_job_factory = job_factory.Pass(); + for (auto i = request_interceptors_.rbegin(); + i != request_interceptors_.rend(); ++i) { + top_job_factory.reset(new net::URLRequestInterceptingJobFactory( + top_job_factory.Pass(), make_scoped_ptr(*i))); + } + request_interceptors_.weak_clear(); + // Save the head of the job factory list at storage_. + storage_->set_job_factory(top_job_factory.Pass()); + } + + return url_request_context_.get(); +} + +scoped_refptr<base::SingleThreadTaskRunner> +BlimpURLRequestContextGetter::GetNetworkTaskRunner() const { + return content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::IO); +} + +net::HostResolver* BlimpURLRequestContextGetter::host_resolver() { + return url_request_context_->host_resolver(); +} + +} // namespace engine +} // namespace blimp
diff --git a/blimp/engine/browser/blimp_url_request_context_getter.h b/blimp/engine/browser/blimp_url_request_context_getter.h new file mode 100644 index 0000000..d0ae01b --- /dev/null +++ b/blimp/engine/browser/blimp_url_request_context_getter.h
@@ -0,0 +1,78 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BLIMP_ENGINE_BROWSER_BLIMP_URL_REQUEST_CONTEXT_GETTER_H_ +#define BLIMP_ENGINE_BROWSER_BLIMP_URL_REQUEST_CONTEXT_GETTER_H_ + +#include "base/files/file_path.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/browser/content_browser_client.h" +#include "net/url_request/url_request_context_getter.h" + +namespace base { +class MessageLoop; +class SingleThreadTaskRunner; +} + +namespace net { +class HostResolver; +class NetworkDelegate; +class NetLog; +class ProxyConfigService; +class ProxyService; +class URLRequestContextStorage; +} + +namespace blimp { +namespace engine { + +class BlimpURLRequestContextGetter : public net::URLRequestContextGetter { + public: + // The content of |protocol_handlers| is is swapped into the new instance. + BlimpURLRequestContextGetter( + bool ignore_certificate_errors, + const base::FilePath& base_path, + const scoped_refptr<base::SingleThreadTaskRunner>& io_loop_task_runner, + const scoped_refptr<base::SingleThreadTaskRunner>& file_loop_task_runner, + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors, + net::NetLog* net_log); + + // net::URLRequestContextGetter implementation. + net::URLRequestContext* GetURLRequestContext() override; + scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() + const override; + + net::HostResolver* host_resolver(); + + protected: + ~BlimpURLRequestContextGetter() override; + + // Used by subclasses to create their own implementation of NetworkDelegate + // and net::ProxyService. + virtual scoped_ptr<net::NetworkDelegate> CreateNetworkDelegate(); + virtual scoped_ptr<net::ProxyConfigService> GetProxyConfigService(); + virtual scoped_ptr<net::ProxyService> GetProxyService(); + + private: + bool ignore_certificate_errors_; + base::FilePath base_path_; + scoped_refptr<base::SingleThreadTaskRunner> io_loop_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> file_loop_task_runner_; + net::NetLog* net_log_; + + scoped_ptr<net::ProxyConfigService> proxy_config_service_; + scoped_ptr<net::NetworkDelegate> network_delegate_; + scoped_ptr<net::URLRequestContextStorage> storage_; + scoped_ptr<net::URLRequestContext> url_request_context_; + content::ProtocolHandlerMap protocol_handlers_; + content::URLRequestInterceptorScopedVector request_interceptors_; + + DISALLOW_COPY_AND_ASSIGN(BlimpURLRequestContextGetter); +}; + +} // namespace engine +} // namespace blimp + +#endif // BLIMP_ENGINE_BROWSER_BLIMP_URL_REQUEST_CONTEXT_GETTER_H_
diff --git a/blimp/engine/browser/blimp_window.cc b/blimp/engine/browser/blimp_window.cc new file mode 100644 index 0000000..bc79448 --- /dev/null +++ b/blimp/engine/browser/blimp_window.cc
@@ -0,0 +1,140 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "blimp/engine/browser/blimp_window.h" + +#include "base/strings/string_util.h" +#include "blimp/engine/browser/blimp_browser_main_parts.h" +#include "blimp/engine/browser/blimp_content_browser_client.h" +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host_view.h" +#include "content/public/browser/web_contents.h" + +namespace blimp { +namespace engine { + +namespace { +const int kDefaultWindowWidthDip = 1; +const int kDefaultWindowHeightDip = 1; + +// TODO(haibinlu): cleanup BlimpWindows on shutdown. See crbug/540498. +typedef std::vector<BlimpWindow*> BlimpWindows; +base::LazyInstance<BlimpWindows>::Leaky g_instances = LAZY_INSTANCE_INITIALIZER; + +// Returns the default size if |size| has 0 for width and/or height; +// otherwise, returns |size|. +gfx::Size AdjustWindowSize(const gfx::Size& size) { + return size.IsEmpty() + ? gfx::Size(kDefaultWindowWidthDip, kDefaultWindowHeightDip) + : size; +} +} // namespace + +BlimpWindow::~BlimpWindow() { + BlimpWindows* instances = g_instances.Pointer(); + BlimpWindows::iterator it( + std::find(instances->begin(), instances->end(), this)); + DCHECK(it != instances->end()); + instances->erase(it); +} + +// static +void BlimpWindow::Create(content::BrowserContext* browser_context, + const GURL& url, + content::SiteInstance* site_instance, + const gfx::Size& initial_size) { + content::WebContents::CreateParams create_params(browser_context, + site_instance); + scoped_ptr<content::WebContents> web_contents( + content::WebContents::Create(create_params)); + BlimpWindow* win = DoCreate(web_contents.Pass(), initial_size); + if (!url.is_empty()) + win->LoadURL(url); +} + +void BlimpWindow::LoadURL(const GURL& url) { + content::NavigationController::LoadURLParams params(url); + params.transition_type = ui::PageTransitionFromInt( + ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR); + web_contents_->GetController().LoadURLWithParams(params); + web_contents_->Focus(); +} + +void BlimpWindow::AddNewContents(content::WebContents* source, + content::WebContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_rect, + bool user_gesture, + bool* was_blocked) { + DoCreate(scoped_ptr<content::WebContents>(new_contents), initial_rect.size()); +} + +content::WebContents* BlimpWindow::OpenURLFromTab( + content::WebContents* source, + const content::OpenURLParams& params) { + // CURRENT_TAB is the only one we implement for now. + if (params.disposition != CURRENT_TAB) + return nullptr; + // TOOD(haibinlu): add helper method to get LoadURLParams from OpenURLParams. + content::NavigationController::LoadURLParams load_url_params(params.url); + load_url_params.source_site_instance = params.source_site_instance; + load_url_params.referrer = params.referrer; + load_url_params.frame_tree_node_id = params.frame_tree_node_id; + load_url_params.transition_type = params.transition; + load_url_params.extra_headers = params.extra_headers; + load_url_params.should_replace_current_entry = + params.should_replace_current_entry; + + if (params.transferred_global_request_id != content::GlobalRequestID()) { + load_url_params.is_renderer_initiated = params.is_renderer_initiated; + load_url_params.transferred_global_request_id = + params.transferred_global_request_id; + } else if (params.is_renderer_initiated) { + load_url_params.is_renderer_initiated = true; + } + + source->GetController().LoadURLWithParams(load_url_params); + return source; +} + +void BlimpWindow::RequestToLockMouse(content::WebContents* web_contents, + bool user_gesture, + bool last_unlocked_by_target) { + web_contents->GotResponseToLockMouseRequest(true); +} + +void BlimpWindow::CloseContents(content::WebContents* source) { + delete this; +} + +void BlimpWindow::ActivateContents(content::WebContents* contents) { + contents->GetRenderViewHost()->Focus(); +} + +void BlimpWindow::DeactivateContents(content::WebContents* contents) { + contents->GetRenderViewHost()->Blur(); +} + +BlimpWindow::BlimpWindow(scoped_ptr<content::WebContents> web_contents) + : web_contents_(web_contents.Pass()) { + web_contents_->SetDelegate(this); + g_instances.Get().push_back(this); +} + +// static +BlimpWindow* BlimpWindow::DoCreate( + scoped_ptr<content::WebContents> web_contents, + const gfx::Size& initial_size) { + BlimpWindow* win = new BlimpWindow(web_contents.Pass()); + content::RenderWidgetHostView* host_view = + win->web_contents_->GetRenderWidgetHostView(); + if (host_view) + host_view->SetSize(AdjustWindowSize(initial_size)); + return win; +} + +} // namespace engine +} // namespace blimp
diff --git a/blimp/engine/browser/blimp_window.h b/blimp/engine/browser/blimp_window.h new file mode 100644 index 0000000..fadf3b63 --- /dev/null +++ b/blimp/engine/browser/blimp_window.h
@@ -0,0 +1,79 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +#ifndef BLIMP_ENGINE_BROWSER_BLIMP_WINDOW_H_ +#define BLIMP_ENGINE_BROWSER_BLIMP_WINDOW_H_ + +#include <vector> + +#include "base/lazy_instance.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/browser/web_contents_delegate.h" +#include "content/public/browser/web_contents_observer.h" +#include "ui/gfx/geometry/size.h" + +namespace content { +class BrowserContext; +class SiteInstance; +class WebContents; +} + +class GURL; + +namespace blimp { +namespace engine { + +// Owns and controls a WebContents instance corresponding to a window on +// Blimp client. +class BlimpWindow : public content::WebContentsDelegate { + public: + // This also unregisters itself with a singleton registry. + ~BlimpWindow() override; + + // Creates a new blimp window with |initial_size| and navigates to the |url|. + // Caller retains ownership of |browser_context| and |site_instance| and + // ensures |browser_context| and |site_instance| outlives BlimpWindow. + static void Create(content::BrowserContext* browser_context, + const GURL& url, + content::SiteInstance* site_instance, + const gfx::Size& initial_size); + + // Navigates to |url|. + void LoadURL(const GURL& url); + + // content::WebContentsDelegate implementation. + content::WebContents* OpenURLFromTab( + content::WebContents* source, + const content::OpenURLParams& params) override; + void AddNewContents(content::WebContents* source, + content::WebContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_rect, + bool user_gesture, + bool* was_blocked) override; + void RequestToLockMouse(content::WebContents* web_contents, + bool user_gesture, + bool last_unlocked_by_target) override; + void CloseContents(content::WebContents* source) override; + void ActivateContents(content::WebContents* contents) override; + void DeactivateContents(content::WebContents* contents) override; + + private: + // The newly created instance registers itself with a singleton registry. + explicit BlimpWindow(scoped_ptr<content::WebContents> web_contents); + + // Helper to create a new BlimpWindow given |web_contents|. + // The newly window is owned by a singleton registry. + static BlimpWindow* DoCreate(scoped_ptr<content::WebContents> web_contents, + const gfx::Size& initial_size); + + scoped_ptr<content::WebContents> web_contents_; + + DISALLOW_COPY_AND_ASSIGN(BlimpWindow); +}; + +} // namespace engine +} // namespace blimp + +#endif // BLIMP_ENGINE_BROWSER_BLIMP_WINDOW_H_
diff --git a/blimp/engine/common/BUILD.gn b/blimp/engine/common/BUILD.gn new file mode 100644 index 0000000..48632dc --- /dev/null +++ b/blimp/engine/common/BUILD.gn
@@ -0,0 +1,16 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("common") { + sources = [ + "blimp_content_client.cc", + "blimp_content_client.h", + ] + + deps = [ + "//base", + "//content/public/common", + "//ui/base", + ] +}
diff --git a/blimp/engine/common/blimp_content_client.cc b/blimp/engine/common/blimp_content_client.cc new file mode 100644 index 0000000..00c2c2d --- /dev/null +++ b/blimp/engine/common/blimp_content_client.cc
@@ -0,0 +1,50 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "blimp/engine/common/blimp_content_client.h" + +#include "content/public/common/user_agent.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" + +namespace blimp { +namespace engine { + +// TODO(haibinlu) Generate proper version. See crbug/537367. +const char kProduct[] = "Chrome/20.77.33.5"; + +std::string GetBlimpEngineUserAgent() { + return content::BuildUserAgentFromProduct(kProduct); +} + +BlimpContentClient::~BlimpContentClient() {} + +std::string BlimpContentClient::GetUserAgent() const { + return GetBlimpEngineUserAgent(); +} + +base::string16 BlimpContentClient::GetLocalizedString(int message_id) const { + return l10n_util::GetStringUTF16(message_id); +} + +base::StringPiece BlimpContentClient::GetDataResource( + int resource_id, + ui::ScaleFactor scale_factor) const { + return ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale( + resource_id, scale_factor); +} + +base::RefCountedStaticMemory* BlimpContentClient::GetDataResourceBytes( + int resource_id) const { + return ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytes( + resource_id); +} + +gfx::Image& BlimpContentClient::GetNativeImageNamed(int resource_id) const { + return ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( + resource_id); +} + +} // namespace engine +} // namespace blimp
diff --git a/blimp/engine/common/blimp_content_client.h b/blimp/engine/common/blimp_content_client.h new file mode 100644 index 0000000..8826a62 --- /dev/null +++ b/blimp/engine/common/blimp_content_client.h
@@ -0,0 +1,35 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BLIMP_ENGINE_COMMON_BLIMP_CONTENT_CLIENT_H_ +#define BLIMP_ENGINE_COMMON_BLIMP_CONTENT_CLIENT_H_ + +#include <string> + +#include "content/public/common/content_client.h" + +namespace blimp { +namespace engine { + +std::string GetBlimpEngineUserAgent(); + +class BlimpContentClient : public content::ContentClient { + public: + ~BlimpContentClient() override; + + // content::ContentClient implementation. + std::string GetUserAgent() const override; + base::string16 GetLocalizedString(int message_id) const override; + base::StringPiece GetDataResource( + int resource_id, + ui::ScaleFactor scale_factor) const override; + base::RefCountedStaticMemory* GetDataResourceBytes( + int resource_id) const override; + gfx::Image& GetNativeImageNamed(int resource_id) const override; +}; + +} // namespace engine +} // namespace blimp + +#endif // BLIMP_ENGINE_COMMON_BLIMP_CONTENT_CLIENT_H_
diff --git a/blimp/engine/renderer/BUILD.gn b/blimp/engine/renderer/BUILD.gn new file mode 100644 index 0000000..8d9db08 --- /dev/null +++ b/blimp/engine/renderer/BUILD.gn
@@ -0,0 +1,15 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("renderer") { + sources = [ + "blimp_content_renderer_client.cc", + "blimp_content_renderer_client.h", + ] + + deps = [ + "//components/web_cache/renderer", + "//content/public/renderer", + ] +}
diff --git a/blimp/engine/renderer/blimp_content_renderer_client.cc b/blimp/engine/renderer/blimp_content_renderer_client.cc new file mode 100644 index 0000000..6b6e7b7a --- /dev/null +++ b/blimp/engine/renderer/blimp_content_renderer_client.cc
@@ -0,0 +1,23 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "blimp/engine/renderer/blimp_content_renderer_client.h" + +#include "components/web_cache/renderer/web_cache_render_process_observer.h" +#include "content/public/renderer/render_thread.h" + +namespace blimp { +namespace engine { + +BlimpContentRendererClient::BlimpContentRendererClient() {} + +BlimpContentRendererClient::~BlimpContentRendererClient() {} + +void BlimpContentRendererClient::RenderThreadStarted() { + web_cache_observer_.reset(new web_cache::WebCacheRenderProcessObserver()); + content::RenderThread::Get()->AddObserver(web_cache_observer_.get()); +} + +} // namespace engine +} // namespace blimp
diff --git a/blimp/engine/renderer/blimp_content_renderer_client.h b/blimp/engine/renderer/blimp_content_renderer_client.h new file mode 100644 index 0000000..0006200 --- /dev/null +++ b/blimp/engine/renderer/blimp_content_renderer_client.h
@@ -0,0 +1,37 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BLIMP_ENGINE_RENDERER_BLIMP_CONTENT_RENDERER_CLIENT_H_ +#define BLIMP_ENGINE_RENDERER_BLIMP_CONTENT_RENDERER_CLIENT_H_ + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/renderer/content_renderer_client.h" + +namespace web_cache { +class WebCacheRenderProcessObserver; +} + +namespace blimp { +namespace engine { + +class BlimpContentRendererClient : public content::ContentRendererClient { + public: + BlimpContentRendererClient(); + ~BlimpContentRendererClient() override; + + // content::ContentRendererClient implementation. + void RenderThreadStarted() override; + + private: + // This observer manages the process-global web cache. + scoped_ptr<web_cache::WebCacheRenderProcessObserver> web_cache_observer_; + + DISALLOW_COPY_AND_ASSIGN(BlimpContentRendererClient); +}; + +} // namespace engine +} // namespace blimp + +#endif // BLIMP_ENGINE_RENDERER_BLIMP_CONTENT_RENDERER_CLIENT_H_
diff --git a/blimp/engine/ui/BUILD.gn b/blimp/engine/ui/BUILD.gn new file mode 100644 index 0000000..4e88178 --- /dev/null +++ b/blimp/engine/ui/BUILD.gn
@@ -0,0 +1,14 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("ui") { + sources = [ + "blimp_screen.cc", + "blimp_screen.h", + ] + + deps = [ + "//ui/gfx", + ] +}
diff --git a/blimp/engine/ui/blimp_screen.cc b/blimp/engine/ui/blimp_screen.cc new file mode 100644 index 0000000..2eba20f3 --- /dev/null +++ b/blimp/engine/ui/blimp_screen.cc
@@ -0,0 +1,77 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "blimp/engine/ui/blimp_screen.h" + +namespace blimp { +namespace engine { + +namespace { + +const int64 kDisplayId = 1; +const int kDefaultDisplayWidth = 1; +const int kDefaultDisplayHeight = 1; +const float kDefaultScale = 1.0f; +const int kNumDisplays = 1; + +} // namespace + +BlimpScreen::BlimpScreen() : display_(kDisplayId) { + display_.SetScaleAndBounds( + kDefaultScale, gfx::Rect(kDefaultDisplayWidth, kDefaultDisplayHeight)); +} + +BlimpScreen::~BlimpScreen() {} + +void BlimpScreen::UpdateDisplaySize(const gfx::Size& size) { + display_.SetScaleAndBounds(kDefaultScale, gfx::Rect(size)); +} + +gfx::Point BlimpScreen::GetCursorScreenPoint() { + return gfx::Point(); +} + +gfx::NativeWindow BlimpScreen::GetWindowUnderCursor() { + NOTIMPLEMENTED(); + return gfx::NativeWindow(nullptr); +} + +gfx::NativeWindow BlimpScreen::GetWindowAtScreenPoint(const gfx::Point& point) { + NOTIMPLEMENTED(); + return gfx::NativeWindow(nullptr); +} + +int BlimpScreen::GetNumDisplays() const { + return kNumDisplays; +} + +std::vector<gfx::Display> BlimpScreen::GetAllDisplays() const { + return std::vector<gfx::Display>(1, display_); +} + +gfx::Display BlimpScreen::GetDisplayNearestWindow( + gfx::NativeWindow window) const { + return display_; +} + +gfx::Display BlimpScreen::GetDisplayNearestPoint( + const gfx::Point& point) const { + return display_; +} + +gfx::Display BlimpScreen::GetDisplayMatching( + const gfx::Rect& match_rect) const { + return display_; +} + +gfx::Display BlimpScreen::GetPrimaryDisplay() const { + return display_; +} + +void BlimpScreen::AddObserver(gfx::DisplayObserver* observer) {} + +void BlimpScreen::RemoveObserver(gfx::DisplayObserver* observer) {} + +} // namespace engine +} // namespace blimp
diff --git a/blimp/engine/ui/blimp_screen.h b/blimp/engine/ui/blimp_screen.h new file mode 100644 index 0000000..99858b8a --- /dev/null +++ b/blimp/engine/ui/blimp_screen.h
@@ -0,0 +1,47 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BLIMP_ENGINE_UI_BLIMP_SCREEN_H_ +#define BLIMP_ENGINE_UI_BLIMP_SCREEN_H_ + +#include <vector> + +#include "ui/gfx/display.h" +#include "ui/gfx/screen.h" + +namespace blimp { +namespace engine { + +// Presents the client's single screen. +class BlimpScreen : public gfx::Screen { + public: + BlimpScreen(); + ~BlimpScreen() override; + + // Updates the size reported by the primary display. + void UpdateDisplaySize(const gfx::Size& size); + + // gfx::Screen implementation. + gfx::Point GetCursorScreenPoint() override; + gfx::NativeWindow GetWindowUnderCursor() override; + gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override; + int GetNumDisplays() const override; + std::vector<gfx::Display> GetAllDisplays() const override; + gfx::Display GetDisplayNearestWindow(gfx::NativeView view) const override; + gfx::Display GetDisplayNearestPoint(const gfx::Point& point) const override; + gfx::Display GetDisplayMatching(const gfx::Rect& match_rect) const override; + gfx::Display GetPrimaryDisplay() const override; + void AddObserver(gfx::DisplayObserver* observer) override; + void RemoveObserver(gfx::DisplayObserver* observer) override; + + private: + gfx::Display display_; + + DISALLOW_COPY_AND_ASSIGN(BlimpScreen); +}; + +} // namespace engine +} // namespace blimp + +#endif // BLIMP_ENGINE_UI_BLIMP_SCREEN_H_
diff --git a/build/android/copy_ex.gypi b/build/android/copy_ex.gypi new file mode 100644 index 0000000..bae0dd24 --- /dev/null +++ b/build/android/copy_ex.gypi
@@ -0,0 +1,59 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Copy files to a directory with the option to clear directory first. +# +# Variables: +# dest_path - directory to copy files to. +# src_files - a list of files to copy. +# clear - optional, if set, clear directory before copying files. +# stamp - optional, path to touch on success. +# +# Exmaple +# { +# 'target_name': 'copy_assets', +# 'type': 'none', +# 'variables': { +# 'dest_path': 'apk/assets/path', +# 'src_files': ['path1/fr.pak'], +# 'clear': 1, +# }, +# 'includes': [ '../build/android/copy_ex.gypi' ], +# }, +# +{ + 'variables': { + 'clear%': 0, + 'stamp%': '', + }, + 'actions': [{ + 'action_name': '<(_target_name)_copy_ex', + 'variables': { + 'additional_args':[], + 'conditions': [ + ['clear == 1', { + 'additional_args': ['--clear'], + }], + ['stamp != ""', { + 'additional_args': ['--stamp', '<(stamp)'], + }], + ], + }, + 'inputs': [ + '<(DEPTH)/build/android/gyp/copy_ex.py', + '<(DEPTH)/build/android/gyp/generate_copy_ex_outputs.py', + '<@(src_files)', + ], + 'outputs': [ + '<(stamp)', + '<!@pymod_do_main(generate_copy_ex_outputs --dest-path <(dest_path) --src-files <(src_files))' + ], + 'action': [ + 'python', '<(DEPTH)/build/android/gyp/copy_ex.py', + '--dest', '<(dest_path)', + '--files', '<(src_files)', + '<(additional_args)', + ], + }], +}
diff --git a/build/android/gyp/generate_copy_ex_outputs.py b/build/android/gyp/generate_copy_ex_outputs.py new file mode 100755 index 0000000..e425b4a6 --- /dev/null +++ b/build/android/gyp/generate_copy_ex_outputs.py
@@ -0,0 +1,33 @@ +#!/usr/bin/env python +# +# Copyright (c) 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# Generate outputs according source files and destination path for +# copy_ex.gypi + +import argparse +import os +import sys + +def DoMain(argv): + parser = argparse.ArgumentParser(prog='generate_copy_ex_outputs') + parser.add_argument('--src-files', + nargs = '+', + help = 'a list of files to copy') + parser.add_argument('--dest-path', + required = True, + help = 'the directory to copy file to') + options = parser.parse_args(argv) + # Quote each element so filename spaces don't mess up gyp's attempt to parse + # it into a list. + return ' '.join('"%s"' % os.path.join(options.dest_path, + os.path.basename(src)) + for src in options.src_files) + +if __name__ == '__main__': + results = DoMain(sys.argv[1:]) + if results: + print results +
diff --git a/build/android/pylib/constants/__init__.py b/build/android/pylib/constants/__init__.py index 96a61511..cbc475e 100644 --- a/build/android/pylib/constants/__init__.py +++ b/build/android/pylib/constants/__init__.py
@@ -158,11 +158,11 @@ ANDROID_SDK_VERSION = version_codes.MARSHMALLOW ANDROID_SDK_BUILD_TOOLS_VERSION = '23.0.0' ANDROID_SDK_ROOT = os.path.join(DIR_SOURCE_ROOT, - 'third_party/android_tools/sdk') + 'third_party', 'android_tools', 'sdk') ANDROID_SDK_TOOLS = os.path.join(ANDROID_SDK_ROOT, 'build-tools', ANDROID_SDK_BUILD_TOOLS_VERSION) ANDROID_NDK_ROOT = os.path.join(DIR_SOURCE_ROOT, - 'third_party/android_tools/ndk') + 'third_party', 'android_tools', 'ndk') PROGUARD_SCRIPT_PATH = os.path.join( ANDROID_SDK_ROOT, 'tools', 'proguard', 'bin', 'proguard.sh')
diff --git a/build/android/pylib/instrumentation/test_jar.py b/build/android/pylib/instrumentation/test_jar.py index cabcc8a..634cf470 100644 --- a/build/android/pylib/instrumentation/test_jar.py +++ b/build/android/pylib/instrumentation/test_jar.py
@@ -165,8 +165,10 @@ return sorted(tests_missing_annotations) def _IsTestValidForSdkRange(self, test_name, attached_min_sdk_level): - required_min_sdk_level = int( - self.GetTestAnnotations(test_name).get('MinAndroidSdkLevel', 0)) + required_min_sdk_level = self.GetTestAnnotations( + test_name).get('MinAndroidSdkLevel', None) + if required_min_sdk_level: + required_min_sdk_level = int(required_min_sdk_level['value']) return (required_min_sdk_level is None or attached_min_sdk_level >= required_min_sdk_level)
diff --git a/build/android/pylib/instrumentation/test_runner.py b/build/android/pylib/instrumentation/test_runner.py index 5266aed..9473566 100644 --- a/build/android/pylib/instrumentation/test_runner.py +++ b/build/android/pylib/instrumentation/test_runner.py
@@ -156,7 +156,8 @@ Whether the feature being tested is FirstRunExperience. """ annotations = self.test_pkg.GetTestAnnotations(test) - return 'FirstRunExperience' == annotations.get('Feature', None) + feature = annotations.get('Feature', None) + return feature and 'FirstRunExperience' in feature['value'] def _IsPerfTest(self, test): """Determines whether a test is a performance test. @@ -276,10 +277,10 @@ timeout_scale = 1 if 'TimeoutScale' in annotations: try: - timeout_scale = int(annotations['TimeoutScale']) + timeout_scale = int(annotations['TimeoutScale']['value']) except ValueError: logging.warning('Non-integer value of TimeoutScale ignored. (%s)', - annotations['TimeoutScale']) + annotations['TimeoutScale']['value']) if self.options.wait_for_debugger: timeout_scale *= 100 return timeout_scale
diff --git a/build/android/pylib/uiautomator/test_runner.py b/build/android/pylib/uiautomator/test_runner.py index a2d002ba..450cfaf 100644 --- a/build/android/pylib/uiautomator/test_runner.py +++ b/build/android/pylib/uiautomator/test_runner.py
@@ -62,7 +62,8 @@ self.device.ClearApplicationState(self._package) if self.flags: annotations = self.test_pkg.GetTestAnnotations(test) - if 'FirstRunExperience' == annotations.get('Feature', None): + feature = annotations.get('Feature', None) + if feature and 'FirstRunExperience' in feature['value']: self.flags.RemoveFlags(['--disable-fre']) else: self.flags.AddFlags(['--disable-fre'])
diff --git a/build/android/pylib/utils/proguard.py b/build/android/pylib/utils/proguard.py index 251cc4d..4f5a5213 100644 --- a/build/android/pylib/utils/proguard.py +++ b/build/android/pylib/utils/proguard.py
@@ -18,7 +18,9 @@ _PROGUARD_METHOD_RE = re.compile(r'\s*?- Method:\s*(\S*)[(].*$') _PROGUARD_ANNOTATION_RE = re.compile(r'\s*?- Annotation \[L(\S*);\]:$') _PROGUARD_ANNOTATION_CONST_RE = ( - re.compile(r'\s*?- Constant element value.*$')) + re.compile(r'\s*?- Constant element value \[(\S*) .*\]$')) +_PROGUARD_ANNOTATION_ARRAY_RE = ( + re.compile(r'\s*?- Array element value \[(\S*)\]:$')) _PROGUARD_ANNOTATION_VALUE_RE = re.compile(r'\s*?- \S+? \[(.*)\]$') _PROGUARD_PATH_SDK = os.path.join( @@ -44,11 +46,11 @@ { 'class': '', 'superclass': '', - 'annotations': {}, + 'annotations': {/* dict -- see below */}, 'methods': [ { 'method': '', - 'annotations': {}, + 'annotations': {/* dict -- see below */}, }, ... ], @@ -56,6 +58,26 @@ ... ], } + + Annotations dict format: + { + 'empty-annotation-class-name': None, + 'annotation-class-name': { + 'field': 'primitive-value', + 'field': [ 'array-item-1', 'array-item-2', ... ], + /* Object fields are not supported yet, coming soon! */ + 'field': { + /* Object value */ + 'field': 'primitive-value', + 'field': [ 'array-item-1', 'array-item-2', ... ], + 'field': { /* Object value */ } + } + } + } + + Note that for top-level annotations their class names are used for + identification, whereas for any nested annotations the corresponding + field names are used. """ with tempfile.NamedTemporaryFile() as proguard_output: @@ -69,15 +91,66 @@ '-dump', proguard_output.name]) return Parse(proguard_output) +class _ParseState(object): + def __init__(self): + self.class_result = None + self.method_result = None + self.annotation = None + self.annotation_field = None + + def ResetPerSection(self): + self.InitMethod(None) + + def InitClass(self, class_result): + self.InitMethod(None) + self.class_result = class_result + + def InitMethod(self, method_result): + self.annotation = None + self.ResetAnnotationField() + self.method_result = method_result + if method_result: + self.class_result['methods'].append(method_result) + + def InitAnnotation(self, annotation): + self.annotation = annotation + self.GetAnnotations()[annotation] = None + self.ResetAnnotationField() + + def ResetAnnotationField(self): + self.annotation_field = None + + def InitAnnotationField(self, field, value): + if not self.GetCurrentAnnotation(): + self.GetAnnotations()[self.annotation] = {} + self.GetCurrentAnnotation()[field] = value + self.annotation_field = field + + def UpdateCurrentAnnotationField(self, value): + ann = self.GetCurrentAnnotation() + assert ann + if type(ann[self.annotation_field]) is list: + ann[self.annotation_field].append(value) + else: + ann[self.annotation_field] = value + self.ResetAnnotationField() + + def GetAnnotations(self): + if self.method_result: + return self.method_result['annotations'] + else: + return self.class_result['annotations'] + + def GetCurrentAnnotation(self): + assert self.annotation + return self.GetAnnotations()[self.annotation] + def Parse(proguard_output): results = { 'classes': [], } - annotation = None - annotation_has_value = False - class_result = None - method_result = None + state = _ParseState() for line in proguard_output: line = line.strip('\r\n') @@ -91,57 +164,56 @@ 'methods': [], } results['classes'].append(class_result) - annotation = None - annotation_has_value = False - method_result = None + state.InitClass(class_result) continue - if not class_result: + if not state.class_result: continue m = _PROGUARD_SUPERCLASS_RE.match(line) if m: - class_result['superclass'] = m.group(1).replace('/', '.') + state.class_result['superclass'] = m.group(1).replace('/', '.') continue m = _PROGUARD_SECTION_RE.match(line) if m: - annotation = None - annotation_has_value = False - method_result = None + state.ResetPerSection() continue m = _PROGUARD_METHOD_RE.match(line) if m: - method_result = { + state.InitMethod({ 'method': m.group(1), 'annotations': {}, - } - class_result['methods'].append(method_result) - annotation = None - annotation_has_value = False + }) continue m = _PROGUARD_ANNOTATION_RE.match(line) if m: # Ignore the annotation package. - annotation = m.group(1).split('/')[-1] - if method_result: - method_result['annotations'][annotation] = None - else: - class_result['annotations'][annotation] = None + state.InitAnnotation(m.group(1).split('/')[-1]) continue - if annotation: - if not annotation_has_value: - m = _PROGUARD_ANNOTATION_CONST_RE.match(line) - annotation_has_value = bool(m) - else: + if state.annotation: + if state.annotation_field: m = _PROGUARD_ANNOTATION_VALUE_RE.match(line) if m: - if method_result: - method_result['annotations'][annotation] = m.group(1) - else: - class_result['annotations'][annotation] = m.group(1) - annotation_has_value = None + state.UpdateCurrentAnnotationField(m.group(1)) + continue + m = _PROGUARD_ANNOTATION_CONST_RE.match(line) + if m: + if not m.group(1) == '(default)': + state.ResetAnnotationField() + else: + m = _PROGUARD_ANNOTATION_ARRAY_RE.match(line) + if m: + state.ResetAnnotationField() + if not state.annotation_field: + m = _PROGUARD_ANNOTATION_CONST_RE.match(line) + if m: + state.InitAnnotationField(m.group(1), None) + continue + m = _PROGUARD_ANNOTATION_ARRAY_RE.match(line) + if m: + state.InitAnnotationField(m.group(1), []) return results
diff --git a/build/android/pylib/utils/proguard_test.py b/build/android/pylib/utils/proguard_test.py index e5d5e013..e8c81cc 100644 --- a/build/android/pylib/utils/proguard_test.py +++ b/build/android/pylib/utils/proguard_test.py
@@ -8,6 +8,9 @@ class TestParse(unittest.TestCase): + def setUp(self): + self.maxDiff = None + def testClass(self): actual = proguard.Parse( ['- Program class: org/example/Test', @@ -52,7 +55,12 @@ ' - Annotation [Lorg/example/Annotation;]:', ' - Annotation [Lorg/example/AnnotationWithValue;]:', ' - Constant element value [attr \'13\']', - ' - Utf8 [val]']) + ' - Utf8 [val]', + ' - Annotation [Lorg/example/AnnotationWithTwoValues;]:', + ' - Constant element value [attr1 \'13\']', + ' - Utf8 [val1]', + ' - Constant element value [attr2 \'13\']', + ' - Utf8 [val2]']) expected = { 'classes': [ { @@ -60,7 +68,39 @@ 'superclass': '', 'annotations': { 'Annotation': None, - 'AnnotationWithValue': 'val' + 'AnnotationWithValue': {'attr': 'val'}, + 'AnnotationWithTwoValues': {'attr1': 'val1', 'attr2': 'val2'} + }, + 'methods': [] + } + ] + } + self.assertEquals(expected, actual) + + def testClassAnnotationWithArrays(self): + actual = proguard.Parse( + ['- Program class: org/example/Test', + ' - Annotation [Lorg/example/AnnotationWithEmptyArray;]:', + ' - Array element value [arrayAttr]:', + ' - Annotation [Lorg/example/AnnotationWithOneElemArray;]:', + ' - Array element value [arrayAttr]:', + ' - Constant element value [(default) \'13\']', + ' - Utf8 [val]', + ' - Annotation [Lorg/example/AnnotationWithTwoElemArray;]:', + ' - Array element value [arrayAttr]:', + ' - Constant element value [(default) \'13\']', + ' - Utf8 [val1]', + ' - Constant element value [(default) \'13\']', + ' - Utf8 [val2]']) + expected = { + 'classes': [ + { + 'class': 'org.example.Test', + 'superclass': '', + 'annotations': { + 'AnnotationWithEmptyArray': {'arrayAttr': []}, + 'AnnotationWithOneElemArray': {'arrayAttr': ['val']}, + 'AnnotationWithTwoElemArray': {'arrayAttr': ['val1', 'val2']} }, 'methods': [] } @@ -76,7 +116,12 @@ ' - Annotation [Lorg/example/Annotation;]:', ' - Annotation [Lorg/example/AnnotationWithValue;]:', ' - Constant element value [attr \'13\']', - ' - Utf8 [val]']) + ' - Utf8 [val]', + ' - Annotation [Lorg/example/AnnotationWithTwoValues;]:', + ' - Constant element value [attr1 \'13\']', + ' - Utf8 [val1]', + ' - Constant element value [attr2 \'13\']', + ' - Utf8 [val2]']) expected = { 'classes': [ { @@ -88,7 +133,94 @@ 'method': 'Test', 'annotations': { 'Annotation': None, - 'AnnotationWithValue': 'val' + 'AnnotationWithValue': {'attr': 'val'}, + 'AnnotationWithTwoValues': {'attr1': 'val1', 'attr2': 'val2'} + }, + } + ] + } + ] + } + self.assertEquals(expected, actual) + + def testMethodAnnotationWithArrays(self): + actual = proguard.Parse( + ['- Program class: org/example/Test', + 'Methods (count = 1):', + '- Method: Test()V', + ' - Annotation [Lorg/example/AnnotationWithEmptyArray;]:', + ' - Array element value [arrayAttr]:', + ' - Annotation [Lorg/example/AnnotationWithOneElemArray;]:', + ' - Array element value [arrayAttr]:', + ' - Constant element value [(default) \'13\']', + ' - Utf8 [val]', + ' - Annotation [Lorg/example/AnnotationWithTwoElemArray;]:', + ' - Array element value [arrayAttr]:', + ' - Constant element value [(default) \'13\']', + ' - Utf8 [val1]', + ' - Constant element value [(default) \'13\']', + ' - Utf8 [val2]']) + expected = { + 'classes': [ + { + 'class': 'org.example.Test', + 'superclass': '', + 'annotations': {}, + 'methods': [ + { + 'method': 'Test', + 'annotations': { + 'AnnotationWithEmptyArray': {'arrayAttr': []}, + 'AnnotationWithOneElemArray': {'arrayAttr': ['val']}, + 'AnnotationWithTwoElemArray': {'arrayAttr': ['val1', 'val2']} + }, + } + ] + } + ] + } + self.assertEquals(expected, actual) + + def testMethodAnnotationWithPrimitivesAndArrays(self): + actual = proguard.Parse( + ['- Program class: org/example/Test', + 'Methods (count = 1):', + '- Method: Test()V', + ' - Annotation [Lorg/example/AnnotationPrimitiveThenArray;]:', + ' - Constant element value [attr \'13\']', + ' - Utf8 [val]', + ' - Array element value [arrayAttr]:', + ' - Constant element value [(default) \'13\']', + ' - Utf8 [val]', + ' - Annotation [Lorg/example/AnnotationArrayThenPrimitive;]:', + ' - Array element value [arrayAttr]:', + ' - Constant element value [(default) \'13\']', + ' - Utf8 [val]', + ' - Constant element value [attr \'13\']', + ' - Utf8 [val]', + ' - Annotation [Lorg/example/AnnotationTwoArrays;]:', + ' - Array element value [arrayAttr1]:', + ' - Constant element value [(default) \'13\']', + ' - Utf8 [val1]', + ' - Array element value [arrayAttr2]:', + ' - Constant element value [(default) \'13\']', + ' - Utf8 [val2]']) + expected = { + 'classes': [ + { + 'class': 'org.example.Test', + 'superclass': '', + 'annotations': {}, + 'methods': [ + { + 'method': 'Test', + 'annotations': { + 'AnnotationPrimitiveThenArray': {'attr': 'val', + 'arrayAttr': ['val']}, + 'AnnotationArrayThenPrimitive': {'arrayAttr': ['val'], + 'attr': 'val'}, + 'AnnotationTwoArrays': {'arrayAttr1': ['val1'], + 'arrayAttr2': ['val2']} }, } ]
diff --git a/build/android/tombstones.py b/build/android/tombstones.py index f4be6bd..c961d75 100755 --- a/build/android/tombstones.py +++ b/build/android/tombstones.py
@@ -23,7 +23,6 @@ from devil.android import device_utils from devil.utils import run_tests_helper - _TZ_UTC = {'TZ': 'UTC'} def _ListTombstones(device):
diff --git a/build/common.gypi b/build/common.gypi index 84d9514..f5743e21 100644 --- a/build/common.gypi +++ b/build/common.gypi
@@ -1515,6 +1515,16 @@ # Compile d8 for the host toolset. 'v8_toolset_for_d8': 'host', + # V8 extras + # Adding V8 extras files requires API owners review + # Be sure to synchronize with build/module_args/v8.gni + + 'v8_extra_library_files': [ + ], + 'v8_experimental_extra_library_files': [ + '../third_party/WebKit/Source/core/streams/ByteLengthQueuingStrategy.js', + ], + # Use brlapi from brltty for braille display support. 'use_brlapi%': 0,
diff --git a/build/module_args/v8.gni b/build/module_args/v8.gni index 4a4caed..f18bfaf 100644 --- a/build/module_args/v8.gni +++ b/build/module_args/v8.gni
@@ -11,5 +11,10 @@ v8_use_external_startup_data = !(is_chromeos || is_win || is_ios) +# V8 extras +# Adding V8 extras files requires API owners review +# Be sure to synchronize with build/common.gypi + v8_extra_library_files = [] -v8_experimental_extra_library_files = [] +v8_experimental_extra_library_files = + [ "../third_party/WebKit/Source/core/streams/ByteLengthQueuingStrategy.js" ]
diff --git a/cc/animation/scrollbar_animation_controller.cc b/cc/animation/scrollbar_animation_controller.cc index 48b199d..2c11f73 100644 --- a/cc/animation/scrollbar_animation_controller.cc +++ b/cc/animation/scrollbar_animation_controller.cc
@@ -12,26 +12,22 @@ namespace cc { ScrollbarAnimationController::ScrollbarAnimationController( - LayerImpl* scroll_layer, + int scroll_layer_id, ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, base::TimeDelta resize_delay_before_starting, base::TimeDelta duration) - : scroll_layer_(scroll_layer), - client_(client), + : client_(client), delay_before_starting_(delay_before_starting), resize_delay_before_starting_(resize_delay_before_starting), duration_(duration), is_animating_(false), + scroll_layer_id_(scroll_layer_id), currently_scrolling_(false), scroll_gesture_has_scrolled_(false), - weak_factory_(this) { -} + weak_factory_(this) {} -ScrollbarAnimationController::~ScrollbarAnimationController() { - if (is_animating_) - client_->StopAnimatingScrollbarAnimationController(this); -} +ScrollbarAnimationController::~ScrollbarAnimationController() {} void ScrollbarAnimationController::Animate(base::TimeTicks now) { if (!is_animating_) @@ -42,6 +38,9 @@ float progress = AnimationProgressAtTime(now); RunAnimationFrame(progress); + + if (is_animating_) + client_->SetNeedsAnimateForScrollbarAnimation(); } float ScrollbarAnimationController::AnimationProgressAtTime( @@ -90,12 +89,15 @@ delayed_scrollbar_fade_.Cancel(); is_animating_ = true; last_awaken_time_ = base::TimeTicks(); - client_->StartAnimatingScrollbarAnimationController(this); + client_->SetNeedsAnimateForScrollbarAnimation(); } void ScrollbarAnimationController::StopAnimation() { is_animating_ = false; - client_->StopAnimatingScrollbarAnimationController(this); +} + +ScrollbarSet ScrollbarAnimationController::Scrollbars() const { + return client_->ScrollbarsFor(scroll_layer_id_); } } // namespace cc
diff --git a/cc/animation/scrollbar_animation_controller.h b/cc/animation/scrollbar_animation_controller.h index 795c7c1..3bb1507 100644 --- a/cc/animation/scrollbar_animation_controller.h +++ b/cc/animation/scrollbar_animation_controller.h
@@ -10,6 +10,7 @@ #include "base/time/time.h" #include "cc/base/cc_export.h" #include "cc/layers/layer_impl.h" +#include "cc/layers/scrollbar_layer_impl_base.h" #include "ui/gfx/geometry/vector2d_f.h" namespace cc { @@ -18,13 +19,11 @@ class CC_EXPORT ScrollbarAnimationControllerClient { public: - virtual void StartAnimatingScrollbarAnimationController( - ScrollbarAnimationController* controller) = 0; - virtual void StopAnimatingScrollbarAnimationController( - ScrollbarAnimationController* controller) = 0; virtual void PostDelayedScrollbarAnimationTask(const base::Closure& task, base::TimeDelta delay) = 0; virtual void SetNeedsRedrawForScrollbarAnimation() = 0; + virtual void SetNeedsAnimateForScrollbarAnimation() = 0; + virtual ScrollbarSet ScrollbarsFor(int scroll_layer_id) const = 0; protected: virtual ~ScrollbarAnimationControllerClient() {} @@ -46,7 +45,7 @@ virtual void DidMouseMoveNear(float distance) {} protected: - ScrollbarAnimationController(LayerImpl* scroll_layer, + ScrollbarAnimationController(int scroll_layer_id, ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, base::TimeDelta resize_delay_before_starting, @@ -56,8 +55,8 @@ void StartAnimation(); void StopAnimation(); + ScrollbarSet Scrollbars() const; - LayerImpl* scroll_layer_; ScrollbarAnimationControllerClient* client_; private: @@ -74,6 +73,7 @@ bool is_animating_; + int scroll_layer_id_; bool currently_scrolling_; bool scroll_gesture_has_scrolled_; base::CancelableClosure delayed_scrollbar_fade_;
diff --git a/cc/animation/scrollbar_animation_controller_linear_fade.cc b/cc/animation/scrollbar_animation_controller_linear_fade.cc index 72fdd58..13b9754 100644 --- a/cc/animation/scrollbar_animation_controller_linear_fade.cc +++ b/cc/animation/scrollbar_animation_controller_linear_fade.cc
@@ -12,28 +12,27 @@ scoped_ptr<ScrollbarAnimationControllerLinearFade> ScrollbarAnimationControllerLinearFade::Create( - LayerImpl* scroll_layer, + int scroll_layer_id, ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, base::TimeDelta resize_delay_before_starting, base::TimeDelta duration) { return make_scoped_ptr(new ScrollbarAnimationControllerLinearFade( - scroll_layer, client, delay_before_starting, resize_delay_before_starting, - duration)); + scroll_layer_id, client, delay_before_starting, + resize_delay_before_starting, duration)); } ScrollbarAnimationControllerLinearFade::ScrollbarAnimationControllerLinearFade( - LayerImpl* scroll_layer, + int scroll_layer_id, ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, base::TimeDelta resize_delay_before_starting, base::TimeDelta duration) - : ScrollbarAnimationController(scroll_layer, + : ScrollbarAnimationController(scroll_layer_id, client, delay_before_starting, resize_delay_before_starting, - duration) { -} + duration) {} ScrollbarAnimationControllerLinearFade:: ~ScrollbarAnimationControllerLinearFade() { @@ -53,17 +52,11 @@ void ScrollbarAnimationControllerLinearFade::ApplyOpacityToScrollbars( float opacity) { - if (!scroll_layer_->scrollbars()) - return; - - LayerImpl::ScrollbarSet* scrollbars = scroll_layer_->scrollbars(); - for (LayerImpl::ScrollbarSet::iterator it = scrollbars->begin(); - it != scrollbars->end(); ++it) { - ScrollbarLayerImplBase* scrollbar = *it; - - if (scrollbar->is_overlay_scrollbar()) - scrollbar->OnOpacityAnimated(scrollbar->CanScrollOrientation() ? opacity - : 0); + for (ScrollbarLayerImplBase* scrollbar : Scrollbars()) { + if (!scrollbar->is_overlay_scrollbar()) + continue; + scrollbar->OnOpacityAnimated(scrollbar->CanScrollOrientation() ? opacity + : 0); } }
diff --git a/cc/animation/scrollbar_animation_controller_linear_fade.h b/cc/animation/scrollbar_animation_controller_linear_fade.h index 05940a0..f6f40112 100644 --- a/cc/animation/scrollbar_animation_controller_linear_fade.h +++ b/cc/animation/scrollbar_animation_controller_linear_fade.h
@@ -16,7 +16,7 @@ : public ScrollbarAnimationController { public: static scoped_ptr<ScrollbarAnimationControllerLinearFade> Create( - LayerImpl* scroll_layer, + int scroll_layer_id, ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, base::TimeDelta resize_delay_before_starting, @@ -28,7 +28,7 @@ protected: ScrollbarAnimationControllerLinearFade( - LayerImpl* scroll_layer, + int scroll_layer_id, ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, base::TimeDelta resize_delay_before_starting,
diff --git a/cc/animation/scrollbar_animation_controller_linear_fade_unittest.cc b/cc/animation/scrollbar_animation_controller_linear_fade_unittest.cc index 6d2d3e8..2c8f993 100644 --- a/cc/animation/scrollbar_animation_controller_linear_fade_unittest.cc +++ b/cc/animation/scrollbar_animation_controller_linear_fade_unittest.cc
@@ -21,16 +21,10 @@ public ScrollbarAnimationControllerClient { public: ScrollbarAnimationControllerLinearFadeTest() - : host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_) {} + : host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_), + did_request_redraw_(false), + did_request_animate_(false) {} - void StartAnimatingScrollbarAnimationController( - ScrollbarAnimationController* controller) override { - is_animating_ = true; - } - void StopAnimatingScrollbarAnimationController( - ScrollbarAnimationController* controller) override { - is_animating_ = false; - } void PostDelayedScrollbarAnimationTask(const base::Closure& start_fade, base::TimeDelta delay) override { start_fade_ = start_fade; @@ -39,6 +33,12 @@ void SetNeedsRedrawForScrollbarAnimation() override { did_request_redraw_ = true; } + void SetNeedsAnimateForScrollbarAnimation() override { + did_request_animate_ = true; + } + ScrollbarSet ScrollbarsFor(int scroll_layer_id) const override { + return host_impl_.ScrollbarsFor(scroll_layer_id); + } protected: void SetUp() override { @@ -62,13 +62,12 @@ LayerImpl* scroll_layer_ptr = scroll_layer.get(); clip_layer_->AddChild(scroll_layer.Pass()); - scrollbar_layer_->SetScrollLayerAndClipLayerByIds(scroll_layer_ptr->id(), - clip_layer_->id()); + scrollbar_layer_->SetScrollLayerId(scroll_layer_ptr->id()); clip_layer_->SetBounds(gfx::Size(100, 100)); scroll_layer_ptr->SetBounds(gfx::Size(200, 200)); scrollbar_controller_ = ScrollbarAnimationControllerLinearFade::Create( - scroll_layer_ptr, this, base::TimeDelta::FromSeconds(2), + scroll_layer_ptr->id(), this, base::TimeDelta::FromSeconds(2), base::TimeDelta::FromSeconds(5), base::TimeDelta::FromSeconds(3)); } @@ -84,8 +83,8 @@ base::Closure start_fade_; base::TimeDelta delay_; - bool is_animating_; bool did_request_redraw_; + bool did_request_animate_; }; class VerticalScrollbarAnimationControllerLinearFadeTest @@ -263,8 +262,10 @@ base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); scrollbar_controller_->DidScrollBegin(); + EXPECT_FALSE(did_request_animate_); scrollbar_controller_->DidScrollUpdate(false); + EXPECT_FALSE(did_request_animate_); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); EXPECT_TRUE(start_fade_.Equals(base::Closure())); @@ -272,23 +273,30 @@ time += base::TimeDelta::FromSeconds(100); scrollbar_controller_->Animate(time); + EXPECT_FALSE(did_request_animate_); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); scrollbar_controller_->DidScrollEnd(); + EXPECT_FALSE(did_request_animate_); start_fade_.Run(); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; time += base::TimeDelta::FromSeconds(2); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); @@ -298,84 +306,101 @@ scrollbar_controller_->DidScrollEnd(); start_fade_.Run(); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; time += base::TimeDelta::FromSeconds(2); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_FALSE(did_request_animate_); EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity()); - EXPECT_FALSE(is_animating_); } TEST_F(ScrollbarAnimationControllerLinearFadeTest, AwakenByProgrammaticScroll) { base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); scrollbar_controller_->DidScrollUpdate(false); + EXPECT_FALSE(did_request_animate_); start_fade_.Run(); - EXPECT_TRUE(is_animating_); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity()); scrollbar_controller_->DidScrollUpdate(false); + EXPECT_FALSE(did_request_animate_); start_fade_.Run(); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; time += base::TimeDelta::FromSeconds(2); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); scrollbar_controller_->DidScrollUpdate(false); start_fade_.Run(); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_FALSE(did_request_animate_); EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity()); - EXPECT_FALSE(is_animating_); } TEST_F(ScrollbarAnimationControllerLinearFadeTest, @@ -384,31 +409,37 @@ time += base::TimeDelta::FromSeconds(1); scrollbar_controller_->DidScrollUpdate(false); start_fade_.Run(); - EXPECT_TRUE(is_animating_); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity()); scrollbar_controller_->DidScrollBegin(); + EXPECT_FALSE(did_request_animate_); EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity()); scrollbar_controller_->DidScrollEnd(); + EXPECT_FALSE(did_request_animate_); EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_FALSE(did_request_animate_); EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity()); - EXPECT_FALSE(is_animating_); } TEST_F(ScrollbarAnimationControllerLinearFadeTest, @@ -416,30 +447,38 @@ base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); scrollbar_controller_->DidScrollUpdate(false); + EXPECT_FALSE(did_request_animate_); start_fade_.Run(); - EXPECT_TRUE(is_animating_); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity()); scrollbar_controller_->DidScrollBegin(); EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); - EXPECT_TRUE(is_animating_); scrollbar_controller_->Animate(time); + EXPECT_TRUE(did_request_animate_); + did_request_animate_ = false; EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); scrollbar_controller_->DidScrollUpdate(false); + EXPECT_FALSE(did_request_animate_); EXPECT_FLOAT_EQ(1, scrollbar_layer_->opacity()); time += base::TimeDelta::FromSeconds(1); scrollbar_controller_->DidScrollEnd(); + EXPECT_FALSE(did_request_animate_); EXPECT_FLOAT_EQ(1, scrollbar_layer_->opacity()); }
diff --git a/cc/animation/scrollbar_animation_controller_thinning.cc b/cc/animation/scrollbar_animation_controller_thinning.cc index 6ced8098..d8a2d6d 100644 --- a/cc/animation/scrollbar_animation_controller_thinning.cc +++ b/cc/animation/scrollbar_animation_controller_thinning.cc
@@ -19,23 +19,23 @@ scoped_ptr<ScrollbarAnimationControllerThinning> ScrollbarAnimationControllerThinning::Create( - LayerImpl* scroll_layer, + int scroll_layer_id, ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, base::TimeDelta resize_delay_before_starting, base::TimeDelta duration) { return make_scoped_ptr(new ScrollbarAnimationControllerThinning( - scroll_layer, client, delay_before_starting, resize_delay_before_starting, - duration)); + scroll_layer_id, client, delay_before_starting, + resize_delay_before_starting, duration)); } ScrollbarAnimationControllerThinning::ScrollbarAnimationControllerThinning( - LayerImpl* scroll_layer, + int scroll_layer_id, ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, base::TimeDelta resize_delay_before_starting, base::TimeDelta duration) - : ScrollbarAnimationController(scroll_layer, + : ScrollbarAnimationController(scroll_layer_id, client, delay_before_starting, resize_delay_before_starting, @@ -135,24 +135,18 @@ void ScrollbarAnimationControllerThinning::ApplyOpacityAndThumbThicknessScale( float opacity, float thumb_thickness_scale) { - if (!scroll_layer_->scrollbars()) - return; + for (ScrollbarLayerImplBase* scrollbar : Scrollbars()) { + if (!scrollbar->is_overlay_scrollbar()) + continue; + float effective_opacity = + scrollbar->CanScrollOrientation() + ? AdjustScale(opacity, scrollbar->opacity(), opacity_change_) + : 0; - LayerImpl::ScrollbarSet* scrollbars = scroll_layer_->scrollbars(); - for (LayerImpl::ScrollbarSet::iterator it = scrollbars->begin(); - it != scrollbars->end(); ++it) { - ScrollbarLayerImplBase* scrollbar = *it; - if (scrollbar->is_overlay_scrollbar()) { - float effectiveOpacity = - scrollbar->CanScrollOrientation() - ? AdjustScale(opacity, scrollbar->opacity(), opacity_change_) - : 0; - - scrollbar->OnOpacityAnimated(effectiveOpacity); - scrollbar->SetThumbThicknessScaleFactor(AdjustScale( - thumb_thickness_scale, scrollbar->thumb_thickness_scale_factor(), - thickness_change_)); - } + scrollbar->OnOpacityAnimated(effective_opacity); + scrollbar->SetThumbThicknessScaleFactor(AdjustScale( + thumb_thickness_scale, scrollbar->thumb_thickness_scale_factor(), + thickness_change_)); } }
diff --git a/cc/animation/scrollbar_animation_controller_thinning.h b/cc/animation/scrollbar_animation_controller_thinning.h index f22d94c..44362bd 100644 --- a/cc/animation/scrollbar_animation_controller_thinning.h +++ b/cc/animation/scrollbar_animation_controller_thinning.h
@@ -18,7 +18,7 @@ : public ScrollbarAnimationController { public: static scoped_ptr<ScrollbarAnimationControllerThinning> Create( - LayerImpl* scroll_layer, + int scroll_layer_id, ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, base::TimeDelta resize_delay_before_starting, @@ -38,7 +38,7 @@ protected: ScrollbarAnimationControllerThinning( - LayerImpl* scroll_layer, + int scroll_layer_id, ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, base::TimeDelta resize_delay_before_starting,
diff --git a/cc/animation/scrollbar_animation_controller_thinning_unittest.cc b/cc/animation/scrollbar_animation_controller_thinning_unittest.cc index 04f81d3..3c5ff361 100644 --- a/cc/animation/scrollbar_animation_controller_thinning_unittest.cc +++ b/cc/animation/scrollbar_animation_controller_thinning_unittest.cc
@@ -23,14 +23,6 @@ ScrollbarAnimationControllerThinningTest() : host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_) {} - void StartAnimatingScrollbarAnimationController( - ScrollbarAnimationController* controller) override { - is_animating_ = true; - } - void StopAnimatingScrollbarAnimationController( - ScrollbarAnimationController* controller) override { - is_animating_ = false; - } void PostDelayedScrollbarAnimationTask(const base::Closure& start_fade, base::TimeDelta delay) override { start_fade_ = start_fade; @@ -39,6 +31,12 @@ void SetNeedsRedrawForScrollbarAnimation() override { did_request_redraw_ = true; } + void SetNeedsAnimateForScrollbarAnimation() override { + did_request_animate_ = true; + } + ScrollbarSet ScrollbarsFor(int scroll_layer_id) const override { + return host_impl_.ScrollbarsFor(scroll_layer_id); + } protected: void SetUp() override { @@ -63,13 +61,12 @@ kIsLeftSideVerticalScrollbar, kIsOverlayScrollbar); - scrollbar_layer_->SetScrollLayerAndClipLayerByIds(scroll_layer_ptr->id(), - clip_layer_->id()); + scrollbar_layer_->SetScrollLayerId(scroll_layer_ptr->id()); clip_layer_->SetBounds(gfx::Size(100, 100)); scroll_layer_ptr->SetBounds(gfx::Size(200, 200)); scrollbar_controller_ = ScrollbarAnimationControllerThinning::Create( - scroll_layer_ptr, this, base::TimeDelta::FromSeconds(2), + scroll_layer_ptr->id(), this, base::TimeDelta::FromSeconds(2), base::TimeDelta::FromSeconds(5), base::TimeDelta::FromSeconds(3)); } @@ -83,8 +80,8 @@ base::Closure start_fade_; base::TimeDelta delay_; - bool is_animating_; bool did_request_redraw_; + bool did_request_animate_; }; // Check initialization of scrollbar.
diff --git a/cc/blink/web_scrollbar_layer_impl.cc b/cc/blink/web_scrollbar_layer_impl.cc index a6813cb..8248149 100644 --- a/cc/blink/web_scrollbar_layer_impl.cc +++ b/cc/blink/web_scrollbar_layer_impl.cc
@@ -67,11 +67,4 @@ scroll_layer ? scroll_layer->id() : cc::Layer::INVALID_ID); } -void WebScrollbarLayerImpl::setClipLayer(blink::WebLayer* layer) { - cc::Layer* clip_layer = - layer ? static_cast<WebLayerImpl*>(layer)->layer() : 0; - layer_->layer()->ToScrollbarLayer()->SetClipLayer( - clip_layer ? clip_layer->id() : cc::Layer::INVALID_ID); -} - } // namespace cc_blink
diff --git a/cc/blink/web_scrollbar_layer_impl.h b/cc/blink/web_scrollbar_layer_impl.h index d4963d9..734e069 100644 --- a/cc/blink/web_scrollbar_layer_impl.h +++ b/cc/blink/web_scrollbar_layer_impl.h
@@ -35,7 +35,6 @@ // blink::WebScrollbarLayer implementation. blink::WebLayer* layer() override; void setScrollLayer(blink::WebLayer* layer) override; - void setClipLayer(blink::WebLayer* layer) override; private: scoped_ptr<WebLayerImpl> layer_;
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index afacef8..e71bc79 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -10,7 +10,6 @@ #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "cc/animation/animation_registrar.h" -#include "cc/animation/scrollbar_animation_controller.h" #include "cc/base/math_util.h" #include "cc/base/simple_enclosed_region.h" #include "cc/debug/debug_colors.h" @@ -18,8 +17,8 @@ #include "cc/debug/micro_benchmark_impl.h" #include "cc/debug/traced_value.h" #include "cc/input/scroll_state.h" +#include "cc/layers/layer.h" #include "cc/layers/layer_utils.h" -#include "cc/layers/painted_scrollbar_layer_impl.h" #include "cc/output/copy_output_request.h" #include "cc/quads/debug_border_draw_quad.h" #include "cc/quads/render_pass.h" @@ -50,7 +49,7 @@ layer_id_(id), layer_tree_impl_(tree_impl), scroll_offset_(scroll_offset), - scroll_clip_layer_(nullptr), + scroll_clip_layer_id_(Layer::INVALID_ID), should_scroll_on_main_thread_(false), have_wheel_event_handlers_(false), have_scroll_event_handlers_(false), @@ -118,6 +117,7 @@ if (!copy_requests_.empty() && layer_tree_impl_->IsActiveTree()) layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this); + layer_tree_impl_->UnregisterScrollLayer(this); layer_tree_impl_->UnregisterLayer(this); TRACE_EVENT_OBJECT_DELETED_WITH_ID( @@ -459,7 +459,20 @@ } void LayerImpl::SetScrollClipLayer(int scroll_clip_layer_id) { - scroll_clip_layer_ = layer_tree_impl()->LayerById(scroll_clip_layer_id); + if (scroll_clip_layer_id_ == scroll_clip_layer_id) + return; + + layer_tree_impl()->UnregisterScrollLayer(this); + scroll_clip_layer_id_ = scroll_clip_layer_id; + layer_tree_impl()->RegisterScrollLayer(this); +} + +LayerImpl* LayerImpl::scroll_clip_layer() const { + return layer_tree_impl()->LayerById(scroll_clip_layer_id_); +} + +bool LayerImpl::scrollable() const { + return scroll_clip_layer_id_ != Layer::INVALID_ID; } bool LayerImpl::user_scrollable(ScrollbarOrientation orientation) const { @@ -575,8 +588,7 @@ layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_); layer->SetTransformAndInvertibility(transform_, transform_is_invertible_); - layer->SetScrollClipLayer(scroll_clip_layer_ ? scroll_clip_layer_->id() - : Layer::INVALID_ID); + layer->SetScrollClipLayer(scroll_clip_layer_id_); layer->set_user_scrollable_horizontal(user_scrollable_horizontal_); layer->set_user_scrollable_vertical(user_scrollable_vertical_); @@ -661,15 +673,12 @@ } gfx::Vector2dF LayerImpl::FixedContainerSizeDelta() const { - if (!scroll_clip_layer_) + LayerImpl* scroll_clip_layer = + layer_tree_impl()->LayerById(scroll_clip_layer_id_); + if (!scroll_clip_layer) return gfx::Vector2dF(); - gfx::Vector2dF delta_from_scroll = scroll_clip_layer_->bounds_delta(); - - // In virtual-viewport mode, we don't need to compensate for pinch zoom or - // scale since the fixed container is the outer viewport, which sits below - // the page scale. - return delta_from_scroll; + return scroll_clip_layer->bounds_delta(); } base::DictionaryValue* LayerImpl::LayerTreeAsJson() const { @@ -874,6 +883,8 @@ void LayerImpl::UpdatePropertyTreeOpacity() { if (effect_tree_index_ != -1) { EffectTree& effect_tree = layer_tree_impl()->property_trees()->effect_tree; + if (effect_tree_index_ >= static_cast<int>(effect_tree.size())) + return; EffectNode* node = effect_tree.Node(effect_tree_index_); // A LayerImpl's own current state is insufficient for determining whether // it owns an OpacityNode, since this depends on the state of the @@ -958,7 +969,7 @@ bounds_ = bounds; - ScrollbarParametersDidChange(true); + layer_tree_impl()->DidUpdateScrollState(id()); if (masks_to_bounds()) NoteLayerPropertyChangedForSubtree(); else @@ -979,7 +990,7 @@ else if (this == layer_tree_impl()->OuterViewportContainerLayer()) transform_tree.SetOuterViewportBoundsDelta(bounds_delta); - ScrollbarParametersDidChange(true); + layer_tree_impl()->DidUpdateScrollState(id()); if (masks_to_bounds()) { // If layer is clipping, then update the clip node using the new bounds. @@ -1479,8 +1490,8 @@ void LayerImpl::DidUpdateScrollOffset() { DCHECK(scroll_offset_); + layer_tree_impl()->DidUpdateScrollState(id()); NoteLayerPropertyChangedForSubtree(); - ScrollbarParametersDidChange(false); UpdatePropertyTreeScrollOffset(); @@ -1514,7 +1525,9 @@ } gfx::ScrollOffset LayerImpl::MaxScrollOffset() const { - if (!scroll_clip_layer_ || bounds().IsEmpty()) + LayerImpl* scroll_clip_layer = + layer_tree_impl()->LayerById(scroll_clip_layer_id_); + if (!scroll_clip_layer || bounds().IsEmpty()) return gfx::ScrollOffset(); LayerImpl const* page_scale_layer = layer_tree_impl()->PageScaleLayer(); @@ -1524,7 +1537,7 @@ float scale_factor = 1.f; for (LayerImpl const* current_layer = this; - current_layer != scroll_clip_layer_->parent(); + current_layer != scroll_clip_layer->parent(); current_layer = current_layer->parent()) { if (current_layer == page_scale_layer) scale_factor = layer_tree_impl()->current_page_scale_factor(); @@ -1536,8 +1549,8 @@ std::floor(scaled_scroll_bounds.height())); gfx::ScrollOffset max_offset( - scaled_scroll_bounds.width() - scroll_clip_layer_->bounds().width(), - scaled_scroll_bounds.height() - scroll_clip_layer_->bounds().height()); + scaled_scroll_bounds.width() - scroll_clip_layer->bounds().width(), + scaled_scroll_bounds.height() - scroll_clip_layer->bounds().height()); // We need the final scroll offset to be in CSS coords. max_offset.Scale(1 / scale_factor); max_offset.SetToMax(gfx::ScrollOffset()); @@ -1560,147 +1573,6 @@ return delta; } -void LayerImpl::SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer, - LayerImpl* scrollbar_clip_layer, - bool on_resize) const { - DCHECK(scrollbar_layer); - LayerImpl* page_scale_layer = layer_tree_impl()->PageScaleLayer(); - - DCHECK(this != page_scale_layer); - DCHECK(scrollbar_clip_layer); - gfx::RectF clip_rect(gfx::PointF(), - scrollbar_clip_layer->BoundsForScrolling()); - - // See comment in MaxScrollOffset() regarding the use of the content layer - // bounds here. - gfx::RectF scroll_rect(gfx::PointF(), BoundsForScrolling()); - - if (scroll_rect.size().IsEmpty()) - return; - - gfx::ScrollOffset current_offset; - for (LayerImpl const* current_layer = this; - current_layer != scrollbar_clip_layer->parent(); - current_layer = current_layer->parent()) { - current_offset += current_layer->CurrentScrollOffset(); - if (current_layer == page_scale_layer) { - float scale_factor = layer_tree_impl()->current_page_scale_factor(); - current_offset.Scale(scale_factor); - scroll_rect.Scale(scale_factor); - } - } - - bool scrollbar_needs_animation = false; - scrollbar_needs_animation |= scrollbar_layer->SetVerticalAdjust( - scrollbar_clip_layer->bounds_delta().y()); - if (scrollbar_layer->orientation() == HORIZONTAL) { - float visible_ratio = clip_rect.width() / scroll_rect.width(); - scrollbar_needs_animation |= - scrollbar_layer->SetCurrentPos(current_offset.x()); - scrollbar_needs_animation |= - scrollbar_layer->SetMaximum(scroll_rect.width() - clip_rect.width()); - scrollbar_needs_animation |= - scrollbar_layer->SetVisibleToTotalLengthRatio(visible_ratio); - } else { - float visible_ratio = clip_rect.height() / scroll_rect.height(); - bool y_offset_did_change = - scrollbar_layer->SetCurrentPos(current_offset.y()); - scrollbar_needs_animation |= y_offset_did_change; - scrollbar_needs_animation |= - scrollbar_layer->SetMaximum(scroll_rect.height() - clip_rect.height()); - scrollbar_needs_animation |= - scrollbar_layer->SetVisibleToTotalLengthRatio(visible_ratio); - if (y_offset_did_change && layer_tree_impl()->IsActiveTree() && - this == layer_tree_impl()->OuterViewportScrollLayer()) { - TRACE_COUNTER_ID1("cc", "scroll_offset_y", this->id(), - current_offset.y()); - } - } - if (scrollbar_needs_animation) { - layer_tree_impl()->set_needs_update_draw_properties(); - // TODO(wjmaclean) The scrollbar animator for the pinch-zoom scrollbars - // should activate for every scroll on the main frame, not just the - // scrolls that move the pinch virtual viewport (i.e. trigger from - // either inner or outer viewport). - if (scrollbar_animation_controller_) { - // Non-overlay scrollbars shouldn't trigger animations. - if (scrollbar_layer->is_overlay_scrollbar()) - scrollbar_animation_controller_->DidScrollUpdate(on_resize); - } - } -} - -void LayerImpl::DidBecomeActive() { - if (layer_tree_impl_->settings().scrollbar_animator == - LayerTreeSettings::NO_ANIMATOR) { - return; - } - - bool need_scrollbar_animation_controller = scrollable() && scrollbars_; - if (!need_scrollbar_animation_controller) { - scrollbar_animation_controller_ = nullptr; - return; - } - - if (scrollbar_animation_controller_) - return; - - scrollbar_animation_controller_ = - layer_tree_impl_->CreateScrollbarAnimationController(this); -} - -void LayerImpl::ClearScrollbars() { - if (!scrollbars_) - return; - - scrollbars_.reset(nullptr); -} - -void LayerImpl::AddScrollbar(ScrollbarLayerImplBase* layer) { - DCHECK(layer); - DCHECK(!scrollbars_ || scrollbars_->find(layer) == scrollbars_->end()); - if (!scrollbars_) - scrollbars_.reset(new ScrollbarSet()); - - scrollbars_->insert(layer); -} - -void LayerImpl::RemoveScrollbar(ScrollbarLayerImplBase* layer) { - DCHECK(scrollbars_); - DCHECK(layer); - DCHECK(scrollbars_->find(layer) != scrollbars_->end()); - - scrollbars_->erase(layer); - if (scrollbars_->empty()) - scrollbars_ = nullptr; -} - -bool LayerImpl::HasScrollbar(ScrollbarOrientation orientation) const { - if (!scrollbars_) - return false; - - for (ScrollbarSet::iterator it = scrollbars_->begin(); - it != scrollbars_->end(); - ++it) - if ((*it)->orientation() == orientation) - return true; - - return false; -} - -void LayerImpl::ScrollbarParametersDidChange(bool on_resize) { - if (!scrollbars_) - return; - - for (ScrollbarSet::iterator it = scrollbars_->begin(); - it != scrollbars_->end(); - ++it) { - bool is_scroll_layer = (*it)->ScrollLayerId() == layer_id_; - bool scroll_layer_resized = is_scroll_layer && on_resize; - (*it)->ScrollbarParametersDidChange(scroll_layer_resized); - } -} - void LayerImpl::SetNeedsPushProperties() { if (needs_push_properties_) return;
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 4e949809..543691fb 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h
@@ -23,7 +23,6 @@ #include "cc/base/synced_property.h" #include "cc/debug/frame_timing_request.h" #include "cc/input/input_handler.h" -#include "cc/input/scrollbar.h" #include "cc/layers/draw_properties.h" #include "cc/layers/layer_lists.h" #include "cc/layers/layer_position_constraint.h" @@ -62,7 +61,6 @@ class RenderPass; class RenderPassId; class Renderer; -class ScrollbarAnimationController; class ScrollbarLayerImplBase; class SimpleEnclosedRegion; class Tile; @@ -451,9 +449,6 @@ gfx::ScrollOffset MaxScrollOffset() const; gfx::ScrollOffset ClampScrollOffsetToLimits(gfx::ScrollOffset offset) const; gfx::Vector2dF ClampScrollToMaxScrollOffset(); - void SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer, - LayerImpl* scrollbar_clip_layer, - bool on_resize) const; void SetScrollCompensationAdjustment(const gfx::Vector2dF& scroll_offset) { scroll_compensation_adjustment_ = scroll_offset; } @@ -466,8 +461,9 @@ gfx::Vector2dF ScrollBy(const gfx::Vector2dF& scroll); void SetScrollClipLayer(int scroll_clip_layer_id); - LayerImpl* scroll_clip_layer() const { return scroll_clip_layer_; } - bool scrollable() const { return !!scroll_clip_layer_; } + int scroll_clip_layer_id() const { return scroll_clip_layer_id_; } + LayerImpl* scroll_clip_layer() const; + bool scrollable() const; void set_user_scrollable_horizontal(bool scrollable) { user_scrollable_horizontal_ = scrollable; @@ -582,7 +578,7 @@ virtual SimpleEnclosedRegion VisibleOpaqueRegion() const; - virtual void DidBecomeActive(); + virtual void DidBecomeActive() {} virtual void DidBeginTracing(); @@ -594,19 +590,8 @@ // ReleaseResources call. virtual void RecreateResources(); - ScrollbarAnimationController* scrollbar_animation_controller() const { - return scrollbar_animation_controller_.get(); - } - - typedef std::set<ScrollbarLayerImplBase*> ScrollbarSet; - ScrollbarSet* scrollbars() { return scrollbars_.get(); } - void ClearScrollbars(); - void AddScrollbar(ScrollbarLayerImplBase* layer); - void RemoveScrollbar(ScrollbarLayerImplBase* layer); - bool HasScrollbar(ScrollbarOrientation orientation) const; - void ScrollbarParametersDidChange(bool on_resize); int clip_height() { - return scroll_clip_layer_ ? scroll_clip_layer_->bounds().height() : 0; + return scroll_clip_layer() ? scroll_clip_layer()->bounds().height() : 0; } virtual skia::RefPtr<SkPicture> GetPicture(); @@ -763,7 +748,7 @@ // Properties synchronized from the associated Layer. gfx::Point3F transform_origin_; gfx::Size bounds_; - LayerImpl* scroll_clip_layer_; + int scroll_clip_layer_id_; gfx::Vector2dF offset_to_transform_parent_; @@ -863,11 +848,6 @@ // Manages animations for this layer. scoped_refptr<LayerAnimationController> layer_animation_controller_; - // Manages scrollbars for this layer - scoped_ptr<ScrollbarAnimationController> scrollbar_animation_controller_; - - scoped_ptr<ScrollbarSet> scrollbars_; - ScopedPtrVector<CopyOutputRequest> copy_requests_; // Group of properties that need to be computed based on the layer tree
diff --git a/cc/layers/layer_impl_unittest.cc b/cc/layers/layer_impl_unittest.cc index 315544ad..7089bbe 100644 --- a/cc/layers/layer_impl_unittest.cc +++ b/cc/layers/layer_impl_unittest.cc
@@ -578,159 +578,5 @@ pending_layer->CurrentScrollOffset()); } -TEST_F(LayerImplScrollTest, SetNewScrollbarParameters) { - gfx::ScrollOffset scroll_offset(10, 5); - layer()->PushScrollOffsetFromMainThread(scroll_offset); - - scoped_ptr<PaintedScrollbarLayerImpl> vertical_scrollbar( - PaintedScrollbarLayerImpl::Create(tree(), 100, VERTICAL)); - vertical_scrollbar->SetScrollLayerAndClipLayerByIds( - layer()->id(), tree()->root_layer()->id()); - - int expected_vertical_maximum = - layer()->bounds().height() - tree()->root_layer()->bounds().height(); - EXPECT_EQ(expected_vertical_maximum, vertical_scrollbar->maximum()); - EXPECT_EQ(scroll_offset.y(), vertical_scrollbar->current_pos()); - - scoped_ptr<PaintedScrollbarLayerImpl> horizontal_scrollbar( - PaintedScrollbarLayerImpl::Create(tree(), 101, HORIZONTAL)); - horizontal_scrollbar->SetScrollLayerAndClipLayerByIds( - layer()->id(), tree()->root_layer()->id()); - - int expected_horizontal_maximum = - layer()->bounds().width() - tree()->root_layer()->bounds().width(); - EXPECT_EQ(expected_horizontal_maximum, horizontal_scrollbar->maximum()); - EXPECT_EQ(scroll_offset.x(), horizontal_scrollbar->current_pos()); -} - -class LayerImplScrollbarSyncTest : public testing::Test { - public: - enum { - ROOT = 1, - IV_CLIP = 2, - PAGE = 3, - IV_SCROLL = 4, - SCROLLBAR = 5, - OLD_ROOT = 6, - OV_CLIP = 7, - OV_SCROLL = 8, - }; - enum TreeID { - PENDING, - ACTIVE - }; - - LayerImplScrollbarSyncTest() - : host_impl_(settings(), - &proxy_, - &shared_bitmap_manager_, - &task_graph_runner_) { - host_impl_.CreatePendingTree(); - - CreateLayers(host_impl_.pending_tree()); - CreateLayers(host_impl_.active_tree()); - } - - void CreateLayers(LayerTreeImpl * tree) { - tree->SetRootLayer(LayerImpl::Create(tree, ROOT)); - LayerImpl * root = tree->root_layer(); - ASSERT_TRUE(root != nullptr); - - int hierarchy[] = {IV_CLIP, PAGE, IV_SCROLL, OLD_ROOT, OV_CLIP, OV_SCROLL}; - LayerImpl * parent = root; - for (int child_id : hierarchy) { - parent->AddChild(LayerImpl::Create(tree, child_id)); - parent = tree->LayerById(child_id); - ASSERT_TRUE(parent != nullptr); - } - - root->AddChild( - SolidColorScrollbarLayerImpl::Create(tree, SCROLLBAR, HORIZONTAL, - 5, 5, false, true)); - } - - LayerImpl* layer(int id, TreeID tree_id) { - LayerTreeImpl* tree = - ((tree_id == PENDING) ? - host_impl_.pending_tree() : host_impl_.active_tree()); - - assert(tree); - return tree->LayerById(id); - } - - bool LayerHasScrollbar(int id, TreeID tree_id) { - return layer(id, tree_id)->HasScrollbar(HORIZONTAL); - } - - ScrollbarLayerImplBase* pending_scrollbar() { - LayerImpl* layer_impl = layer(SCROLLBAR, PENDING); - assert(layer_impl); - return layer_impl->ToScrollbarLayer(); - } - - LayerImpl* pending_root() { - LayerImpl * result = layer(ROOT, PENDING); - assert(result); - return result; - } - - LayerImpl* active_root() { - LayerImpl * result = layer(ROOT, ACTIVE); - assert(result); - return result; - } - - LayerTreeSettings settings() { - LayerTreeSettings settings; - return settings; - } - - private: - FakeImplProxy proxy_; - TestSharedBitmapManager shared_bitmap_manager_; - TestTaskGraphRunner task_graph_runner_; - FakeLayerTreeHostImpl host_impl_; -}; - -TEST_F(LayerImplScrollbarSyncTest, LayerImplBecomesScrollable) { - // In the beginning IV_SCROLL layer is not scrollable. - ASSERT_FALSE(layer(IV_SCROLL, PENDING)->scrollable()); - - // For pinch virtual viewport the clip layer is the inner viewport - // clip layer (IV_CLIP) and the scroll one is the outer viewport - // scroll layer (OV_SCROLL). - pending_scrollbar()->SetScrollLayerAndClipLayerByIds(OV_SCROLL, IV_CLIP); - - ASSERT_TRUE(LayerHasScrollbar(OV_SCROLL, PENDING)); - ASSERT_TRUE(LayerHasScrollbar(IV_CLIP, PENDING)); - - // Synchronize with the active tree. - TreeSynchronizer::PushProperties(pending_root(), active_root()); - - ASSERT_TRUE(LayerHasScrollbar(OV_SCROLL, ACTIVE)); - ASSERT_TRUE(LayerHasScrollbar(IV_CLIP, ACTIVE)); - - // Make IV_SCROLL layer scrollable. - layer(IV_SCROLL, PENDING)->SetScrollClipLayer(IV_CLIP); - layer(IV_SCROLL, PENDING)->SetNeedsPushProperties(); - ASSERT_TRUE(layer(IV_SCROLL, PENDING)->scrollable()); - - pending_scrollbar()->SetScrollLayerAndClipLayerByIds(OV_SCROLL, IV_CLIP); - - // Now IV_CLIP layer should also receive the scrollbar. - ASSERT_TRUE(LayerHasScrollbar(OV_SCROLL, PENDING)); - ASSERT_TRUE(LayerHasScrollbar(IV_CLIP, PENDING)); - ASSERT_TRUE(LayerHasScrollbar(IV_SCROLL, PENDING)); - - // Synchronize with the active tree. - TreeSynchronizer::PushProperties(pending_root(), active_root()); - - ASSERT_TRUE(layer(IV_SCROLL, ACTIVE)->scrollable()); - - ASSERT_TRUE(LayerHasScrollbar(OV_SCROLL, ACTIVE)); - ASSERT_TRUE(LayerHasScrollbar(IV_CLIP, ACTIVE)); - ASSERT_TRUE(LayerHasScrollbar(IV_SCROLL, ACTIVE)); -} - } // namespace } // namespace cc
diff --git a/cc/layers/painted_scrollbar_layer.cc b/cc/layers/painted_scrollbar_layer.cc index 67f83c65..7a65992 100644 --- a/cc/layers/painted_scrollbar_layer.cc +++ b/cc/layers/painted_scrollbar_layer.cc
@@ -45,7 +45,6 @@ : Layer(settings), scrollbar_(scrollbar.Pass()), scroll_layer_id_(scroll_layer_id), - clip_layer_id_(Layer::INVALID_ID), internal_contents_scale_(1.f), thumb_thickness_(scrollbar_->ThumbThickness()), thumb_length_(scrollbar_->ThumbLength()), @@ -69,14 +68,6 @@ SetNeedsFullTreeSync(); } -void PaintedScrollbarLayer::SetClipLayer(int layer_id) { - if (layer_id == clip_layer_id_) - return; - - clip_layer_id_ = layer_id; - SetNeedsFullTreeSync(); -} - bool PaintedScrollbarLayer::OpacityCanAnimateOnImplThread() const { return scrollbar_->IsOverlay(); } @@ -108,11 +99,10 @@ void PaintedScrollbarLayer::PushPropertiesTo(LayerImpl* layer) { Layer::PushPropertiesTo(layer); - PushScrollClipPropertiesTo(layer); - PaintedScrollbarLayerImpl* scrollbar_layer = static_cast<PaintedScrollbarLayerImpl*>(layer); + scrollbar_layer->SetScrollLayerId(scroll_layer_id_); scrollbar_layer->set_internal_contents_scale_and_bounds( internal_contents_scale_, internal_content_bounds_); @@ -144,14 +134,6 @@ return this; } -void PaintedScrollbarLayer::PushScrollClipPropertiesTo(LayerImpl* layer) { - PaintedScrollbarLayerImpl* scrollbar_layer = - static_cast<PaintedScrollbarLayerImpl*>(layer); - - scrollbar_layer->SetScrollLayerAndClipLayerByIds(scroll_layer_id_, - clip_layer_id_); -} - void PaintedScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) { // When the LTH is set to null or has changed, then this layer should remove // all of its associated resources.
diff --git a/cc/layers/painted_scrollbar_layer.h b/cc/layers/painted_scrollbar_layer.h index 3e376b1..b6170a64 100644 --- a/cc/layers/painted_scrollbar_layer.h +++ b/cc/layers/painted_scrollbar_layer.h
@@ -31,7 +31,6 @@ // ScrollbarLayerInterface int ScrollLayerId() const override; void SetScrollLayer(int layer_id) override; - void SetClipLayer(int layer_id) override; ScrollbarOrientation orientation() const override; @@ -39,7 +38,6 @@ bool Update() override; void SetLayerTreeHost(LayerTreeHost* host) override; void PushPropertiesTo(LayerImpl* layer) override; - void PushScrollClipPropertiesTo(LayerImpl* layer) override; const gfx::Size& internal_content_bounds() const { return internal_content_bounds_; @@ -83,7 +81,6 @@ scoped_ptr<Scrollbar> scrollbar_; int scroll_layer_id_; - int clip_layer_id_; float internal_contents_scale_; gfx::Size internal_content_bounds_;
diff --git a/cc/layers/painted_scrollbar_layer_impl_unittest.cc b/cc/layers/painted_scrollbar_layer_impl_unittest.cc index eac32b6..68f24af 100644 --- a/cc/layers/painted_scrollbar_layer_impl_unittest.cc +++ b/cc/layers/painted_scrollbar_layer_impl_unittest.cc
@@ -46,8 +46,8 @@ scrollbar_layer_impl->SetThumbLength(500); scrollbar_layer_impl->SetTrackLength(layer_size.height()); scrollbar_layer_impl->SetCurrentPos(100.f / 4); - scrollbar_layer_impl->SetMaximum(100); - scrollbar_layer_impl->SetVisibleToTotalLengthRatio(1.f / 2); + scrollbar_layer_impl->SetClipLayerLength(100.f); + scrollbar_layer_impl->SetScrollLayerLength(200.f); scrollbar_layer_impl->set_track_ui_resource_id(track_uid); scrollbar_layer_impl->set_thumb_ui_resource_id(thumb_uid);
diff --git a/cc/layers/scrollbar_layer_impl_base.cc b/cc/layers/scrollbar_layer_impl_base.cc index 6696e49..4e18b62 100644 --- a/cc/layers/scrollbar_layer_impl_base.cc +++ b/cc/layers/scrollbar_layer_impl_base.cc
@@ -17,19 +17,19 @@ bool is_left_side_vertical_scrollbar, bool is_overlay) : LayerImpl(tree_impl, id), - scroll_layer_(nullptr), - clip_layer_(nullptr), + scroll_layer_id_(Layer::INVALID_ID), is_overlay_scrollbar_(is_overlay), thumb_thickness_scale_factor_(1.f), current_pos_(0.f), - maximum_(0), + clip_layer_length_(0.f), + scroll_layer_length_(0.f), orientation_(orientation), is_left_side_vertical_scrollbar_(is_left_side_vertical_scrollbar), - vertical_adjust_(0.f), - visible_to_total_length_ratio_(1.f) { -} + vertical_adjust_(0.f) {} -ScrollbarLayerImplBase::~ScrollbarLayerImplBase() {} +ScrollbarLayerImplBase::~ScrollbarLayerImplBase() { + layer_tree_impl()->UnregisterScrollbar(this); +} void ScrollbarLayerImplBase::PushPropertiesTo(LayerImpl* layer) { float active_opacity = layer->opacity(); @@ -39,7 +39,7 @@ layer->SetHideLayerAndSubtree(active_hidden); DCHECK(layer->ToScrollbarLayer()); layer->ToScrollbarLayer()->set_is_overlay_scrollbar(is_overlay_scrollbar_); - PushScrollClipPropertiesTo(layer); + layer->ToScrollbarLayer()->SetScrollLayerId(ScrollLayerId()); } void ScrollbarLayerImplBase::DidBecomeActive() { @@ -47,56 +47,19 @@ UpdatePropertyTreeOpacity(); } -void ScrollbarLayerImplBase::PushScrollClipPropertiesTo(LayerImpl* layer) { - DCHECK(layer->ToScrollbarLayer()); - layer->ToScrollbarLayer()->SetScrollLayerAndClipLayerByIds(ScrollLayerId(), - ClipLayerId()); -} - ScrollbarLayerImplBase* ScrollbarLayerImplBase::ToScrollbarLayer() { return this; } -namespace { - -typedef void (LayerImpl::*ScrollbarRegistrationOperation)( - ScrollbarLayerImplBase*); - -void RegisterScrollbarWithLayers(ScrollbarLayerImplBase* scrollbar, - LayerImpl* container_layer, - LayerImpl* scroll_layer, - ScrollbarRegistrationOperation operation) { - if (!container_layer || !scroll_layer) +void ScrollbarLayerImplBase::SetScrollLayerId(int scroll_layer_id) { + if (scroll_layer_id_ == scroll_layer_id) return; - DCHECK(scrollbar); + layer_tree_impl()->UnregisterScrollbar(this); - // Scrollbars must be notifed of changes to their scroll and container layers - // and all scrollable layers in between. - for (LayerImpl* current_layer = scroll_layer; - current_layer && current_layer != container_layer->parent(); - current_layer = current_layer->parent()) { - (current_layer->*operation)(scrollbar); - } -} -} // namespace + scroll_layer_id_ = scroll_layer_id; -void ScrollbarLayerImplBase::SetScrollLayerAndClipLayerByIds( - int scroll_layer_id, - int clip_layer_id) { - LayerImpl* scroll_layer = layer_tree_impl()->LayerById(scroll_layer_id); - LayerImpl* clip_layer = layer_tree_impl()->LayerById(clip_layer_id); - if (scroll_layer_ == scroll_layer && clip_layer_ == clip_layer) - return; - - RegisterScrollbarWithLayers( - this, clip_layer_, scroll_layer_, &LayerImpl::RemoveScrollbar); - scroll_layer_ = scroll_layer; - clip_layer_ = clip_layer; - RegisterScrollbarWithLayers( - this, clip_layer_, scroll_layer_, &LayerImpl::AddScrollbar); - - ScrollbarParametersDidChange(false); + layer_tree_impl()->RegisterScrollbar(this); } bool ScrollbarLayerImplBase::SetCurrentPos(float current_pos) { @@ -107,18 +70,12 @@ return true; } -bool ScrollbarLayerImplBase::SetMaximum(int maximum) { - if (maximum_ == maximum) - return false; - maximum_ = maximum; - NoteLayerPropertyChanged(); - return true; -} - bool ScrollbarLayerImplBase::CanScrollOrientation() const { - if (!scroll_layer_) + LayerImpl* scroll_layer = layer_tree_impl()->LayerById(scroll_layer_id_); + if (!scroll_layer) return false; - return scroll_layer_->user_scrollable(orientation()) && (0 < maximum()); + return scroll_layer->user_scrollable(orientation()) && + clip_layer_length_ < scroll_layer_length_; } bool ScrollbarLayerImplBase::SetVerticalAdjust(float vertical_adjust) { @@ -129,13 +86,18 @@ return true; } -bool ScrollbarLayerImplBase::SetVisibleToTotalLengthRatio(float ratio) { - if (!IsThumbResizable()) +bool ScrollbarLayerImplBase::SetClipLayerLength(float clip_layer_length) { + if (clip_layer_length_ == clip_layer_length) return false; + clip_layer_length_ = clip_layer_length; + NoteLayerPropertyChanged(); + return true; +} - if (visible_to_total_length_ratio_ == ratio) +bool ScrollbarLayerImplBase::SetScrollLayerLength(float scroll_layer_length) { + if (scroll_layer_length_ == scroll_layer_length) return false; - visible_to_total_length_ratio_ = ratio; + scroll_layer_length_ = scroll_layer_length; NoteLayerPropertyChanged(); return true; } @@ -213,14 +175,14 @@ float track_length = TrackLength(); int thumb_length = ThumbLength(); int thumb_thickness = ThumbThickness(); + float maximum = scroll_layer_length_ - clip_layer_length_; // With the length known, we can compute the thumb's position. - float clamped_current_pos = - std::min(std::max(current_pos_, 0.f), static_cast<float>(maximum_)); + float clamped_current_pos = std::min(std::max(current_pos_, 0.f), maximum); int thumb_offset = TrackStart(); - if (maximum_ > 0) { - float ratio = clamped_current_pos / maximum_; + if (maximum > 0) { + float ratio = clamped_current_pos / maximum; float max_offset = track_length - thumb_length; thumb_offset += static_cast<int>(ratio * max_offset); } @@ -247,11 +209,4 @@ return gfx::ToEnclosingRect(thumb_rect); } -void ScrollbarLayerImplBase::ScrollbarParametersDidChange(bool on_resize) { - if (!clip_layer_ || !scroll_layer_) - return; - - scroll_layer_->SetScrollbarPosition(this, clip_layer_, on_resize); -} - } // namespace cc
diff --git a/cc/layers/scrollbar_layer_impl_base.h b/cc/layers/scrollbar_layer_impl_base.h index 339dcc9f..ebe508b 100644 --- a/cc/layers/scrollbar_layer_impl_base.h +++ b/cc/layers/scrollbar_layer_impl_base.h
@@ -16,24 +16,20 @@ class CC_EXPORT ScrollbarLayerImplBase : public LayerImpl { public: - int ScrollLayerId() const { - return scroll_layer_ ? scroll_layer_->id() : Layer::INVALID_ID; - } - int ClipLayerId() const { - return clip_layer_ ? clip_layer_->id() : Layer::INVALID_ID; - } + int ScrollLayerId() const { return scroll_layer_id_; } - void SetScrollLayerAndClipLayerByIds(int scroll_layer_id, int clip_layer_id); - void ClearScrollLayer() { scroll_layer_ = nullptr; } - void ClearClipLayer() { clip_layer_ = nullptr; } + void SetScrollLayerId(int scroll_layer_id); float current_pos() const { return current_pos_; } bool SetCurrentPos(float current_pos); - int maximum() const { return maximum_; } - bool SetMaximum(int maximum); - + bool SetClipLayerLength(float clip_layer_length); + bool SetScrollLayerLength(float scroll_layer_length); bool SetVerticalAdjust(float vertical_adjust); + float clip_layer_length() const { return clip_layer_length_; } + float scroll_layer_length() const { return scroll_layer_length_; } + float vertical_adjust() const { return vertical_adjust_; } + bool is_overlay_scrollbar() const { return is_overlay_scrollbar_; } void set_is_overlay_scrollbar(bool is_overlay) { is_overlay_scrollbar_ = is_overlay; @@ -49,9 +45,7 @@ void PushPropertiesTo(LayerImpl* layer) override; void DidBecomeActive() override; ScrollbarLayerImplBase* ToScrollbarLayer() override; - void PushScrollClipPropertiesTo(LayerImpl* layer); - bool SetVisibleToTotalLengthRatio(float ratio); // Thumb quad rect in layer space. virtual gfx::Rect ComputeThumbQuadRect() const; @@ -60,8 +54,6 @@ } bool SetThumbThicknessScaleFactor(float thumb_thickness_scale_factor); - void ScrollbarParametersDidChange(bool on_resize); - protected: ScrollbarLayerImplBase(LayerTreeImpl* tree_impl, int id, @@ -70,11 +62,6 @@ bool is_overlay); ~ScrollbarLayerImplBase() override; - float visible_to_total_length_ratio() const { - return visible_to_total_length_ratio_; - } - float vertical_adjust() const { return vertical_adjust_; } - virtual int ThumbThickness() const = 0; virtual int ThumbLength() const = 0; virtual float TrackLength() const = 0; @@ -84,13 +71,13 @@ virtual bool IsThumbResizable() const = 0; private: - LayerImpl* scroll_layer_; - LayerImpl* clip_layer_; + int scroll_layer_id_; bool is_overlay_scrollbar_; float thumb_thickness_scale_factor_; float current_pos_; - int maximum_; + float clip_layer_length_; + float scroll_layer_length_; ScrollbarOrientation orientation_; bool is_left_side_vertical_scrollbar_; @@ -98,11 +85,11 @@ // height (which may differ in the presence of top-controls hiding). float vertical_adjust_; - float visible_to_total_length_ratio_; - DISALLOW_COPY_AND_ASSIGN(ScrollbarLayerImplBase); }; +typedef std::set<ScrollbarLayerImplBase*> ScrollbarSet; + } // namespace cc #endif // CC_LAYERS_SCROLLBAR_LAYER_IMPL_BASE_H_
diff --git a/cc/layers/scrollbar_layer_interface.h b/cc/layers/scrollbar_layer_interface.h index e76fc27a..a396a5d 100644 --- a/cc/layers/scrollbar_layer_interface.h +++ b/cc/layers/scrollbar_layer_interface.h
@@ -17,8 +17,6 @@ public: virtual int ScrollLayerId() const = 0; virtual void SetScrollLayer(int layer_id) = 0; - virtual void SetClipLayer(int layer_id) = 0; - virtual void PushScrollClipPropertiesTo(LayerImpl* layer) = 0; virtual ScrollbarOrientation orientation() const = 0;
diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc index 2d92f60..eb857c2f 100644 --- a/cc/layers/scrollbar_layer_unittest.cc +++ b/cc/layers/scrollbar_layer_unittest.cc
@@ -53,7 +53,6 @@ child2 = PaintedScrollbarLayer::Create(settings, scrollbar.Pass(), child1->id()); } - child2->ToScrollbarLayer()->SetClipLayer(layer_tree_root->id()); layer_tree_root->AddChild(child1); layer_tree_root->InsertChild(child2, reverse_order ? 0 : 1); host->SetRootLayer(layer_tree_root); @@ -146,36 +145,6 @@ scoped_ptr<FakeResourceTrackingLayerTreeHost> layer_tree_host_; }; -TEST_F(ScrollbarLayerTest, ResolveScrollLayerPointer) { - scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar); - LayerImpl* layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar( - layer_settings(), layer_tree_host_.get(), scrollbar.Pass(), false, false, - 0, 0); - - LayerImpl* cc_child1 = layer_impl_tree_root->children()[0]; - PaintedScrollbarLayerImpl* cc_child2 = - static_cast<PaintedScrollbarLayerImpl*>( - layer_impl_tree_root->children()[1]); - - EXPECT_EQ(cc_child1->scrollbars()->size(), 1UL); - EXPECT_EQ(*(cc_child1->scrollbars()->begin()), cc_child2); -} - -TEST_F(ScrollbarLayerTest, ResolveScrollLayerPointer_ReverseOrder) { - scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar); - LayerImpl* layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar( - layer_settings(), layer_tree_host_.get(), scrollbar.Pass(), true, false, - 0, 0); - - PaintedScrollbarLayerImpl* cc_child1 = - static_cast<PaintedScrollbarLayerImpl*>( - layer_impl_tree_root->children()[0]); - LayerImpl* cc_child2 = layer_impl_tree_root->children()[1]; - - EXPECT_EQ(cc_child2->scrollbars()->size(), 1UL); - EXPECT_EQ(*(cc_child2->scrollbars()->begin()), cc_child1); -} - TEST_F(ScrollbarLayerTest, ShouldScrollNonOverlayOnMainThread) { // Create and attach a non-overlay scrollbar. scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar); @@ -231,7 +200,6 @@ scroll_layer->AddChild(content_layer); layer_tree_root->AddChild(scrollbar_layer); scrollbar_layer->ToScrollbarLayer()->SetScrollLayer(scroll_layer->id()); - scrollbar_layer->ToScrollbarLayer()->SetClipLayer(layer_tree_root->id()); layer_tree_root->SavePaintProperties(); content_layer->SavePaintProperties(); @@ -244,7 +212,8 @@ layer_impl_tree_root->children()[1]); EXPECT_EQ(10.f, cc_scrollbar_layer->current_pos()); - EXPECT_EQ(30, cc_scrollbar_layer->maximum()); + EXPECT_EQ(30, cc_scrollbar_layer->scroll_layer_length() - + cc_scrollbar_layer->clip_layer_length()); layer_tree_root->SetBounds(gfx::Size(700, 1500)); layer_tree_root->SavePaintProperties(); @@ -254,20 +223,18 @@ content_layer->SetBounds(gfx::Size(1000, 2000)); content_layer->SavePaintProperties(); - ScrollbarAnimationController* scrollbar_controller = - layer_impl_tree_root->scrollbar_animation_controller(); layer_impl_tree_root = layer_tree_host_->CommitAndCreateLayerImplTree(); - EXPECT_EQ(scrollbar_controller, - layer_impl_tree_root->scrollbar_animation_controller()); EXPECT_EQ(100.f, cc_scrollbar_layer->current_pos()); - EXPECT_EQ(300, cc_scrollbar_layer->maximum()); + EXPECT_EQ(300, cc_scrollbar_layer->scroll_layer_length() - + cc_scrollbar_layer->clip_layer_length()); LayerImpl* scroll_layer_impl = layer_impl_tree_root->children()[0]; scroll_layer_impl->ScrollBy(gfx::Vector2d(12, 34)); EXPECT_EQ(112.f, cc_scrollbar_layer->current_pos()); - EXPECT_EQ(300, cc_scrollbar_layer->maximum()); + EXPECT_EQ(300, cc_scrollbar_layer->scroll_layer_length() - + cc_scrollbar_layer->clip_layer_length()); } #define UPDATE_AND_EXTRACT_LAYER_POINTERS() \ @@ -278,7 +245,6 @@ root_layer_impl = root_clip_layer_impl->children()[0]; \ scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>( \ root_layer_impl->children()[1]); \ - scrollbar_layer_impl->ScrollbarParametersDidChange(false); \ } while (false) TEST_F(ScrollbarLayerTest, UpdatePropertiesOfScrollBarWhenThumbRemoved) { @@ -303,7 +269,6 @@ root_layer->SetScrollOffset(gfx::ScrollOffset(0, 0)); scrollbar_layer->SetBounds(gfx::Size(70, 10)); scrollbar_layer->SetScrollLayer(root_layer->id()); - scrollbar_layer->SetClipLayer(root_clip_layer->id()); scrollbar_layer->fake_scrollbar()->set_location(gfx::Point(20, 10)); scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(30, 10, 50, 10)); scrollbar_layer->fake_scrollbar()->set_thumb_thickness(10); @@ -345,7 +310,6 @@ root_layer->SetScrollOffset(gfx::ScrollOffset(0, 0)); scrollbar_layer->SetBounds(gfx::Size(70, 10)); scrollbar_layer->SetScrollLayer(root_layer->id()); - scrollbar_layer->SetClipLayer(root_clip_layer->id()); scrollbar_layer->fake_scrollbar()->set_location(gfx::Point(20, 10)); scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(30, 10, 50, 10)); scrollbar_layer->fake_scrollbar()->set_thumb_thickness(10); @@ -416,8 +380,8 @@ layer_impl_tree_root->children()[1]); scrollbar_layer_impl->SetBounds(gfx::Size(kTrackLength, kThumbThickness)); scrollbar_layer_impl->SetCurrentPos(10.f); - scrollbar_layer_impl->SetMaximum(100); - scrollbar_layer_impl->SetVisibleToTotalLengthRatio(0.4f); + scrollbar_layer_impl->SetClipLayerLength(200 / 3.f); + scrollbar_layer_impl->SetScrollLayerLength(100 + 200 / 3.f); // Thickness should be overridden to 3. { @@ -433,7 +397,8 @@ // For solid color scrollbars, position and size should reflect the // current viewport state. - scrollbar_layer_impl->SetVisibleToTotalLengthRatio(0.2f); + scrollbar_layer_impl->SetClipLayerLength(25.f); + scrollbar_layer_impl->SetScrollLayerLength(125.f); { scoped_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; @@ -447,7 +412,8 @@ // We shouldn't attempt div-by-zero when the maximum is zero. scrollbar_layer_impl->SetCurrentPos(0.f); - scrollbar_layer_impl->SetMaximum(0); + scrollbar_layer_impl->SetClipLayerLength(125.f); + scrollbar_layer_impl->SetScrollLayerLength(125.f); { scoped_ptr<RenderPass> render_pass = RenderPass::Create(); AppendQuadsData data; @@ -456,7 +422,7 @@ const QuadList& quads = render_pass->quad_list; ASSERT_EQ(1u, quads.size()); EXPECT_EQ(DrawQuad::SOLID_COLOR, quads.front()->material); - EXPECT_EQ(gfx::Rect(1, 0, 19, 3), quads.front()->rect); + EXPECT_EQ(gfx::Rect(1, 0, 98, 3), quads.front()->rect); } } @@ -478,7 +444,6 @@ layer_settings(), scrollbar->Orientation(), kThumbThickness, kTrackStart, kIsLeftSideVerticalScrollbar, child1->id()); child2->ToScrollbarLayer()->SetScrollLayer(scroll_layer->id()); - child2->ToScrollbarLayer()->SetClipLayer(layer_tree_root->id()); scroll_layer->AddChild(child1); scroll_layer->InsertChild(child2, 1); layer_tree_root->AddChild(scroll_layer); @@ -498,7 +463,6 @@ scrollbar_layer_impl->SetBounds(gfx::Size(kTrackLength, kThumbThickness)); scrollbar_layer_impl->SetCurrentPos(4.f); - scrollbar_layer_impl->SetMaximum(8); { scoped_ptr<RenderPass> render_pass = RenderPass::Create(); @@ -555,26 +519,27 @@ TEST_F(ScrollbarLayerSolidColorThumbTest, SolidColorThumbLength) { horizontal_scrollbar_layer_->SetCurrentPos(0); - horizontal_scrollbar_layer_->SetMaximum(10); // Simple case - one third of the scrollable area is visible, so the thumb // should be one third as long as the track. - horizontal_scrollbar_layer_->SetVisibleToTotalLengthRatio(0.33f); + horizontal_scrollbar_layer_->SetClipLayerLength(5.f); + horizontal_scrollbar_layer_->SetScrollLayerLength(15.f); horizontal_scrollbar_layer_->SetBounds(gfx::Size(100, 3)); EXPECT_EQ(33, horizontal_scrollbar_layer_->ComputeThumbQuadRect().width()); // The thumb's length should never be less than its thickness. - horizontal_scrollbar_layer_->SetVisibleToTotalLengthRatio(0.01f); + horizontal_scrollbar_layer_->SetClipLayerLength(0.01f); + horizontal_scrollbar_layer_->SetScrollLayerLength(15.f); horizontal_scrollbar_layer_->SetBounds(gfx::Size(100, 3)); EXPECT_EQ(3, horizontal_scrollbar_layer_->ComputeThumbQuadRect().width()); } TEST_F(ScrollbarLayerSolidColorThumbTest, SolidColorThumbPosition) { horizontal_scrollbar_layer_->SetBounds(gfx::Size(100, 3)); - horizontal_scrollbar_layer_->SetVisibleToTotalLengthRatio(0.1f); - horizontal_scrollbar_layer_->SetCurrentPos(0); - horizontal_scrollbar_layer_->SetMaximum(100); + horizontal_scrollbar_layer_->SetCurrentPos(0.f); + horizontal_scrollbar_layer_->SetClipLayerLength(12.f); + horizontal_scrollbar_layer_->SetScrollLayerLength(112.f); EXPECT_EQ(0, horizontal_scrollbar_layer_->ComputeThumbQuadRect().x()); EXPECT_EQ(10, horizontal_scrollbar_layer_->ComputeThumbQuadRect().width()); @@ -593,9 +558,9 @@ SolidColorScrollbarLayerImpl* layers[2] = { horizontal_scrollbar_layer_.get(), vertical_scrollbar_layer_.get() }; for (size_t i = 0; i < 2; ++i) { - layers[i]->SetVisibleToTotalLengthRatio(0.2f); - layers[i]->SetCurrentPos(25); - layers[i]->SetMaximum(100); + layers[i]->SetCurrentPos(25.f); + layers[i]->SetClipLayerLength(25.f); + layers[i]->SetScrollLayerLength(125.f); } layers[0]->SetBounds(gfx::Size(100, 3)); layers[1]->SetBounds(gfx::Size(3, 100));
diff --git a/cc/layers/solid_color_scrollbar_layer.cc b/cc/layers/solid_color_scrollbar_layer.cc index 4ed55ca..62a3180 100644 --- a/cc/layers/solid_color_scrollbar_layer.cc +++ b/cc/layers/solid_color_scrollbar_layer.cc
@@ -43,7 +43,6 @@ int scroll_layer_id) : Layer(settings), scroll_layer_id_(Layer::INVALID_ID), - clip_layer_id_(scroll_layer_id), orientation_(orientation), thumb_thickness_(thumb_thickness), track_start_(track_start), @@ -58,15 +57,10 @@ void SolidColorScrollbarLayer::PushPropertiesTo(LayerImpl* layer) { Layer::PushPropertiesTo(layer); - PushScrollClipPropertiesTo(layer); -} - -void SolidColorScrollbarLayer::PushScrollClipPropertiesTo(LayerImpl* layer) { SolidColorScrollbarLayerImpl* scrollbar_layer = static_cast<SolidColorScrollbarLayerImpl*>(layer); - scrollbar_layer->SetScrollLayerAndClipLayerByIds(scroll_layer_id_, - clip_layer_id_); + scrollbar_layer->SetScrollLayerId(scroll_layer_id_); } void SolidColorScrollbarLayer::SetNeedsDisplayRect(const gfx::Rect& rect) { @@ -89,14 +83,6 @@ SetNeedsFullTreeSync(); } -void SolidColorScrollbarLayer::SetClipLayer(int layer_id) { - if (layer_id == clip_layer_id_) - return; - - clip_layer_id_ = layer_id; - SetNeedsFullTreeSync(); -} - ScrollbarOrientation SolidColorScrollbarLayer::orientation() const { return orientation_; }
diff --git a/cc/layers/solid_color_scrollbar_layer.h b/cc/layers/solid_color_scrollbar_layer.h index 6097014..8b14bce 100644 --- a/cc/layers/solid_color_scrollbar_layer.h +++ b/cc/layers/solid_color_scrollbar_layer.h
@@ -29,14 +29,12 @@ ScrollbarLayerInterface* ToScrollbarLayer() override; void PushPropertiesTo(LayerImpl* layer) override; - void PushScrollClipPropertiesTo(LayerImpl* layer) override; void SetNeedsDisplayRect(const gfx::Rect& rect) override; // ScrollbarLayerInterface int ScrollLayerId() const override; void SetScrollLayer(int layer_id) override; - void SetClipLayer(int layer_id) override; ScrollbarOrientation orientation() const override; @@ -51,7 +49,6 @@ private: int scroll_layer_id_; - int clip_layer_id_; ScrollbarOrientation orientation_; int thumb_thickness_; int track_start_;
diff --git a/cc/layers/solid_color_scrollbar_layer_impl.cc b/cc/layers/solid_color_scrollbar_layer_impl.cc index beb9cb6..0b0a24e 100644 --- a/cc/layers/solid_color_scrollbar_layer_impl.cc +++ b/cc/layers/solid_color_scrollbar_layer_impl.cc
@@ -75,9 +75,11 @@ } int SolidColorScrollbarLayerImpl::ThumbLength() const { - return std::max( - static_cast<int>(visible_to_total_length_ratio() * TrackLength()), - ThumbThickness()); + float thumb_length = TrackLength(); + if (scroll_layer_length()) + thumb_length *= clip_layer_length() / scroll_layer_length(); + + return std::max(static_cast<int>(thumb_length), ThumbThickness()); } float SolidColorScrollbarLayerImpl::TrackLength() const {
diff --git a/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc b/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc index c758497..f141535 100644 --- a/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc +++ b/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc
@@ -31,9 +31,9 @@ is_overlay); scrollbar_layer_impl->SetBounds(layer_size); scrollbar_layer_impl->SetDrawsContent(true); - scrollbar_layer_impl->SetCurrentPos(100.f / 4); - scrollbar_layer_impl->SetMaximum(100); - scrollbar_layer_impl->SetVisibleToTotalLengthRatio(1.f / 2); + scrollbar_layer_impl->SetCurrentPos(25.f); + scrollbar_layer_impl->SetClipLayerLength(100.f); + scrollbar_layer_impl->SetScrollLayerLength(200.f); // SolidColorScrollbarLayers construct with opacity = 0.f, so override. scrollbar_layer_impl->SetOpacity(1.f);
diff --git a/cc/layers/viewport.cc b/cc/layers/viewport.cc index 80e711f..4b68de5 100644 --- a/cc/layers/viewport.cc +++ b/cc/layers/viewport.cc
@@ -50,17 +50,11 @@ ScrollResult result; - // TODO(bokan): This shouldn't be needed but removing it causes subtle - // viewport movement during top controls manipulation. - if (gfx::ToRoundedVector2d(pending_content_delta).IsZero()) { - result.consumed_delta = delta; - } else { - pending_content_delta -= host_impl_->ScrollLayer(OuterScrollLayer(), - pending_content_delta, - viewport_point, - is_direct_manipulation); - result.consumed_delta = delta - AdjustOverscroll(pending_content_delta); - } + pending_content_delta -= host_impl_->ScrollLayer(OuterScrollLayer(), + pending_content_delta, + viewport_point, + is_direct_manipulation); + result.consumed_delta = delta - AdjustOverscroll(pending_content_delta); result.content_scrolled_delta = content_delta - pending_content_delta; return result;
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 0f5abf2..85ceb2e 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -173,7 +173,7 @@ did_lock_scrolling_layer_(false), wheel_scrolling_(false), scroll_affects_scroll_handler_(false), - scroll_layer_id_when_mouse_over_scrollbar_(0), + scroll_layer_id_when_mouse_over_scrollbar_(Layer::INVALID_ID), tile_priorities_dirty_(false), settings_(settings), visible_(false), @@ -2753,9 +2753,6 @@ if (!layer_impl->scrollable() || layer_impl == OuterViewportScrollLayer()) continue; - if (!layer_impl->HasScrollbar(VERTICAL)) - continue; - float height = layer_impl->clip_height(); // These magical values match WebKit and are designed to scroll nearly the @@ -2835,66 +2832,56 @@ gfx::ScalePoint(viewport_point, active_tree_->device_scale_factor()); LayerImpl* layer_impl = active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); - if (HandleMouseOverScrollbar(layer_impl, device_viewport_point)) + HandleMouseOverScrollbar(layer_impl); + if (scroll_layer_id_when_mouse_over_scrollbar_ != Layer::INVALID_ID) return; - if (scroll_layer_id_when_mouse_over_scrollbar_) { - LayerImpl* scroll_layer_impl = active_tree_->LayerById( - scroll_layer_id_when_mouse_over_scrollbar_); - - // The check for a null scroll_layer_impl below was added to see if it will - // eliminate the crashes described in http://crbug.com/326635. - // TODO(wjmaclean) Add a unit test if this fixes the crashes. - ScrollbarAnimationController* animation_controller = - scroll_layer_impl ? scroll_layer_impl->scrollbar_animation_controller() - : NULL; - if (animation_controller) - animation_controller->DidMouseMoveOffScrollbar(); - scroll_layer_id_when_mouse_over_scrollbar_ = 0; - } - bool scroll_on_main_thread = false; LayerImpl* scroll_layer_impl = FindScrollLayerForDeviceViewportPoint( device_viewport_point, InputHandler::GESTURE, layer_impl, &scroll_on_main_thread, NULL); + if (scroll_layer_impl == InnerViewportScrollLayer()) + scroll_layer_impl = OuterViewportScrollLayer(); if (scroll_on_main_thread || !scroll_layer_impl) return; ScrollbarAnimationController* animation_controller = - scroll_layer_impl->scrollbar_animation_controller(); + ScrollbarAnimationControllerForId(scroll_layer_impl->id()); if (!animation_controller) return; - // TODO(wjmaclean) Is it ok to choose distance from more than two scrollbars? float distance_to_scrollbar = std::numeric_limits<float>::max(); - for (LayerImpl::ScrollbarSet::iterator it = - scroll_layer_impl->scrollbars()->begin(); - it != scroll_layer_impl->scrollbars()->end(); - ++it) + for (ScrollbarLayerImplBase* scrollbar : + ScrollbarsFor(scroll_layer_impl->id())) distance_to_scrollbar = std::min(distance_to_scrollbar, - DeviceSpaceDistanceToLayer(device_viewport_point, *it)); + DeviceSpaceDistanceToLayer(device_viewport_point, scrollbar)); animation_controller->DidMouseMoveNear(distance_to_scrollbar / active_tree_->device_scale_factor()); } -bool LayerTreeHostImpl::HandleMouseOverScrollbar(LayerImpl* layer_impl, - const gfx::PointF& device_viewport_point) { - if (layer_impl && layer_impl->ToScrollbarLayer()) { - int scroll_layer_id = layer_impl->ToScrollbarLayer()->ScrollLayerId(); - layer_impl = active_tree_->LayerById(scroll_layer_id); - if (layer_impl && layer_impl->scrollbar_animation_controller()) { - scroll_layer_id_when_mouse_over_scrollbar_ = scroll_layer_id; - layer_impl->scrollbar_animation_controller()->DidMouseMoveNear(0); - } else { - scroll_layer_id_when_mouse_over_scrollbar_ = 0; - } +void LayerTreeHostImpl::HandleMouseOverScrollbar(LayerImpl* layer_impl) { + int new_id = Layer::INVALID_ID; + if (layer_impl && layer_impl->ToScrollbarLayer()) + new_id = layer_impl->ToScrollbarLayer()->ScrollLayerId(); - return true; - } + if (new_id == scroll_layer_id_when_mouse_over_scrollbar_) + return; - return false; + ScrollbarAnimationController* old_animation_controller = + ScrollbarAnimationControllerForId( + scroll_layer_id_when_mouse_over_scrollbar_); + if (old_animation_controller) + old_animation_controller->DidMouseMoveOffScrollbar(); + + scroll_layer_id_when_mouse_over_scrollbar_ = new_id; + + ScrollbarAnimationController* new_animation_controller = + ScrollbarAnimationControllerForId( + scroll_layer_id_when_mouse_over_scrollbar_); + if (new_animation_controller) + new_animation_controller->DidMouseMoveNear(0); } void LayerTreeHostImpl::PinchGestureBegin() { @@ -3044,16 +3031,8 @@ } void LayerTreeHostImpl::AnimateScrollbars(base::TimeTicks monotonic_time) { - if (scrollbar_animation_controllers_.empty()) - return; - - TRACE_EVENT0("cc", "LayerTreeHostImpl::AnimateScrollbars"); - std::set<ScrollbarAnimationController*> controllers_copy = - scrollbar_animation_controllers_; - for (auto& it : controllers_copy) - it->Animate(monotonic_time); - - SetNeedsAnimate(); + for (auto& it : scrollbar_animation_controllers_) + it.second->Animate(monotonic_time); } void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time) { @@ -3132,15 +3111,32 @@ return str; } -void LayerTreeHostImpl::StartAnimatingScrollbarAnimationController( - ScrollbarAnimationController* controller) { - scrollbar_animation_controllers_.insert(controller); - SetNeedsAnimate(); +void LayerTreeHostImpl::RegisterScrollbarAnimationController( + int scroll_layer_id) { + if (settings().scrollbar_animator == LayerTreeSettings::NO_ANIMATOR) + return; + if (ScrollbarAnimationControllerForId(scroll_layer_id)) + return; + scrollbar_animation_controllers_.add( + scroll_layer_id, + active_tree_->CreateScrollbarAnimationController(scroll_layer_id)); } -void LayerTreeHostImpl::StopAnimatingScrollbarAnimationController( - ScrollbarAnimationController* controller) { - scrollbar_animation_controllers_.erase(controller); +void LayerTreeHostImpl::UnregisterScrollbarAnimationController( + int scroll_layer_id) { + scrollbar_animation_controllers_.erase(scroll_layer_id); +} + +ScrollbarAnimationController* +LayerTreeHostImpl::ScrollbarAnimationControllerForId( + int scroll_layer_id) const { + if (InnerViewportScrollLayer() && OuterViewportScrollLayer() && + scroll_layer_id == InnerViewportScrollLayer()->id()) + scroll_layer_id = OuterViewportScrollLayer()->id(); + auto i = scrollbar_animation_controllers_.find(scroll_layer_id); + if (i == scrollbar_animation_controllers_.end()) + return nullptr; + return i->second; } void LayerTreeHostImpl::PostDelayedScrollbarAnimationTask( @@ -3149,10 +3145,19 @@ client_->PostDelayedAnimationTaskOnImplThread(task, delay); } +void LayerTreeHostImpl::SetNeedsAnimateForScrollbarAnimation() { + TRACE_EVENT0("cc", "LayerTreeHostImpl::SetNeedsAnimateForScrollbarAnimation"); + SetNeedsAnimate(); +} + void LayerTreeHostImpl::SetNeedsRedrawForScrollbarAnimation() { SetNeedsRedraw(); } +ScrollbarSet LayerTreeHostImpl::ScrollbarsFor(int scroll_layer_id) const { + return active_tree_->ScrollbarsFor(scroll_layer_id); +} + void LayerTreeHostImpl::AddVideoFrameController( VideoFrameController* controller) { bool was_empty = video_frame_controllers_.empty();
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index f2d5dfaa..ed724b3 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -298,6 +298,11 @@ size_t SourceAnimationFrameNumberForTesting() const; + void RegisterScrollbarAnimationController(int scroll_layer_id); + void UnregisterScrollbarAnimationController(int scroll_layer_id); + ScrollbarAnimationController* ScrollbarAnimationControllerForId( + int scroll_layer_id) const; + DrawMode GetDrawMode() const; // Viewport size in draw space: this size is in physical pixels and is used @@ -323,13 +328,11 @@ void SetIsLikelyToRequireADraw(bool is_likely_to_require_a_draw) override; // ScrollbarAnimationControllerClient implementation. - void StartAnimatingScrollbarAnimationController( - ScrollbarAnimationController* controller) override; - void StopAnimatingScrollbarAnimationController( - ScrollbarAnimationController* controller) override; void PostDelayedScrollbarAnimationTask(const base::Closure& task, base::TimeDelta delay) override; + void SetNeedsAnimateForScrollbarAnimation() override; void SetNeedsRedrawForScrollbarAnimation() override; + ScrollbarSet ScrollbarsFor(int scroll_layer_id) const override; // VideoBeginFrameSource implementation. void AddVideoFrameController(VideoFrameController* controller) override; @@ -652,8 +655,7 @@ void ClearCurrentlyScrollingLayer(); - bool HandleMouseOverScrollbar(LayerImpl* layer_impl, - const gfx::PointF& device_viewport_point); + void HandleMouseOverScrollbar(LayerImpl* layer_impl); LayerImpl* FindScrollLayerForDeviceViewportPoint( const gfx::PointF& device_viewport_point, @@ -783,9 +785,13 @@ scoped_ptr<AnimationRegistrar> animation_registrar_; scoped_ptr<AnimationHost> animation_host_; - std::set<ScrollbarAnimationController*> scrollbar_animation_controllers_; std::set<VideoFrameController*> video_frame_controllers_; + // Map from scroll layer ID to scrollbar animation controller. + // There is one animation controller per pair of overlay scrollbars. + base::ScopedPtrHashMap<int, scoped_ptr<ScrollbarAnimationController>> + scrollbar_animation_controllers_; + RenderingStatsInstrumentation* rendering_stats_instrumentation_; MicroBenchmarkControllerImpl micro_benchmark_controller_; scoped_ptr<TaskGraphRunner> single_thread_synchronous_task_graph_runner_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 0de56bf5..68f775d 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -1014,22 +1014,14 @@ EXPECT_EQ(InputHandler::SCROLL_STARTED, host_impl_->ScrollBegin(gfx::Point(), InputHandler::WHEEL)); - // Trying to scroll without a vertical scrollbar will fail. + // Trying to scroll if not user_scrollable_vertical will fail. + host_impl_->InnerViewportScrollLayer()->set_user_scrollable_vertical(false); EXPECT_FALSE(host_impl_->ScrollVerticallyByPage( gfx::Point(), SCROLL_FORWARD)); EXPECT_FALSE(host_impl_->ScrollVerticallyByPage( gfx::Point(), SCROLL_BACKWARD)); - scoped_ptr<PaintedScrollbarLayerImpl> vertical_scrollbar( - PaintedScrollbarLayerImpl::Create( - host_impl_->active_tree(), - 20, - VERTICAL)); - vertical_scrollbar->SetBounds(gfx::Size(15, 1000)); - host_impl_->InnerViewportScrollLayer()->AddScrollbar( - vertical_scrollbar.get()); - - // Trying to scroll with a vertical scrollbar will succeed. + host_impl_->InnerViewportScrollLayer()->set_user_scrollable_vertical(true); EXPECT_TRUE(host_impl_->ScrollVerticallyByPage( gfx::Point(), SCROLL_FORWARD)); EXPECT_FLOAT_EQ(875.f, @@ -1311,6 +1303,54 @@ outer_scroll_layer->CurrentScrollOffset()); } +// Make sure scrolls smaller than a unit applied to the viewport don't get +// dropped. crbug.com/539334. +TEST_F(LayerTreeHostImplTest, ScrollViewportWithFractionalAmounts) { + LayerTreeSettings settings = DefaultSettings(); + CreateHostImpl(settings, CreateOutputSurface()); + host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); + + const gfx::Size content_size(1000, 1000); + const gfx::Size viewport_size(500, 500); + CreateBasicVirtualViewportLayers(viewport_size, content_size); + + LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); + + // Sanity checks. + EXPECT_VECTOR_EQ( + gfx::Vector2dF(500, 500), + outer_scroll_layer->MaxScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), outer_scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), inner_scroll_layer->CurrentScrollOffset()); + + RebuildPropertyTrees(); + + // Scroll only the layout viewport. + host_impl_->ScrollBegin(gfx::Point(250, 250), InputHandler::GESTURE); + host_impl_->ScrollBy(gfx::Point(250, 250), gfx::Vector2dF(0.125f, 0.125f)); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0.125f, 0.125f), + outer_scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0, 0), + inner_scroll_layer->CurrentScrollOffset()); + host_impl_->ScrollEnd(); + + host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 1.f, 2.f); + + // Now that we zoomed in, the scroll should be applied to the inner viewport. + host_impl_->ScrollBegin(gfx::Point(250, 250), InputHandler::GESTURE); + host_impl_->ScrollBy(gfx::Point(250, 250), gfx::Vector2dF(0.5f, 0.5f)); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0.125f, 0.125f), + outer_scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0.25f, 0.25f), + inner_scroll_layer->CurrentScrollOffset()); + host_impl_->ScrollEnd(); +} + // Tests that scrolls during a pinch gesture (i.e. "two-finger" scrolls) work // as expected. That is, scrolling during a pinch should bubble from the inner // to the outer viewport. @@ -2159,9 +2199,9 @@ VERTICAL, 10, 0, false, true); EXPECT_FLOAT_EQ(0.f, scrollbar->opacity()); - LayerImpl* scroll = host_impl_->InnerViewportScrollLayer(); - LayerImpl* root = scroll->parent()->parent(); - scrollbar->SetScrollLayerAndClipLayerByIds(scroll->id(), root->id()); + LayerImpl* scroll = host_impl_->active_tree()->OuterViewportScrollLayer(); + LayerImpl* root = host_impl_->active_tree()->InnerViewportContainerLayer(); + scrollbar->SetScrollLayerId(scroll->id()); root->AddChild(scrollbar.Pass()); host_impl_->active_tree()->DidBecomeActive(); @@ -2178,10 +2218,12 @@ base::TimeTicks fake_now = base::TimeTicks::Now(); + // A task will be posted to fade the initial scrollbar. EXPECT_FALSE(did_request_animate_); EXPECT_FALSE(did_request_redraw_); - EXPECT_EQ(base::TimeDelta(), requested_animation_delay_); - EXPECT_TRUE(animation_task_.Equals(base::Closure())); + EXPECT_FALSE(animation_task_.Equals(base::Closure())); + requested_animation_delay_ = base::TimeDelta(); + animation_task_ = base::Closure(); // If no scroll happened during a scroll gesture, it should have no effect. host_impl_->ScrollBegin(gfx::Point(), InputHandler::WHEEL); @@ -2293,9 +2335,9 @@ scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar = SolidColorScrollbarLayerImpl::Create(host_impl_->pending_tree(), 400, VERTICAL, 10, 0, false, true); - LayerImpl* scroll = host_impl_->pending_tree()->InnerViewportScrollLayer(); - LayerImpl* root = scroll->parent()->parent(); - scrollbar->SetScrollLayerAndClipLayerByIds(scroll->id(), root->id()); + LayerImpl* scroll = host_impl_->pending_tree()->OuterViewportScrollLayer(); + LayerImpl* root = host_impl_->pending_tree()->InnerViewportContainerLayer(); + scrollbar->SetScrollLayerId(scroll->id()); root->AddChild(scrollbar.Pass()); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); host_impl_->pending_tree()->BuildPropertyTreesForTesting(); @@ -2308,6 +2350,8 @@ scrollbar_layer->effect_tree_index()); EXPECT_FLOAT_EQ(scrollbar_layer->opacity(), active_tree_node->data.opacity); + host_impl_->ScrollbarAnimationControllerForId(scroll->id()) + ->DidMouseMoveNear(0); host_impl_->ScrollBegin(gfx::Point(), InputHandler::WHEEL); host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 5)); host_impl_->ScrollEnd(); @@ -2335,6 +2379,126 @@ RunTest(LayerTreeSettings::THINNING); } +TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { + LayerTreeSettings settings; + settings.scrollbar_animator = LayerTreeSettings::LINEAR_FADE; + settings.scrollbar_fade_delay_ms = 20; + settings.scrollbar_fade_duration_ms = 20; + CreateHostImpl(settings, CreateOutputSurface()); + + gfx::Size viewport_size(300, 200); + gfx::Size content_size(1000, 1000); + + const int vert_1_id = 10; + const int horiz_1_id = 11; + const int vert_2_id = 12; + const int horiz_2_id = 13; + const int child_clip_id = 14; + const int child_scroll_id = 15; + + CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); + host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( + viewport_size); + LayerImpl* root_scroll = + host_impl_->active_tree()->OuterViewportScrollLayer(); + scoped_ptr<SolidColorScrollbarLayerImpl> vert_1_scrollbar = + SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), vert_1_id, + VERTICAL, 5, 5, true, true); + scoped_ptr<SolidColorScrollbarLayerImpl> horiz_1_scrollbar = + SolidColorScrollbarLayerImpl::Create( + host_impl_->active_tree(), horiz_1_id, HORIZONTAL, 5, 5, true, true); + scoped_ptr<SolidColorScrollbarLayerImpl> vert_2_scrollbar = + SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), vert_2_id, + VERTICAL, 5, 5, true, true); + scoped_ptr<SolidColorScrollbarLayerImpl> horiz_2_scrollbar = + SolidColorScrollbarLayerImpl::Create( + host_impl_->active_tree(), horiz_2_id, HORIZONTAL, 5, 5, true, true); + scoped_ptr<LayerImpl> child = + LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); + child->SetBounds(content_size); + scoped_ptr<LayerImpl> child_clip = + LayerImpl::Create(host_impl_->active_tree(), child_clip_id); + child->SetBounds(viewport_size); + LayerImpl* child_ptr = child.get(); + LayerImpl* child_clip_ptr = child_clip.get(); + + // Check scrollbar registration on the viewport layers. + EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(root_scroll->id()).size()); + EXPECT_EQ(nullptr, + host_impl_->ScrollbarAnimationControllerForId(root_scroll->id())); + vert_1_scrollbar->SetScrollLayerId(root_scroll->id()); + EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(root_scroll->id()).size()); + EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(root_scroll->id())); + horiz_1_scrollbar->SetScrollLayerId(root_scroll->id()); + EXPECT_EQ(2ul, host_impl_->ScrollbarsFor(root_scroll->id()).size()); + EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(root_scroll->id())); + + // Changing one of the viewport layers should result in a scrollbar animation + // update. + animation_task_ = base::Closure(); + host_impl_->active_tree()->InnerViewportContainerLayer()->SetBoundsDelta( + gfx::Vector2dF(10, 10)); + EXPECT_FALSE(animation_task_.Equals(base::Closure())); + animation_task_ = base::Closure(); + host_impl_->active_tree()->OuterViewportScrollLayer()->SetCurrentScrollOffset( + gfx::ScrollOffset(10, 10)); + EXPECT_FALSE(animation_task_.Equals(base::Closure())); + animation_task_ = base::Closure(); + host_impl_->active_tree()->InnerViewportScrollLayer()->SetCurrentScrollOffset( + gfx::ScrollOffset(10, 10)); + EXPECT_FALSE(animation_task_.Equals(base::Closure())); + animation_task_ = base::Closure(); + + // Check scrollbar registration on a sublayer. + child->SetScrollClipLayer(child_clip->id()); + child_clip->AddChild(child.Pass()); + root_scroll->AddChild(child_clip.Pass()); + EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(child_scroll_id).size()); + EXPECT_EQ(nullptr, + host_impl_->ScrollbarAnimationControllerForId(child_scroll_id)); + vert_2_scrollbar->SetScrollLayerId(child_scroll_id); + EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(child_scroll_id).size()); + EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(child_scroll_id)); + horiz_2_scrollbar->SetScrollLayerId(child_scroll_id); + EXPECT_EQ(2ul, host_impl_->ScrollbarsFor(child_scroll_id).size()); + EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(child_scroll_id)); + + // Changing one of the child layers should result in a scrollbar animation + // update. + animation_task_ = base::Closure(); + child_clip_ptr->SetBounds(gfx::Size(200, 200)); + EXPECT_FALSE(animation_task_.Equals(base::Closure())); + animation_task_ = base::Closure(); + child_ptr->SetCurrentScrollOffset(gfx::ScrollOffset(10, 10)); + EXPECT_FALSE(animation_task_.Equals(base::Closure())); + animation_task_ = base::Closure(); + + // Check scrollbar unregistration. + vert_1_scrollbar.reset(); + EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(root_scroll->id()).size()); + EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(root_scroll->id())); + horiz_1_scrollbar.reset(); + EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(root_scroll->id()).size()); + EXPECT_EQ(nullptr, + host_impl_->ScrollbarAnimationControllerForId(root_scroll->id())); + + EXPECT_EQ(2ul, host_impl_->ScrollbarsFor(child_scroll_id).size()); + vert_2_scrollbar.reset(); + EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(child_scroll_id).size()); + EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForId(child_scroll_id)); + horiz_2_scrollbar.reset(); + EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(child_scroll_id).size()); + EXPECT_EQ(nullptr, + host_impl_->ScrollbarAnimationControllerForId(root_scroll->id())); + + // Changing scroll offset should no longer trigger any animation. + host_impl_->active_tree()->InnerViewportScrollLayer()->SetCurrentScrollOffset( + gfx::ScrollOffset(20, 20)); + EXPECT_TRUE(animation_task_.Equals(base::Closure())); + child_ptr->SetCurrentScrollOffset(gfx::ScrollOffset(20, 20)); + EXPECT_TRUE(animation_task_.Equals(base::Closure())); +} + void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( float device_scale_factor) { LayerTreeSettings settings; @@ -2346,75 +2510,60 @@ gfx::Size device_viewport_size = gfx::ScaleToFlooredSize(viewport_size, device_scale_factor); gfx::Size content_size(1000, 1000); + gfx::Size scrollbar_size(gfx::Size(15, viewport_size.height())); CreateHostImpl(settings, CreateOutputSurface()); host_impl_->active_tree()->SetDeviceScaleFactor(device_scale_factor); host_impl_->SetViewportSize(device_viewport_size); - scoped_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - root->SetBounds(viewport_size); - root->SetHasRenderSurface(true); - - scoped_ptr<LayerImpl> scroll = - LayerImpl::Create(host_impl_->active_tree(), 2); - scroll->SetScrollClipLayer(root->id()); - scroll->PushScrollOffsetFromMainThread(gfx::ScrollOffset()); - scroll->SetBounds(content_size); - scroll->SetIsContainerForFixedPositionLayers(true); - - scoped_ptr<LayerImpl> contents = - LayerImpl::Create(host_impl_->active_tree(), 3); - contents->SetDrawsContent(true); - contents->SetBounds(content_size); - - // The scrollbar is on the right side. - scoped_ptr<PaintedScrollbarLayerImpl> scrollbar = - PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), 5, VERTICAL); - scrollbar->SetDrawsContent(true); - scrollbar->SetBounds(gfx::Size(15, viewport_size.height())); - scrollbar->SetPosition(gfx::Point(285, 0)); - - scroll->AddChild(contents.Pass()); - root->AddChild(scroll.Pass()); - scrollbar->SetScrollLayerAndClipLayerByIds(2, 1); - root->AddChild(scrollbar.Pass()); - - host_impl_->active_tree()->SetRootLayer(root.Pass()); - host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 1, 2, - Layer::INVALID_ID); - host_impl_->active_tree()->DidBecomeActive(); - DrawFrame(); - + CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); + host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( + viewport_size); LayerImpl* root_scroll = - host_impl_->active_tree()->InnerViewportScrollLayer(); - ASSERT_TRUE(root_scroll->scrollbar_animation_controller()); + host_impl_->active_tree()->OuterViewportScrollLayer(); + // The scrollbar is on the left side. + scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar = + SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), 6, + VERTICAL, 5, 5, true, true); + scrollbar->SetScrollLayerId(root_scroll->id()); + scrollbar->SetDrawsContent(true); + scrollbar->SetBounds(scrollbar_size); + scrollbar->SetTouchEventHandlerRegion(gfx::Rect(scrollbar_size)); + host_impl_->active_tree()->InnerViewportContainerLayer()->AddChild( + scrollbar.Pass()); + host_impl_->active_tree()->DidBecomeActive(); + + DrawFrame(); + host_impl_->active_tree()->UpdateDrawProperties(false); + ScrollbarAnimationControllerThinning* scrollbar_animation_controller = static_cast<ScrollbarAnimationControllerThinning*>( - root_scroll->scrollbar_animation_controller()); + host_impl_->ScrollbarAnimationControllerForId(root_scroll->id())); scrollbar_animation_controller->set_mouse_move_distance_for_test(100.f); - host_impl_->MouseMoveAt(gfx::Point(1, 1)); + host_impl_->MouseMoveAt(gfx::Point(200, 1)); EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar()); - host_impl_->MouseMoveAt(gfx::Point(200, 50)); + host_impl_->MouseMoveAt(gfx::Point(100, 50)); EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar()); - host_impl_->MouseMoveAt(gfx::Point(184, 100)); + host_impl_->MouseMoveAt(gfx::Point(116, 100)); EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar()); scrollbar_animation_controller->set_mouse_move_distance_for_test(102.f); - host_impl_->MouseMoveAt(gfx::Point(184, 100)); + host_impl_->MouseMoveAt(gfx::Point(116, 100)); EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar()); did_request_redraw_ = false; - EXPECT_EQ(0, host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); - host_impl_->MouseMoveAt(gfx::Point(290, 100)); - EXPECT_EQ(2, host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); - host_impl_->MouseMoveAt(gfx::Point(290, 120)); - EXPECT_EQ(2, host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); + EXPECT_EQ(Layer::INVALID_ID, + host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); + host_impl_->MouseMoveAt(gfx::Point(10, 100)); + EXPECT_EQ(117, host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); + host_impl_->MouseMoveAt(gfx::Point(10, 120)); + EXPECT_EQ(117, host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); host_impl_->MouseMoveAt(gfx::Point(150, 120)); - EXPECT_EQ(0, host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); + EXPECT_EQ(Layer::INVALID_ID, + host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); } TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf1) {
diff --git a/cc/trees/layer_tree_host_unittest_damage.cc b/cc/trees/layer_tree_host_unittest_damage.cc index 20667bf..f626b55c 100644 --- a/cc/trees/layer_tree_host_unittest_damage.cc +++ b/cc/trees/layer_tree_host_unittest_damage.cc
@@ -353,7 +353,6 @@ layer_settings(), false, true, content_layer->id()); scrollbar_layer->SetPosition(gfx::Point(300, 300)); scrollbar_layer->SetBounds(gfx::Size(10, 100)); - scrollbar_layer->ToScrollbarLayer()->SetClipLayer(scroll_clip_layer->id()); scrollbar_layer->ToScrollbarLayer()->SetScrollLayer(content_layer->id()); root_layer->AddChild(scrollbar_layer);
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 10421ae5..6b0c9fd 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -112,6 +112,108 @@ }); } +bool LayerTreeImpl::IsViewportLayerId(int id) const { + if (id == inner_viewport_scroll_layer_id_ || + id == outer_viewport_scroll_layer_id_) + return true; + if (InnerViewportContainerLayer() && + id == InnerViewportContainerLayer()->id()) + return true; + if (OuterViewportContainerLayer() && + id == OuterViewportContainerLayer()->id()) + return true; + + return false; +} + +void LayerTreeImpl::DidUpdateScrollState(int layer_id) { + if (!IsActiveTree()) + return; + + if (layer_id == Layer::INVALID_ID) + return; + + int scroll_layer_id, clip_layer_id; + if (IsViewportLayerId(layer_id)) { + if (!InnerViewportContainerLayer()) + return; + + // For scrollbar purposes, a change to any of the four viewport layers + // should affect the scrollbars tied to the outermost layers, which express + // the sum of the entire viewport. + scroll_layer_id = outer_viewport_scroll_layer_id_; + clip_layer_id = InnerViewportContainerLayer()->id(); + } else { + // If the clip layer id was passed in, then look up the scroll layer, or + // vice versa. + auto i = clip_scroll_map_.find(layer_id); + if (i != clip_scroll_map_.end()) { + scroll_layer_id = i->second; + clip_layer_id = layer_id; + } else { + scroll_layer_id = layer_id; + clip_layer_id = LayerById(scroll_layer_id)->scroll_clip_layer_id(); + } + } + UpdateScrollbars(scroll_layer_id, clip_layer_id); +} + +void LayerTreeImpl::UpdateScrollbars(int scroll_layer_id, int clip_layer_id) { + DCHECK(IsActiveTree()); + + LayerImpl* clip_layer = LayerById(clip_layer_id); + LayerImpl* scroll_layer = LayerById(scroll_layer_id); + + if (!clip_layer || !scroll_layer) + return; + + gfx::SizeF clip_size(clip_layer->BoundsForScrolling()); + gfx::SizeF scroll_size(scroll_layer->BoundsForScrolling()); + + if (scroll_size.IsEmpty()) + return; + + gfx::ScrollOffset current_offset = scroll_layer->CurrentScrollOffset(); + if (IsViewportLayerId(scroll_layer_id)) { + current_offset += InnerViewportScrollLayer()->CurrentScrollOffset(); + clip_size.Scale(1 / current_page_scale_factor()); + } + + bool scrollbar_needs_animation = false; + bool scroll_layer_size_did_change = false; + bool y_offset_did_change = false; + for (ScrollbarLayerImplBase* scrollbar : ScrollbarsFor(scroll_layer_id)) { + if (scrollbar->orientation() == HORIZONTAL) { + scrollbar_needs_animation |= scrollbar->SetCurrentPos(current_offset.x()); + scrollbar_needs_animation |= + scrollbar->SetClipLayerLength(clip_size.width()); + scrollbar_needs_animation |= scroll_layer_size_did_change |= + scrollbar->SetScrollLayerLength(scroll_size.width()); + } else { + scrollbar_needs_animation |= y_offset_did_change |= + scrollbar->SetCurrentPos(current_offset.y()); + scrollbar_needs_animation |= + scrollbar->SetClipLayerLength(clip_size.height()); + scrollbar_needs_animation |= scroll_layer_size_did_change |= + scrollbar->SetScrollLayerLength(scroll_size.height()); + } + scrollbar_needs_animation |= + scrollbar->SetVerticalAdjust(clip_layer->bounds_delta().y()); + } + + if (y_offset_did_change && IsViewportLayerId(scroll_layer_id)) + TRACE_COUNTER_ID1("cc", "scroll_offset_y", scroll_layer->id(), + current_offset.y()); + + if (scrollbar_needs_animation) { + ScrollbarAnimationController* controller = + layer_tree_host_impl_->ScrollbarAnimationControllerForId( + scroll_layer_id); + if (controller) + controller->DidScrollUpdate(scroll_layer_size_did_change); + } +} + void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) { root_layer_ = layer.Pass(); @@ -272,32 +374,23 @@ if (currently_scrolling_layer_id_ == new_id) return; - if (CurrentlyScrollingLayer() && - CurrentlyScrollingLayer()->scrollbar_animation_controller()) - CurrentlyScrollingLayer()->scrollbar_animation_controller()->DidScrollEnd(); + ScrollbarAnimationController* old_animation_controller = + layer_tree_host_impl_->ScrollbarAnimationControllerForId( + currently_scrolling_layer_id_); + ScrollbarAnimationController* new_animation_controller = + layer_tree_host_impl_->ScrollbarAnimationControllerForId(new_id); + + if (old_animation_controller) + old_animation_controller->DidScrollEnd(); currently_scrolling_layer_id_ = new_id; - if (layer && layer->scrollbar_animation_controller()) - layer->scrollbar_animation_controller()->DidScrollBegin(); + if (new_animation_controller) + new_animation_controller->DidScrollBegin(); } void LayerTreeImpl::ClearCurrentlyScrollingLayer() { SetCurrentlyScrollingLayer(NULL); } -namespace { - -void ForceScrollbarParameterUpdateAfterScaleChange(LayerImpl* current_layer) { - if (!current_layer) - return; - - while (current_layer) { - current_layer->ScrollbarParametersDidChange(false); - current_layer = current_layer->parent(); - } -} - -} // namespace - float LayerTreeImpl::ClampPageScaleFactorToLimits( float page_scale_factor) const { if (min_page_scale_factor_ && page_scale_factor < min_page_scale_factor_) @@ -425,7 +518,7 @@ ClampPageScaleFactorToLimits(current_page_scale_factor())); set_needs_update_draw_properties(); - ForceScrollbarParameterUpdateAfterScaleChange(PageScaleLayer()); + DidUpdateScrollState(inner_viewport_scroll_layer_id_); HideInnerViewportScrollbarsIfNeeded(); } @@ -439,23 +532,14 @@ } void LayerTreeImpl::HideInnerViewportScrollbarsIfNeeded() { - if (!InnerViewportContainerLayer()) - return; - - LayerImpl::ScrollbarSet* scrollbars = - InnerViewportContainerLayer()->scrollbars(); - - if (!scrollbars) - return; - float minimum_scale_to_show_at = min_page_scale_factor() * 1.05f; bool hide_scrollbars = hide_pinch_scrollbars_near_min_scale_ && (current_page_scale_factor() < minimum_scale_to_show_at); - for (LayerImpl::ScrollbarSet::iterator it = scrollbars->begin(); - it != scrollbars->end(); ++it) - (*it)->SetHideLayerAndSubtree(hide_scrollbars); + for (ScrollbarLayerImplBase* scrollbar_layer : + ScrollbarsFor(outer_viewport_scroll_layer_id_)) + scrollbar_layer->SetHideLayerAndSubtree(hide_scrollbars); } SyncedProperty<ScaleGroup>* LayerTreeImpl::page_scale_factor() { @@ -916,7 +1000,7 @@ } scoped_ptr<ScrollbarAnimationController> -LayerTreeImpl::CreateScrollbarAnimationController(LayerImpl* scrolling_layer) { +LayerTreeImpl::CreateScrollbarAnimationController(int scroll_layer_id) { DCHECK(settings().scrollbar_fade_delay_ms); DCHECK(settings().scrollbar_fade_duration_ms); base::TimeDelta delay = @@ -928,18 +1012,13 @@ switch (settings().scrollbar_animator) { case LayerTreeSettings::LINEAR_FADE: { return ScrollbarAnimationControllerLinearFade::Create( - scrolling_layer, - layer_tree_host_impl_, - delay, - resize_delay, + scroll_layer_id, layer_tree_host_impl_, delay, resize_delay, duration); } case LayerTreeSettings::THINNING: { - return ScrollbarAnimationControllerThinning::Create(scrolling_layer, - layer_tree_host_impl_, - delay, - resize_delay, - duration); + return ScrollbarAnimationControllerThinning::Create( + scroll_layer_id, layer_tree_host_impl_, delay, resize_delay, + duration); } case LayerTreeSettings::NO_ANIMATOR: NOTREACHED(); @@ -1134,6 +1213,62 @@ picture_layers_.erase(it); } +void LayerTreeImpl::RegisterScrollbar(ScrollbarLayerImplBase* scrollbar_layer) { + if (scrollbar_layer->ScrollLayerId() == Layer::INVALID_ID) + return; + + scrollbar_map_.insert(std::pair<int, int>(scrollbar_layer->ScrollLayerId(), + scrollbar_layer->id())); + if (IsActiveTree() && scrollbar_layer->is_overlay_scrollbar()) + layer_tree_host_impl_->RegisterScrollbarAnimationController( + scrollbar_layer->ScrollLayerId()); + + DidUpdateScrollState(scrollbar_layer->ScrollLayerId()); +} + +void LayerTreeImpl::UnregisterScrollbar( + ScrollbarLayerImplBase* scrollbar_layer) { + int scroll_layer_id = scrollbar_layer->ScrollLayerId(); + if (scroll_layer_id == Layer::INVALID_ID) + return; + + auto scrollbar_range = scrollbar_map_.equal_range(scroll_layer_id); + for (auto i = scrollbar_range.first; i != scrollbar_range.second; ++i) + if (i->second == scrollbar_layer->id()) { + scrollbar_map_.erase(i); + break; + } + + if (IsActiveTree() && scrollbar_map_.count(scroll_layer_id) == 0) + layer_tree_host_impl_->UnregisterScrollbarAnimationController( + scroll_layer_id); +} + +ScrollbarSet LayerTreeImpl::ScrollbarsFor(int scroll_layer_id) const { + ScrollbarSet scrollbars; + auto scrollbar_range = scrollbar_map_.equal_range(scroll_layer_id); + for (auto i = scrollbar_range.first; i != scrollbar_range.second; ++i) + scrollbars.insert(LayerById(i->second)->ToScrollbarLayer()); + return scrollbars; +} + +void LayerTreeImpl::RegisterScrollLayer(LayerImpl* layer) { + if (layer->scroll_clip_layer_id() == Layer::INVALID_ID) + return; + + clip_scroll_map_.insert( + std::pair<int, int>(layer->scroll_clip_layer_id(), layer->id())); + + DidUpdateScrollState(layer->id()); +} + +void LayerTreeImpl::UnregisterScrollLayer(LayerImpl* layer) { + if (layer->scroll_clip_layer_id() == Layer::INVALID_ID) + return; + + clip_scroll_map_.erase(layer->scroll_clip_layer_id()); +} + void LayerTreeImpl::AddLayerWithCopyOutputRequest(LayerImpl* layer) { // Only the active tree needs to know about layers with copy requests, as // they are aborted if not serviced during draw.
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h index ed4413a..8bc1ee7 100644 --- a/cc/trees/layer_tree_impl.h +++ b/cc/trees/layer_tree_impl.h
@@ -5,6 +5,7 @@ #ifndef CC_TREES_LAYER_TREE_IMPL_H_ #define CC_TREES_LAYER_TREE_IMPL_H_ +#include <map> #include <set> #include <string> #include <vector> @@ -99,7 +100,7 @@ gfx::Size DrawViewportSize() const; const gfx::Rect ViewportRectForTilePriority() const; scoped_ptr<ScrollbarAnimationController> CreateScrollbarAnimationController( - LayerImpl* scrolling_layer); + int scroll_layer_id); void DidAnimateScrollOffset(); void InputScrollAnimationFinished(); bool use_gpu_rasterization() const; @@ -320,6 +321,13 @@ return picture_layers_; } + void RegisterScrollbar(ScrollbarLayerImplBase* scrollbar_layer); + void UnregisterScrollbar(ScrollbarLayerImplBase* scrollbar_layer); + ScrollbarSet ScrollbarsFor(int scroll_layer_id) const; + + void RegisterScrollLayer(LayerImpl* layer); + void UnregisterScrollLayer(LayerImpl* layer); + void AddLayerWithCopyOutputRequest(LayerImpl* layer); void RemoveLayerWithCopyOutputRequest(LayerImpl* layer); const std::vector<LayerImpl*>& LayersWithCopyOutputRequest() const; @@ -363,6 +371,8 @@ void GatherFrameTimingRequestIds(std::vector<int64_t>* request_ids); + void DidUpdateScrollState(int layer_id); + bool IsAnimatingFilterProperty(const LayerImpl* layer) const; bool IsAnimatingOpacityProperty(const LayerImpl* layer) const; bool IsAnimatingTransformProperty(const LayerImpl* layer) const; @@ -407,6 +417,8 @@ float max_page_scale_factor); bool SetPageScaleFactorLimits(float min_page_scale_factor, float max_page_scale_factor); + bool IsViewportLayerId(int id) const; + void UpdateScrollbars(int scroll_layer_id, int clip_layer_id); void DidUpdatePageScale(); void HideInnerViewportScrollbarsIfNeeded(); void PushTopControls(const float* top_controls_shown_ratio); @@ -438,6 +450,17 @@ typedef base::hash_map<int, LayerImpl*> LayerIdMap; LayerIdMap layer_id_map_; + // Maps from clip layer ids to scroll layer ids. Note that this only includes + // the subset of clip layers that act as scrolling containers. (This is + // derived from LayerImpl::scroll_clip_layer_ and exists to avoid O(n) walks.) + base::hash_map<int, int> clip_scroll_map_; + + // Maps scroll layer ids to scrollbar layer ids. For each scroll layer, there + // may be 1 or 2 scrollbar layers (for vertical and horizontal). (This is + // derived from ScrollbarLayerImplBase::scroll_layer_id_ and exists to avoid + // O(n) walks.) + std::multimap<int, int> scrollbar_map_; + std::vector<PictureLayerImpl*> picture_layers_; std::vector<LayerImpl*> layers_with_copy_output_request_;
diff --git a/cc/trees/layer_tree_impl_unittest.cc b/cc/trees/layer_tree_impl_unittest.cc index 2907cc7..77e0749 100644 --- a/cc/trees/layer_tree_impl_unittest.cc +++ b/cc/trees/layer_tree_impl_unittest.cc
@@ -1364,29 +1364,27 @@ scoped_ptr<LayerImpl> clip_layer = LayerImpl::Create(active_tree, 4); scoped_ptr<LayerImpl> page_scale_layer = LayerImpl::Create(active_tree, 5); + scoped_ptr<LayerImpl> outer_scroll_layer = LayerImpl::Create(active_tree, 6); scroll_layer->SetScrollClipLayer(clip_layer->id()); LayerImpl* scroll_layer_ptr = scroll_layer.get(); + LayerImpl* outer_scroll_layer_ptr = outer_scroll_layer.get(); LayerImpl* page_scale_layer_ptr = page_scale_layer.get(); + scroll_layer->AddChild(outer_scroll_layer.Pass()); clip_layer->AddChild(page_scale_layer.Pass()); page_scale_layer_ptr->AddChild(scroll_layer.Pass()); - vertical_scrollbar_layer->SetScrollLayerAndClipLayerByIds( - scroll_layer_ptr->id(), - clip_layer->id()); - horizontal_scrollbar_layer->SetScrollLayerAndClipLayerByIds( - scroll_layer_ptr->id(), - clip_layer->id()); + active_tree->SetViewportLayersFromIds(Layer::INVALID_ID, // Overscroll + page_scale_layer_ptr->id(), + scroll_layer_ptr->id(), + outer_scroll_layer_ptr->id()); + + vertical_scrollbar_layer->SetScrollLayerId(outer_scroll_layer_ptr->id()); + horizontal_scrollbar_layer->SetScrollLayerId(outer_scroll_layer_ptr->id()); active_tree->PushPageScaleFromMainThread(1.0f, 1.0f, 4.0f); - active_tree->SetViewportLayersFromIds( - Layer::INVALID_ID, // Overscroll - page_scale_layer_ptr->id(), - scroll_layer_ptr->id(), - Layer::INVALID_ID); // Outer Scroll - EXPECT_TRUE(vertical_scrollbar_layer->hide_layer_and_subtree()); EXPECT_TRUE(horizontal_scrollbar_layer->hide_layer_and_subtree());
diff --git a/cc/trees/tree_synchronizer.cc b/cc/trees/tree_synchronizer.cc index 3646dcaa..9c61acb 100644 --- a/cc/trees/tree_synchronizer.cc +++ b/cc/trees/tree_synchronizer.cc
@@ -10,12 +10,8 @@ #include "base/containers/scoped_ptr_hash_map.h" #include "base/logging.h" #include "base/trace_event/trace_event.h" -#include "cc/animation/scrollbar_animation_controller.h" -#include "cc/input/scrollbar.h" #include "cc/layers/layer.h" #include "cc/layers/layer_impl.h" -#include "cc/layers/scrollbar_layer_impl_base.h" -#include "cc/layers/scrollbar_layer_interface.h" namespace cc { @@ -28,13 +24,6 @@ if (!layer_impl) return; - layer_impl->ClearScrollbars(); - if (ScrollbarLayerImplBase* scrollbar_layer = - layer_impl->ToScrollbarLayer()) { - scrollbar_layer->ClearClipLayer(); - scrollbar_layer->ClearScrollLayer(); - } - OwnedLayerImplList& children = layer_impl->children(); for (OwnedLayerImplList::iterator it = children.begin(); it != children.end(); @@ -64,8 +53,6 @@ scoped_ptr<LayerImpl> new_tree = SynchronizeTreesRecursive( &new_layers, &old_layers, layer_root, tree_impl); - UpdateScrollbarLayerPointersRecursive(&new_layers, layer_root); - return new_tree.Pass(); } @@ -143,46 +130,6 @@ new_layers, old_layers, layer, tree_impl); } -template <typename LayerType, typename ScrollbarLayerType> -void UpdateScrollbarLayerPointersRecursiveInternal( - const RawPtrLayerImplMap* new_layers, - LayerType* layer) { - if (!layer) - return; - - for (size_t i = 0; i < layer->children().size(); ++i) { - UpdateScrollbarLayerPointersRecursiveInternal< - LayerType, ScrollbarLayerType>(new_layers, layer->child_at(i)); - } - - ScrollbarLayerType* scrollbar_layer = layer->ToScrollbarLayer(); - if (!scrollbar_layer) - return; - - RawPtrLayerImplMap::const_iterator iter = - new_layers->find(layer->id()); - ScrollbarLayerImplBase* scrollbar_layer_impl = - iter != new_layers->end() - ? static_cast<ScrollbarLayerImplBase*>(iter->second) - : NULL; - DCHECK(scrollbar_layer_impl); - - scrollbar_layer->PushScrollClipPropertiesTo(scrollbar_layer_impl); -} - -void UpdateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap* new_layers, - Layer* layer) { - UpdateScrollbarLayerPointersRecursiveInternal<Layer, ScrollbarLayerInterface>( - new_layers, layer); -} - -void UpdateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap* new_layers, - LayerImpl* layer) { - UpdateScrollbarLayerPointersRecursiveInternal< - LayerImpl, - ScrollbarLayerImplBase>(new_layers, layer); -} - // static template <typename LayerType> void TreeSynchronizer::PushPropertiesInternal( @@ -202,8 +149,6 @@ if (push_layer) layer->PushPropertiesTo(layer_impl); - else if (layer->ToScrollbarLayer()) - layer->ToScrollbarLayer()->PushScrollClipPropertiesTo(layer_impl); int num_dependents_need_push_properties = 0; if (recurse_on_children_and_dependents) {
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index ae7b4f74..da52490 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -872,6 +872,8 @@ "//chrome/app:chromium_strings", "//chrome/app:generated_resources", "//chrome/app:google_chrome_strings", + "//chrome/app:settings_chromium_strings", + "//chrome/app:settings_google_chrome_strings", "//chrome/app:settings_strings", "//chrome/app/resources:locale_settings", ]
diff --git a/chrome/VERSION b/chrome/VERSION index 7a23a47..bdb0bbb 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=48 MINOR=0 -BUILD=2530 +BUILD=2531 PATCH=0
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index 1fef19f4..e1d9d7a 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -37,6 +37,7 @@ <uses-permission-sdk-m android:name="android.permission.BLUETOOTH_ADMIN"/> <uses-permission android:name="android.permission.CAMERA" /> + <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" /> <uses-permission android:name="android.permission.GET_ACCOUNTS"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
diff --git a/chrome/android/java/ResourceId.template b/chrome/android/java/ResourceId.template index 4894b5c4..78f5ee05 100644 --- a/chrome/android/java/ResourceId.template +++ b/chrome/android/java/ResourceId.template
@@ -9,7 +9,8 @@ public class ResourceId { public static int mapToDrawableId(int enumeratedId) { int[] resourceList = { -#define DEFINE_RESOURCE_ID(c_id,java_id) java_id, +#define LINK_RESOURCE_ID(c_id,java_id) java_id, +#define DECLARE_RESOURCE_ID(c_id,java_id) java_id, #include "chrome/browser/android/resource_id.h" };
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index a2bd6d5..c8fe8bf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -35,8 +35,6 @@ import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewStub; -import android.view.ViewTreeObserver; -import android.view.ViewTreeObserver.OnPreDrawListener; import android.view.Window; import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; @@ -217,8 +215,6 @@ // Time in ms that it took took us to inflate the initial layout private long mInflateInitialLayoutDurationMs; - private OnPreDrawListener mFirstDrawListener; - private final Locale mCurrentLocale = Locale.getDefault(); private AssistStatusHandler mAssistStatusHandler; @@ -299,23 +295,16 @@ // Inform the WindowAndroid of the keyboard accessory view. mWindowAndroid.setKeyboardAccessoryView((ViewGroup) findViewById(R.id.keyboard_accessory)); - final View controlContainer = findViewById(R.id.control_container); - if (controlContainer != null) { - mFirstDrawListener = new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - controlContainer.getViewTreeObserver() - .removeOnPreDrawListener(mFirstDrawListener); - mFirstDrawListener = null; - onFirstDrawComplete(); - return true; - } - }; - controlContainer.getViewTreeObserver().addOnPreDrawListener(mFirstDrawListener); - } initializeToolbar(); } + @Override + protected View getViewToBeDrawnBeforeInitializingNative() { + View controlContainer = findViewById(R.id.control_container); + return controlContainer != null ? controlContainer + : super.getViewToBeDrawnBeforeInitializingNative(); + } + /** * This function builds the {@link CompositorViewHolder}. Subclasses *must* call * super.setContentView() before using {@link #getTabModelSelector()} or @@ -564,7 +553,7 @@ * @param color The color that the status bar should be set to. */ protected void setStatusBarColor(Tab tab, int color) { - int statusBarColor = (tab != null && tab.getDefaultThemeColor() == color) + int statusBarColor = (tab != null && tab.isDefaultThemeColor()) ? Color.BLACK : ColorUtils.getDarkenedColorForStatusBar(color); ApiCompatibilityUtils.setStatusBarColor(getWindow(), statusBarColor); } @@ -639,12 +628,6 @@ mIntentHandler.onNewIntent(this, intent); } - @Override - public boolean hasDoneFirstDraw() { - return mToolbarManager != null - ? mToolbarManager.hasDoneFirstDraw() : super.hasDoneFirstDraw(); - } - /** * @return Whether the given activity contains a {@link CustomTab}. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/FrozenNativePage.java b/chrome/android/java/src/org/chromium/chrome/browser/FrozenNativePage.java index 201718e..98c4d2c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/FrozenNativePage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/FrozenNativePage.java
@@ -18,6 +18,7 @@ private final String mHost; private final String mTitle; private final int mBackgroundColor; + private final int mThemeColor; /** * Creates a FrozenNativePage to replace the given NativePage and destroys the NativePage. @@ -33,6 +34,7 @@ mUrl = nativePage.getUrl(); mTitle = nativePage.getTitle(); mBackgroundColor = nativePage.getBackgroundColor(); + mThemeColor = nativePage.getThemeColor(); } @Override @@ -62,6 +64,11 @@ } @Override + public int getThemeColor() { + return mThemeColor; + } + + @Override public void updateForUrl(String url) { }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/NativePage.java b/chrome/android/java/src/org/chromium/chrome/browser/NativePage.java index ffc7e7e..4392a0fd3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/NativePage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/NativePage.java
@@ -36,6 +36,11 @@ int getBackgroundColor(); /** + * @return The theme color of the page. + */ + int getThemeColor(); + + /** * Updates the native page based on the given url. */ void updateForUrl(String url);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java index 40815c1..4d66d32c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java
@@ -11,6 +11,7 @@ import android.content.res.Resources; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.os.Build; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; @@ -183,8 +184,11 @@ mPopup.setAnimationStyle(R.style.OverflowMenuAnim); } - // Turn off window animations for low end devices. - if (SysUtils.isLowEndDevice()) mPopup.setAnimationStyle(0); + // Turn off window animations for low end devices, and on Android M, which has built-in menu + // animations. + if (SysUtils.isLowEndDevice() || Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + mPopup.setAnimationStyle(0); + } Rect bgPadding = new Rect(); mPopup.getBackground().getPadding(bgPadding);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/CrashFileManager.java b/chrome/android/java/src/org/chromium/chrome/browser/crash/CrashFileManager.java index 2a78e0a..ed378f50 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/crash/CrashFileManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/crash/CrashFileManager.java
@@ -47,15 +47,21 @@ private static final Pattern TMP_PATTERN = Pattern.compile("\\.tmp\\z"); - private static Comparator<File> sFileComparator = new Comparator<File>() { + /** + * Comparator used for sorting files by modification + * Note that the behavior is undecided if the files are created at the same time + * @return Comparator for prioritizing the more recently modified file + */ + @VisibleForTesting + protected static final Comparator<File> sFileComparator = new Comparator<File>() { @Override public int compare(File lhs, File rhs) { if (lhs == rhs) { return 0; } else if (lhs.lastModified() < rhs.lastModified()) { - return -1; - } else { return 1; + } else { + return -1; } } };
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/document/DocumentActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/document/DocumentActivity.java index 01e9a69d..3a94ecf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/document/DocumentActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/document/DocumentActivity.java
@@ -801,8 +801,9 @@ private void updateTaskDescription(String label, Bitmap icon) { int color = mDefaultThemeColor; - if (getActivityTab() != null) color = getActivityTab().getThemeColor(); - boolean useDefaultStatusBarColor = isIncognito() || color == mDefaultThemeColor; + if (getActivityTab() != null && !getActivityTab().isDefaultThemeColor()) { + color = getActivityTab().getThemeColor(); + } ApiCompatibilityUtils.setTaskDescription(this, label, icon, color); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java index 56eb1b9..a6e8113 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
@@ -466,7 +466,9 @@ boolean canResolve = canResolveDownloadItem(mContext, downloadId); completionMap.put( progress.mDownloadInfo, Pair.create(downloadId, canResolve)); - mDownloadNotifier.notifyDownloadSuccessful(progress.mDownloadInfo); + mDownloadNotifier.notifyDownloadSuccessful( + progress.mDownloadInfo, + getLaunchIntentFromDownloadId(mContext, downloadId)); broadcastDownloadSuccessful(progress.mDownloadInfo); } break; @@ -505,7 +507,7 @@ try { downloadId = manager.addCompletedDownload( downloadInfo.getFileName(), description, true, mimeType, - downloadInfo.getFilePath(), downloadInfo.getContentLength(), true); + downloadInfo.getFilePath(), downloadInfo.getContentLength(), false); if (shouldOpenAfterDownload(downloadInfo)) { handleAutoOpenAfterDownload(downloadInfo, downloadId); } @@ -579,7 +581,7 @@ * * @param downloadId Download Identifier. */ - private void removeProgressNotificationForDownload(int downloadId) { + void removeProgressNotificationForDownload(int downloadId) { mDownloadProgressMap.remove(downloadId); mDownloadNotifier.cancelNotification(downloadId); removeDownloadIdFromSharedPrefs(downloadId);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotifier.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotifier.java index 053a730..9ba4672 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotifier.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotifier.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.download; +import android.content.Intent; + import org.chromium.content.browser.DownloadInfo; /** @@ -13,8 +15,9 @@ /** * Add a download successful notification. * @param downloadInfo info about the successful download. + * @param intent Intent to launch when clicking the download notification. */ - void notifyDownloadSuccessful(DownloadInfo downloadInfo); + void notifyDownloadSuccessful(DownloadInfo downloadInfo, Intent intent); /** * Add a download failed notification.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSnackbarController.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSnackbarController.java index fb0006c..fb17f0e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSnackbarController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSnackbarController.java
@@ -6,6 +6,7 @@ import android.app.Activity; import android.content.Context; +import android.util.Pair; import org.chromium.base.ApplicationStatus; import org.chromium.chrome.R; @@ -25,10 +26,12 @@ } @Override + @SuppressWarnings("unchecked") public void onAction(Object actionData) { - Long downloadId = (Long) actionData; - DownloadManagerService.getDownloadManagerService(mContext).openDownloadedContent( - downloadId); + Pair<DownloadInfo, Long> download = (Pair<DownloadInfo, Long>) actionData; + DownloadManagerService manager = DownloadManagerService.getDownloadManagerService(mContext); + manager.openDownloadedContent(download.second); + manager.removeProgressNotificationForDownload(download.first.getDownloadId()); } @Override @@ -56,7 +59,7 @@ if (canBeResolved) { snackbar.setAction( mContext.getString(R.string.open_downloaded_label), - downloadId); + Pair.create(downloadInfo, downloadId)); } getSnackbarManager().showSnackbar(snackbar); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java b/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java index 2430d2d..980d3537 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java
@@ -6,7 +6,9 @@ import android.app.Notification; import android.app.NotificationManager; +import android.app.PendingIntent; import android.content.Context; +import android.content.Intent; import android.support.v4.app.NotificationCompat; import org.chromium.chrome.R; @@ -53,14 +55,23 @@ } @Override - public void notifyDownloadSuccessful(DownloadInfo downloadInfo) { - // TODO(qinmin): figure out what needs to be done here. + public void notifyDownloadSuccessful(DownloadInfo downloadInfo, Intent intent) { + NotificationCompat.Builder builder = new NotificationCompat.Builder(mApplicationContext) + .setContentTitle(downloadInfo.getFileName()) + .setSmallIcon(android.R.drawable.stat_sys_download_done) + .setOngoing(false) + .setLocalOnly(true) + .setAutoCancel(true) + .setContentText(mApplicationContext.getResources().getString( + R.string.download_notification_completed)) + .setContentIntent(PendingIntent.getActivity( + mApplicationContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); + updateNotification(downloadInfo.getDownloadId(), builder.build()); } @Override public void notifyDownloadFailed(DownloadInfo downloadInfo) { - NotificationCompat.Builder builder = new NotificationCompat.Builder( - mApplicationContext) + NotificationCompat.Builder builder = new NotificationCompat.Builder(mApplicationContext) .setContentTitle(downloadInfo.getFileName()) .setSmallIcon(android.R.drawable.stat_sys_download_done) .setOngoing(false)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkPage.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkPage.java index 31fe999..f30da93 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkPage.java
@@ -27,6 +27,7 @@ private final Tab mTab; private final String mTitle; private final int mBackgroundColor; + private final int mThemeColor; private EnhancedBookmarkManager mManager; /** @@ -48,6 +49,8 @@ ? R.string.offline_pages_saved_pages : R.string.bookmarks); mBackgroundColor = ApiCompatibilityUtils.getColor(activity.getResources(), R.color.default_primary_color); + mThemeColor = ApiCompatibilityUtils.getColor( + activity.getResources(), R.color.default_primary_color); mManager = new EnhancedBookmarkManager(mActivity); Resources res = mActivity.getResources(); @@ -88,6 +91,11 @@ } @Override + public int getThemeColor() { + return mThemeColor; + } + + @Override public void updateForUrl(String url) { mManager.updateForUrl(url); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java index 9a3636c..fadf50d7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitializationActivity.java
@@ -89,7 +89,28 @@ } @Override - public void postInflationStartup() { } + public void postInflationStartup() { + final View firstDrawView = getViewToBeDrawnBeforeInitializingNative(); + assert firstDrawView != null; + ViewTreeObserver.OnPreDrawListener firstDrawListener = + new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + firstDrawView.getViewTreeObserver().removeOnPreDrawListener(this); + onFirstDrawComplete(); + return true; + } + }; + firstDrawView.getViewTreeObserver().addOnPreDrawListener(firstDrawListener); + } + + /** + * @return The primary view that must have completed at least one draw before initializing + * native. This must be non-null. + */ + protected View getViewToBeDrawnBeforeInitializingNative() { + return findViewById(android.R.id.content); + } @Override public void maybePreconnect() { @@ -271,11 +292,6 @@ } @Override - public boolean hasDoneFirstDraw() { - return true; - } - - @Override public void onNewIntentWithNative(Intent intent) { } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeActivityNativeDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeActivityNativeDelegate.java index 5a3e17e..db04082a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeActivityNativeDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeActivityNativeDelegate.java
@@ -46,11 +46,6 @@ boolean isActivityDestroyed(); /** - * @return Whether the activity linked to the delegate has done its first draw. - */ - boolean hasDoneFirstDraw(); - - /** * Called when the first draw for the UI specific to the linked activity is complete. */ void onFirstDrawComplete();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/NativeInitializationController.java b/chrome/android/java/src/org/chromium/chrome/browser/init/NativeInitializationController.java index d1866ed..f7beba74 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/NativeInitializationController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/NativeInitializationController.java
@@ -37,6 +37,7 @@ private List<Intent> mPendingNewIntents; private List<ActivityResult> mPendingActivityResults; private boolean mWaitingForFirstDraw; + private boolean mHasDoneFirstDraw; private boolean mInitializationComplete; /** @@ -109,7 +110,7 @@ } private void onLibraryLoaded() { - if (mActivityDelegate.hasDoneFirstDraw()) { + if (mHasDoneFirstDraw) { // First draw is done onNativeLibraryLoaded(); } else { @@ -122,6 +123,8 @@ * load has to be completed to start the chromium browser process. */ public void firstDrawComplete() { + mHasDoneFirstDraw = true; + if (mWaitingForFirstDraw) { mWaitingForFirstDraw = false; // Allow the UI thread to continue its initialization
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/BookmarksPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/BookmarksPage.java index 22753ae8..d5296fc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/BookmarksPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/BookmarksPage.java
@@ -60,6 +60,7 @@ private final BookmarksPageView mPageView; private final String mTitle; private final int mBackgroundColor; + private final int mThemeColor; // Whether destroy() has been called. private boolean mIsDestroyed; @@ -279,6 +280,8 @@ mFaviconHelper = new FaviconHelper(); mTitle = context.getResources().getString(R.string.ntp_bookmarks); mBackgroundColor = ApiCompatibilityUtils.getColor(context.getResources(), R.color.ntp_bg); + mThemeColor = ApiCompatibilityUtils.getColor( + context.getResources(), R.color.default_primary_color); mCurrentFolderId = new BookmarkId(BookmarkId.INVALID_FOLDER_ID, BookmarkType.NORMAL); mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); @@ -535,6 +538,11 @@ } @Override + public int getThemeColor() { + return mThemeColor; + } + + @Override public View getView() { return mPageView; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java index 63697888..763afdc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java
@@ -27,6 +27,7 @@ private final String mTitle; private final int mBackgroundColor; + private final int mThemeColor; private final IncognitoNewTabPageView mIncognitoNewTabPageView; private boolean mIsLoaded; @@ -56,6 +57,8 @@ mTitle = activity.getResources().getString(R.string.button_new_tab); mBackgroundColor = ApiCompatibilityUtils.getColor(activity.getResources(), R.color.ntp_bg_incognito); + mThemeColor = ApiCompatibilityUtils.getColor(activity.getResources(), + R.color.incognito_primary_color); LayoutInflater inflater = LayoutInflater.from(activity); mIncognitoNewTabPageView = @@ -94,6 +97,11 @@ } @Override + public int getThemeColor() { + return mThemeColor; + } + + @Override public View getView() { return mIncognitoNewTabPageView; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java index da16622c..5d7db9bd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
@@ -9,6 +9,7 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Rect; import android.view.ContextMenu; import android.view.LayoutInflater; @@ -87,6 +88,7 @@ private final Profile mProfile; private final String mTitle; private final int mBackgroundColor; + private final int mThemeColor; private final NewTabPageView mNewTabPageView; private MostVisitedSites mMostVisitedSites; @@ -424,6 +426,8 @@ mTitle = activity.getResources().getString(R.string.button_new_tab); mBackgroundColor = ApiCompatibilityUtils.getColor(activity.getResources(), R.color.ntp_bg); + mThemeColor = ApiCompatibilityUtils.getColor( + activity.getResources(), R.color.default_primary_color); TemplateUrlService.getInstance().addObserver(this); // Whether to show the promo can change within the lifetime of a single NTP instance @@ -599,6 +603,11 @@ } @Override + public int getThemeColor() { + return isLocationBarShownInNTP() ? Color.WHITE : mThemeColor; + } + + @Override public View getView() { return mNewTabPageView; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPage.java index e0df36aa..75b3b99 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPage.java
@@ -16,6 +16,7 @@ import android.widget.ExpandableListView; import org.chromium.base.ActivityState; +import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ApplicationStatus; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; @@ -52,6 +53,8 @@ private int mSnapshotWidth; private int mSnapshotHeight; + private final int mThemeColor; + /** * Whether the page is in the foreground and is visible. */ @@ -80,6 +83,8 @@ mRecentTabsManager = recentTabsManager; mTitle = activity.getResources().getString(R.string.recent_tabs); + mThemeColor = ApiCompatibilityUtils.getColor( + activity.getResources(), R.color.default_primary_color); mRecentTabsManager.setUpdatedCallback(this); LayoutInflater inflater = LayoutInflater.from(activity); mView = (ViewGroup) inflater.inflate(R.layout.recent_tabs_page, null); @@ -144,6 +149,11 @@ } @Override + public int getThemeColor() { + return mThemeColor; + } + + @Override public View getView() { return mView; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java index 5967116..2f654a0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -736,7 +736,9 @@ color = mDefaultThemeColor; } if (color == Color.TRANSPARENT) color = mDefaultThemeColor; + if (isIncognito()) color = mDefaultThemeColor; color |= 0xFF000000; + if (mThemeColor == color) return; mThemeColor = color; for (TabObserver observer : mObservers) { @@ -1156,6 +1158,7 @@ * security state. */ public int getThemeColor() { + if (isNativePage()) return mNativePage.getThemeColor(); return mThemeColor; } @@ -2858,10 +2861,10 @@ } /** - * @return The default toolbar color for this tab. + * @return Whether the theme color for this tab is the default color. */ - public int getDefaultThemeColor() { - return mDefaultThemeColor; + public boolean isDefaultThemeColor() { + return mDefaultThemeColor == mThemeColor; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/ThumbnailTabHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/ThumbnailTabHelper.java index 440776c2..2a50fce 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/ThumbnailTabHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/ThumbnailTabHelper.java
@@ -5,21 +5,13 @@ package org.chromium.chrome.browser.tab; import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.Bitmap.Config; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Rect; import android.os.Handler; import android.text.TextUtils; -import android.util.Log; +import org.chromium.base.annotations.CalledByNative; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.UrlConstants; -import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.util.MathUtils; -import org.chromium.content.browser.ContentReadbackHandler; import org.chromium.content.browser.ContentViewCore; import org.chromium.content_public.browser.GestureStateListener; import org.chromium.content_public.browser.WebContents; @@ -39,13 +31,14 @@ private final Tab mTab; private final Handler mHandler; - private final int mThumbnailWidth; - private final int mThumbnailHeight; + private final int mThumbnailWidthDp; + private final int mThumbnailHeightDp; private ContentViewCore mContentViewCore; private boolean mThumbnailCapturedForLoad; private boolean mIsRenderViewHostReady; private boolean mWasRenderViewHostReady; + private String mRequestedUrl; private final Runnable mThumbnailRunnable = new Runnable() { @Override @@ -61,33 +54,11 @@ mThumbnailCapturedForLoad = !mTab.isHidden(); return; } - if (!shouldUpdateThumbnail()) return; + if (mTab.getWebContents() == null) return; - int snapshotWidth = Math.min(mTab.getWidth(), mThumbnailWidth); - int snapshotHeight = Math.min(mTab.getHeight(), mThumbnailHeight); - - ContentReadbackHandler readbackHandler = getActivity().getContentReadbackHandler(); - if (readbackHandler == null || mTab.getContentViewCore() == null) return; - final String requestedUrl = mTab.getUrl(); - ContentReadbackHandler.GetBitmapCallback bitmapCallback = - new ContentReadbackHandler.GetBitmapCallback() { - @Override - public void onFinishGetBitmap(Bitmap bitmap, int response) { - // Ensure that the URLs match for the requested page, and ensure - // that the page is still valid for thumbnail capturing (i.e. - // not showing an error page). - if (bitmap == null - || !TextUtils.equals(requestedUrl, mTab.getUrl()) - || !mThumbnailCapturedForLoad - || !canUpdateHistoryThumbnail()) { - return; - } - updateHistoryThumbnail(bitmap); - bitmap.recycle(); - } - }; - readbackHandler.getContentBitmapAsync(1, new Rect(0, 0, snapshotWidth, snapshotHeight), - mTab.getContentViewCore(), Bitmap.Config.ARGB_8888, bitmapCallback); + mRequestedUrl = mTab.getUrl(); + nativeCaptureThumbnail(ThumbnailTabHelper.this, mTab.getWebContents(), + mThumbnailWidthDp, mThumbnailHeightDp); } }; @@ -196,7 +167,7 @@ * @param tab The Tab whose thumbnails will be generated by this helper. */ public static void createForTab(Tab tab) { - new ThumbnailTabHelper(tab); + if (!tab.isIncognito()) new ThumbnailTabHelper(tab); } /** @@ -210,8 +181,11 @@ mHandler = new Handler(); Resources res = tab.getWindowAndroid().getApplicationContext().getResources(); - mThumbnailWidth = res.getDimensionPixelSize(R.dimen.most_visited_thumbnail_width); - mThumbnailHeight = res.getDimensionPixelSize(R.dimen.most_visited_thumbnail_height); + float density = res.getDisplayMetrics().density; + mThumbnailWidthDp = Math.round( + res.getDimension(R.dimen.most_visited_thumbnail_width) / density); + mThumbnailHeightDp = Math.round( + res.getDimension(R.dimen.most_visited_thumbnail_height) / density); onContentChanged(); } @@ -249,17 +223,6 @@ mHandler.postDelayed(mThumbnailRunnable, THUMBNAIL_CAPTURE_DELAY_MS); } - private boolean shouldUpdateThumbnail() { - return nativeShouldUpdateThumbnail(mTab.getProfile(), mTab.getUrl()); - } - - private void updateThumbnail(Bitmap bitmap) { - if (mTab.getContentViewCore() != null) { - final boolean atTop = mTab.getContentViewCore().computeVerticalScrollOffset() == 0; - nativeUpdateThumbnail(mTab.getWebContents(), bitmap, atTop); - } - } - private boolean canUpdateHistoryThumbnail() { String url = mTab.getUrl(); if (url.startsWith(UrlConstants.CHROME_SCHEME) @@ -276,52 +239,17 @@ && mTab.getHeight() > 0; } - private void updateHistoryThumbnail(Bitmap bitmap) { - if (mTab.isIncognito()) return; - - // TODO(yusufo): It will probably be faster and more efficient on resources to do this on - // the native side, but the thumbnail_generator code has to be refactored a bit to allow - // creating a downsized version of a bitmap progressively. - if (bitmap.getWidth() != mThumbnailWidth - || bitmap.getHeight() != mThumbnailHeight - || bitmap.getConfig() != Config.ARGB_8888) { - try { - int[] dim = new int[] { - bitmap.getWidth(), bitmap.getHeight() - }; - // If the thumbnail size is small compared to the bitmap size downsize in - // two stages. This makes the final quality better. - float scale = Math.max( - (float) mThumbnailWidth / dim[0], - (float) mThumbnailHeight / dim[1]); - int adjustedWidth = (scale < 1) - ? mThumbnailWidth * (int) (1 / Math.sqrt(scale)) : mThumbnailWidth; - int adjustedHeight = (scale < 1) - ? mThumbnailHeight * (int) (1 / Math.sqrt(scale)) : mThumbnailHeight; - scale = MathUtils.scaleToFitTargetSize(dim, adjustedWidth, adjustedHeight); - // Horizontally center the source bitmap in the final result. - float leftOffset = (adjustedWidth - dim[0]) / 2.0f / scale; - Bitmap tmpBitmap = Bitmap.createBitmap(adjustedWidth, - adjustedHeight, Config.ARGB_8888); - Canvas c = new Canvas(tmpBitmap); - c.scale(scale, scale); - c.drawBitmap(bitmap, leftOffset, 0, new Paint(Paint.FILTER_BITMAP_FLAG)); - if (scale < 1) { - tmpBitmap = Bitmap.createScaledBitmap(tmpBitmap, - mThumbnailWidth, mThumbnailHeight, true); - } - updateThumbnail(tmpBitmap); - tmpBitmap.recycle(); - } catch (OutOfMemoryError ex) { - Log.w(TAG, "OutOfMemoryError while updating the history thumbnail."); - } - } else { - updateThumbnail(bitmap); - } + @CalledByNative + private boolean shouldSaveCapturedThumbnail() { + // Ensure that the URLs match for the requested page, and ensure + // that the page is still valid for thumbnail capturing (i.e. + // not showing an error page). + return TextUtils.equals(mRequestedUrl, mTab.getUrl()) + && mThumbnailCapturedForLoad + && canUpdateHistoryThumbnail(); } private static native void nativeInitThumbnailHelper(WebContents webContents); - private static native void nativeUpdateThumbnail( - WebContents webContents, Bitmap bitmap, boolean atTop); - private static native boolean nativeShouldUpdateThumbnail(Profile profile, String url); + private static native void nativeCaptureThumbnail(ThumbnailTabHelper thumbnailTabHelper, + WebContents webContents, int thumbnailWidthDp, int thumbnailHeightDp); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index 3c39970c..9b81813 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -861,13 +861,6 @@ } /** - * @return Whether {@link Toolbar} has drawn at least once. - */ - public boolean hasDoneFirstDraw() { - return mToolbar.getFirstDrawTime() != 0; - } - - /** * Handle all necessary tasks that can be delayed until initialization completes. * @param activityCreationTimeMs The time of creation for the activity this toolbar belongs to. * @param activityName Simple class name for the activity this toolbar belongs to.
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 201daecf..b5585a21 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -1433,6 +1433,9 @@ <message name="IDS_DOWNLOAD_NOTIFICATION_FAILED" desc="Download notification to be displayed when a download fails."> Download failed. </message> + <message name="IDS_DOWNLOAD_NOTIFICATION_COMPLETED" desc="Download notification to be displayed when a download completes."> + Download complete. + </message> <message name="IDS_DOWNLOAD_FAILED_MESSAGE" desc="Transient message shown when a file download has failed." meaning="Android"> <ph name="FILE_NAME">%1$s<ex>http://abc.com/test.pdf</ex></ph> download failed </message>
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java index aff355a..174b782f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -1948,10 +1948,13 @@ /** * Tests that long-press triggers the Peek Promo, and expanding the Panel dismisses it. + * + * Re-enable the test after fixing http://crbug.com/540820. + * @SmallTest + * @Feature({"ContextualSearch"}) */ - @SmallTest - @Feature({"ContextualSearch"}) @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE}) + @FlakyTest @CommandLineFlags.Add(ContextualSearchFieldTrial.PEEK_PROMO_ENABLED + "=true") public void testLongPressShowsPeekPromo() throws InterruptedException, TimeoutException { // Must be in undecided state in order to trigger the Peek Promo.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/crash/CrashFileManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/crash/CrashFileManagerTest.java index 6d90489..0a05dc4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/crash/CrashFileManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/crash/CrashFileManagerTest.java
@@ -4,12 +4,16 @@ package org.chromium.chrome.browser.crash; +import android.test.MoreAsserts; +import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; import org.chromium.base.annotations.SuppressFBWarnings; import org.chromium.base.test.util.Feature; import java.io.File; +import java.io.IOException; +import java.util.Arrays; import java.util.regex.Pattern; /** @@ -20,6 +24,7 @@ private File mTmpFile1; private File mTmpFile2; + private File mTmpFile3; private File mDmpFile1; private File mDmpFile2; @@ -39,6 +44,9 @@ mTmpFile2 = new File(mCrashDir, "abcde12345" + CrashFileManager.TMP_SUFFIX); mTmpFile2.createNewFile(); + mTmpFile3 = new File(mCrashDir, "abcdefghi" + CrashFileManager.TMP_SUFFIX); + mTmpFile3.createNewFile(); + mDmpFile1 = new File(mCrashDir, "123_abc.dmp0"); mDmpFile1.createNewFile(); @@ -72,25 +80,30 @@ Pattern testPattern = Pattern.compile("^123"); File[] actualFiles = crashFileManager.getMatchingFiles(testPattern); assertNotNull(actualFiles); - assertEquals(expectedFiles.length, actualFiles.length); - for (int i = 0; i < expectedFiles.length; i++) { - // Test to see if files are properly ordered. - assertEquals(expectedFiles[i], actualFiles[i]); - } + MoreAsserts.assertEquals("Failed to match file by pattern", expectedFiles, actualFiles); + } + + @MediumTest + @Feature({"Android-AppBase"}) + public void testFileComparator() throws IOException { + CrashFileManager crashFileManager = new CrashFileManager(mCacheDir); + File[] expectedFiles = new File[] {mTmpFile3, mTmpFile2, mTmpFile1}; + File[] originalFiles = new File[] {mTmpFile1, mTmpFile2, mTmpFile3}; + Arrays.sort(originalFiles, crashFileManager.sFileComparator); + assertNotNull(originalFiles); + MoreAsserts.assertEquals("File comparator failed to prioritize last modified file", + expectedFiles, originalFiles); } @SmallTest @Feature({"Android-AppBase"}) public void testGetAllMinidumpFilesSorted() { CrashFileManager crashFileManager = new CrashFileManager(mCacheDir); - File[] expectedFiles = new File[] {mDmpFile1, mDmpFile2}; + File[] expectedFiles = new File[] {mDmpFile2, mDmpFile1}; File[] actualFiles = crashFileManager.getAllMinidumpFilesSorted(); assertNotNull(actualFiles); - assertEquals(expectedFiles.length, actualFiles.length); - for (int i = 0; i < expectedFiles.length; i++) { - // Test to see if files are properly ordered. - assertEquals(expectedFiles[i], actualFiles[i]); - } + MoreAsserts.assertEquals("Failed to sort minidumps by modification time", expectedFiles, + actualFiles); } @SmallTest @@ -105,6 +118,7 @@ @SmallTest @Feature({"Android-AppBase"}) public void testDeleteFile() { + assertTrue(mTmpFile1.exists()); assertTrue(CrashFileManager.deleteFile(mTmpFile1)); assertFalse(mTmpFile1.exists()); } @@ -116,11 +130,8 @@ File[] expectedFiles = new File[] { mDmpFile1, mDmpFile2 }; File[] actualFiles = crashFileManager.getAllMinidumpFiles(); assertNotNull(actualFiles); - assertEquals(expectedFiles.length, actualFiles.length); - for (int i = 0; i < expectedFiles.length; i++) { - // Test to see if files are properly ordered. - assertEquals(expectedFiles[i], actualFiles[i]); - } + MoreAsserts.assertEquals("Failed to get the correct minidump files in directory", + expectedFiles, actualFiles); } @SmallTest @@ -130,11 +141,8 @@ File[] expectedFiles = new File[] { mUpFile1, mUpFile2 }; File[] actualFiles = crashFileManager.getAllUploadedFiles(); assertNotNull(actualFiles); - assertEquals(expectedFiles.length, actualFiles.length); - for (int i = 0; i < expectedFiles.length; i++) { - // Test to see if files are properly ordered. - assertEquals(expectedFiles[i], actualFiles[i]); - } + MoreAsserts.assertEquals("Failed to get the correct uploaded files in directory", + expectedFiles, actualFiles); } @SmallTest @@ -165,7 +173,7 @@ @SmallTest @Feature({"Android-AppBase"}) public void testCleanAllMiniDumps() { - assertEquals(6, mCrashDir.listFiles().length); + assertEquals(7, mCrashDir.listFiles().length); CrashFileManager crashFileManager = new CrashFileManager(mCacheDir); crashFileManager.cleanAllMiniDumps();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadManagerServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadManagerServiceTest.java index 62e5d5f..debc6cb 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadManagerServiceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadManagerServiceTest.java
@@ -6,6 +6,7 @@ import android.app.DownloadManager; import android.content.Context; +import android.content.Intent; import android.os.Handler; import android.os.HandlerThread; import android.test.InstrumentationTestCase; @@ -101,7 +102,7 @@ } @Override - public void notifyDownloadSuccessful(DownloadInfo downloadInfo) { + public void notifyDownloadSuccessful(DownloadInfo downloadInfo, Intent intent) { assertCorrectExpectedCall(MethodID.DOWNLOAD_SUCCESSFUL, downloadInfo); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NativePageFactoryTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NativePageFactoryTest.java index b1aabdd9..0f1ed39 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NativePageFactoryTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NativePageFactoryTest.java
@@ -68,6 +68,11 @@ } @Override + public int getThemeColor() { + return 0; + } + + @Override public View getView() { return null; }
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index a5c37e7..f1ad048 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -279,6 +279,37 @@ ] } +# GYP version: chrome/settings_chromium_strings.gyp:settings_chromium_strings +# (generate_settings_chromium_strings action) +grit("settings_chromium_strings") { + source = "settings_chromium_strings.grd" + output_dir = "$root_gen_dir/chrome" + use_qualified_include = true + outputs = [ + "grit/settings_chromium_strings.h", + + # These strings are not being treated as strings because they are + # not translated (English only), this should change in late 2015. + "settings_chromium_strings.pak", + ] +} + +# GYP version: +# chrome/settings_google_chrome_strings.gyp:settings_google_chrome_strings +# (generate_settings_google_chrome_strings action) +grit("settings_google_chrome_strings") { + source = "settings_google_chrome_strings.grd" + output_dir = "$root_gen_dir/chrome" + use_qualified_include = true + outputs = [ + "grit/settings_google_chrome_strings.h", + + # These strings are not being treated as strings because they are + # not translated (English only), this should change in late 2015. + "settings_google_chrome_strings.pak", + ] +} + source_set("test_support") { testonly = true visibility = [ "//chrome/test:test_support" ]
diff --git a/chrome/app/chrome_watcher_client_unittest_win.cc b/chrome/app/chrome_watcher_client_unittest_win.cc index 20d1d32..e3549e9 100644 --- a/chrome/app/chrome_watcher_client_unittest_win.cc +++ b/chrome/app/chrome_watcher_client_unittest_win.cc
@@ -6,6 +6,7 @@ #include <windows.h> #include <string> + #include "base/base_switches.h" #include "base/bind.h" #include "base/command_line.h"
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index 3b66d29c..8fbedbd 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -133,9 +133,6 @@ </translations> <release seq="1" allow_pseudo="false"> <messages fallback_to_english="true"> - <!-- Settings specific strings --> - <part file="settings_chromium_strings.grdp" /> - <message name="IDS_PROFILES_DISCONNECT_MANAGED_PROFILE_TEXT" desc="Message explaining to the user what will happen if they disconnect the managed profile."> Disconnecting <ph name="USERNAME">$1<ex>someone@example.com</ex></ph> will clear your history, bookmarks, settings, and other Chromium data stored on this device. Data stored in your Google Account will not be cleared and can be managed on <ph name="GOOGLE_DASHBOARD_LINK"><a target="_blank" href="$2"></ph>Google Dashboard<ph name="END_GOOGLE_DASHBOARD_LINK"></a></ph>. </message>
diff --git a/chrome/app/client_util.cc b/chrome/app/client_util.cc index 4a156a7..f169bfd 100644 --- a/chrome/app/client_util.cc +++ b/chrome/app/client_util.cc
@@ -6,6 +6,7 @@ #include <shlwapi.h> #include "base/base_paths.h" +#include "base/base_switches.h" #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/environment.h"
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index 1ad02c31d..77d6aea 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd
@@ -135,9 +135,6 @@ </translations> <release seq="1" allow_pseudo="false"> <messages fallback_to_english="true"> - <!-- Settings specific strings --> - <part file="settings_google_chrome_strings.grdp" /> - <message name="IDS_PROFILES_DISCONNECT_MANAGED_PROFILE_TEXT" desc="Message explaining to the user what will happen if they disconnect the managed profile."> Disconnecting <ph name="USERNAME">$1<ex>someone@example.com</ex></ph> will clear your history, bookmarks, settings, and other Chrome data stored on this device. Data stored in your Google Account will not be cleared and can be managed on <ph name="GOOGLE_DASHBOARD_LINK"><a target="_blank" href="$2"></ph>Google Dashboard<ph name="END_GOOGLE_DASHBOARD_LINK"></a></ph>. </message>
diff --git a/chrome/app/settings_chromium_strings.grd b/chrome/app/settings_chromium_strings.grd new file mode 100644 index 0000000..df8a8f5 --- /dev/null +++ b/chrome/app/settings_chromium_strings.grd
@@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +This file contains the Material Design settings strings. +While under development, it is set to not be translated, +in translation_expectations.pyl. +Once the Material Design settings is further along, these +strings will begin to be translated. +--> +<grit base_dir="." latest_public_release="0" current_release="1" + source_lang_id="en" enc_check="möl"> + <outputs> + <output filename="grit/settings_chromium_strings.h" type="rc_header"> + <emit emit_type='prepend'></emit> + </output> + <output filename="settings_chromium_strings.pak" type="data_package"/> + </outputs> + + <release seq="1" allow_pseudo="false"> + <messages fallback_to_english="true"> + + <!-- Settings specific strings --> + <part file="settings_chromium_strings.grdp" /> + + </messages> + </release> +</grit>
diff --git a/chrome/app/settings_chromium_strings.grdp b/chrome/app/settings_chromium_strings.grdp index beb31be..7c58c0a 100644 --- a/chrome/app/settings_chromium_strings.grdp +++ b/chrome/app/settings_chromium_strings.grdp
@@ -1,6 +1,25 @@ <?xml version="1.0" encoding="utf-8"?> <!-- Settings-specific Chromium strings (included from chromium_strings.grd). --> <grit-part> + <!-- Default Browser Page --> + <if expr="not chromeos"> + <message name="IDS_SETTINGS_DEFAULT_BROWSER_DEFAULT" desc="The text displayed when Chrome is not the default browser"> + The default browser is currently Chromium. + </message> + <message name="IDS_SETTINGS_DEFAULT_BROWSER_NOT_DEFAULT" desc="The text displayed when Chrome is not the default browser"> + Chromium is not currently your default browser. + </message> + <message name="IDS_SETTINGS_DEFAULT_BROWSER_MAKE_DEFAULT" desc="Default browser checkbox label"> + Make Chromium the default browser + </message> + <message name="IDS_SETTINGS_DEFAULT_BROWSER_UNKNOWN" desc="The text displayed when Chrome cannot determine or set the default browser"> + Chromium cannot determine or set the default browser. + </message> + <message name="IDS_SETTINGS_DEFAULT_BROWSER_SECONDARY" desc="The text displayed when Chrome is installed in side-by-side mode, which does not support setting as the default browser."> + This is a secondary installation of Chromium, and cannot be made your default browser. + </message> + </if> + <!-- Privacy Page --> <message name="IDS_SETTINGS_IMPROVE_BROWSING_EXPERIENCE" desc="The text in the options panel that describes how we use web services to improve browsing experience."> Chromium may use <ph name="BEGIN_LINK"><a target="_blank" href="$1"></ph>web services<ph name="END_LINK"></a><ex></a></ex></ph> to improve your browsing experience. You may optionally disable these services at any time.
diff --git a/chrome/app/settings_google_chrome_strings.grd b/chrome/app/settings_google_chrome_strings.grd new file mode 100644 index 0000000..68c71e2 --- /dev/null +++ b/chrome/app/settings_google_chrome_strings.grd
@@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +This file contains the Material Design settings strings. +While under development, it is set to not be translated, +in translation_expectations.pyl. +Once the Material Design settings is further along, these +strings will begin to be translated. +--> +<grit base_dir="." latest_public_release="0" current_release="1" + source_lang_id="en" enc_check="möl"> + <outputs> + <output filename="grit/settings_google_chrome_strings.h" type="rc_header"> + <emit emit_type='prepend'></emit> + </output> + <output filename="settings_google_chrome_strings.pak" type="data_package"/> + </outputs> + + <release seq="1" allow_pseudo="false"> + <messages fallback_to_english="true"> + + <!-- Settings specific strings --> + <part file="settings_google_chrome_strings.grdp" /> + + </messages> + </release> +</grit>
diff --git a/chrome/app/settings_google_chrome_strings.grdp b/chrome/app/settings_google_chrome_strings.grdp index 772f056f..29c00e6 100644 --- a/chrome/app/settings_google_chrome_strings.grdp +++ b/chrome/app/settings_google_chrome_strings.grdp
@@ -1,6 +1,25 @@ <?xml version="1.0" encoding="utf-8"?> <!-- Settings-specific Google Chrome strings (included from google_chrome_strings.grd). --> <grit-part> + <!-- Default Browser Page --> + <if expr="not chromeos"> + <message name="IDS_SETTINGS_DEFAULT_BROWSER_DEFAULT" desc="The text displayed when Chrome is not the default browser"> + The default browser is currently Google Chrome. + </message> + <message name="IDS_SETTINGS_DEFAULT_BROWSER_NOT_DEFAULT" desc="The text displayed when Chrome is not the default browser"> + Google Chrome is not currently your default browser. + </message> + <message name="IDS_SETTINGS_DEFAULT_BROWSER_MAKE_DEFAULT" desc="Default browser checkbox label"> + Make Google Chrome the default browser + </message> + <message name="IDS_SETTINGS_DEFAULT_BROWSER_UNKNOWN" desc="The text displayed when Chrome cannot determine or set the default browser"> + Google Chrome cannot determine or set the default browser. + </message> + <message name="IDS_SETTINGS_DEFAULT_BROWSER_SECONDARY" desc="The text displayed when Chrome is installed in side-by-side mode, which does not support setting as the default browser."> + This is a secondary installation of Google Chrome, and cannot be made your default browser. + </message> + </if> + <!-- Privacy Page --> <message name="IDS_SETTINGS_IMPROVE_BROWSING_EXPERIENCE" desc="The text in the options panel that describes how we use web services to improve browsing experience."> Google Chrome may use <ph name="BEGIN_LINK"><a target="_blank" href="$1"></ph>web services<ph name="END_LINK"></a><ex></a></ex></ph> to improve your browsing experience. You may optionally disable these services at any time.
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index be08601..582e662 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -104,6 +104,13 @@ Basic </message> + <!-- Default Browser Page --> + <if expr="not chromeos"> + <message name="IDS_SETTINGS_DEFAULT_BROWSER" desc="Name of the Default Browser page, which allows users to set which browser will open .html files within the OS."> + Default browser + </message> + </if> + <!-- Certificate Manager Page --> <message name="IDS_SETTINGS_CERTIFICATE_MANAGER" desc="Name of the certificate manager page which allows users to modify SSL certificate settings."> Certificate manager
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index bc10356..17e91d6 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd
@@ -323,19 +323,19 @@ <if expr="not is_android and not is_ios"> <!-- TODO(estade): replace with vector image when one's available. --> <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_MENU_INCOGNITO" file="common/incognito.png" /> - <if expr="is_macosx"> - <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_ACCOUNT_BUTTON_ERROR" file="legacy/avatar_menu_auth_error.png" /> - <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_AVATAR_BUTTON_ERROR" file="legacy/avatar_button_auth_error.png" /> - <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_EDIT_CAMERA" file="legacy/edit_camera.png" /> - <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_EDIT_HOVER" file="legacy/edit_button_hover.png" /> - <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_EDIT_PRESSED" file="legacy/edit_button_pressed.png" /> - <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_LEGACY_SUPERVISED" file="legacy/icon_legacy_supervised.png" /> - <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_MENU_AVATAR" file="legacy/avatar_menu_profile.png" /> - <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_MENU_CHILD" file="legacy/avatar_menu_child.png" /> - <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_MENU_DISCONNECT" file="legacy/avatar_menu_disconnect.png" /> - <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_MENU_LEGACY_SUPERVISED" file="legacy/avatar_menu_legacy_supervised.png" /> - <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_MENU_LOCK" file="legacy/avatar_menu_lock.png" /> - </if> + </if> + <if expr="is_macosx"> + <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_ACCOUNT_BUTTON_ERROR" file="legacy/avatar_menu_auth_error.png" /> + <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_AVATAR_BUTTON_ERROR" file="legacy/avatar_button_auth_error.png" /> + <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_EDIT_CAMERA" file="legacy/edit_camera.png" /> + <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_EDIT_HOVER" file="legacy/edit_button_hover.png" /> + <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_EDIT_PRESSED" file="legacy/edit_button_pressed.png" /> + <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_LEGACY_SUPERVISED" file="legacy/icon_legacy_supervised.png" /> + <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_MENU_AVATAR" file="legacy/avatar_menu_profile.png" /> + <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_MENU_CHILD" file="legacy/avatar_menu_child.png" /> + <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_MENU_DISCONNECT" file="legacy/avatar_menu_disconnect.png" /> + <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_MENU_LEGACY_SUPERVISED" file="legacy/avatar_menu_legacy_supervised.png" /> + <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_MENU_LOCK" file="legacy/avatar_menu_lock.png" /> </if> <if expr="not is_android and not is_ios and not chromeos"> <!-- User Manager tutorial --> @@ -387,17 +387,6 @@ <structure type="chrome_scaled_image" name="IDR_INFOBAR_AUTOLOGIN" file="common/infobar_autologin.png" /> </if> <structure type="chrome_scaled_image" name="IDR_INFOBAR_COOKIE" file="common/infobar_cookie.png" /> - <if expr="is_android"> - <!-- The actual image here is not used; this line only exists to - reserve a valid ID, so the Android code can map it to the - appropriate Android resource. So we just refer to a random - image. --> - <structure type="chrome_scaled_image" name="IDR_INFOBAR_DESKTOP_NOTIFICATIONS" file="chromium/product_logo_32.png" /> - <structure type="chrome_scaled_image" name="IDR_INFOBAR_FROZEN_TAB" file="chromium/product_logo_32.png" /> - <structure type="chrome_scaled_image" name="IDR_INFOBAR_FULLSCREEN" file="chromium/product_logo_32.png" /> - <structure type="chrome_scaled_image" name="IDR_INFOBAR_GEOLOCATION" file="chromium/product_logo_32.png" /> - <structure type="chrome_scaled_image" name="IDR_INFOBAR_PROTECTED_MEDIA_IDENTIFIER" file="chromium/product_logo_32.png" /> - </if> <if expr="is_macosx"> <structure type="chrome_scaled_image" name="IDR_INFOBAR_DESKTOP_NOTIFICATIONS" file="legacy/infobar_desktop_notifications.png" /> <structure type="chrome_scaled_image" name="IDR_INFOBAR_GEOLOCATION" file="legacy/infobar_geolocation.png" />
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 867e6d8d..783d064b 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1080,6 +1080,12 @@ if (is_android) { sources -= [ + "download/test_download_shelf.cc", + "download/test_download_shelf.h", + "profile_resetter/profile_resetter_test_base.cc", + "profile_resetter/profile_resetter_test_base.h", + "sessions/session_restore_test_helper.cc", + "sessions/session_restore_test_helper.h", "sessions/session_service_test_helper.cc", "sessions/session_service_test_helper.h", ]
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index d21c7d4..63237e4 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -26,6 +26,7 @@ #include "chrome/grit/google_chrome_strings.h" #include "components/autofill/core/common/autofill_switches.h" #include "components/cloud_devices/common/cloud_devices_switches.h" +#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h" #include "components/dom_distiller/core/dom_distiller_switches.h" #include "components/enhanced_bookmarks/enhanced_bookmark_switches.h" #include "components/flags_ui/flags_storage.h" @@ -33,9 +34,11 @@ #include "components/nacl/common/nacl_switches.h" #include "components/offline_pages/offline_page_switches.h" #include "components/omnibox/browser/omnibox_switches.h" +#include "components/password_manager/core/common/password_manager_switches.h" #include "components/plugins/common/plugins_switches.h" #include "components/proximity_auth/switches.h" #include "components/search/search_switches.h" +#include "components/signin/core/common/signin_switches.h" #include "components/sync_driver/sync_driver_switches.h" #include "components/tracing/tracing_switches.h" #include "components/version_info/version_info.h"
diff --git a/chrome/browser/android/android_theme_resources.h b/chrome/browser/android/android_theme_resources.h new file mode 100644 index 0000000..34599b05 --- /dev/null +++ b/chrome/browser/android/android_theme_resources.h
@@ -0,0 +1,23 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ANDROID_ANDROID_THEME_RESOURCES_H_ +#define CHROME_BROWSER_ANDROID_ANDROID_THEME_RESOURCES_H_ + +// LINK_RESOURCE_ID will use an ID defined by grit, so no-op. +#define LINK_RESOURCE_ID(c_id, java_id) +// For DECLARE_RESOURCE_ID, make an entry in an enum. +#define DECLARE_RESOURCE_ID(c_id, java_id) c_id, + +enum { + // Not used; just provides a starting value for the enum. These must + // not conflict with IDR_* values, which top out at 2^16 - 1. + ANDROID_RESOURCE_ID_NONE = 1 << 16, +#include "chrome/browser/android/resource_id.h" +}; + +#undef LINK_RESOURCE_ID +#undef DECLARE_RESOURCE_ID + +#endif // CHROME_BROWSER_ANDROID_ANDROID_THEME_RESOURCES_H_
diff --git a/chrome/browser/android/fullscreen/fullscreen_infobar_delegate.cc b/chrome/browser/android/fullscreen/fullscreen_infobar_delegate.cc index a202c776..cf96e89 100644 --- a/chrome/browser/android/fullscreen/fullscreen_infobar_delegate.cc +++ b/chrome/browser/android/fullscreen/fullscreen_infobar_delegate.cc
@@ -7,6 +7,7 @@ #include "base/android/jni_string.h" #include "base/memory/scoped_ptr.h" #include "base/prefs/pref_service.h" +#include "chrome/browser/android/android_theme_resources.h" #include "chrome/browser/android/tab_android.h" #include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/profiles/profile_manager.h" @@ -15,7 +16,6 @@ #include "components/infobars/core/infobar.h" #include "components/url_formatter/elide_url.h" #include "grit/components_strings.h" -#include "grit/theme_resources.h" #include "jni/FullscreenInfoBarDelegate_jni.h" #include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" @@ -60,7 +60,7 @@ } int FullscreenInfoBarDelegate::GetIconId() const { - return IDR_INFOBAR_FULLSCREEN; + return IDR_ANDROID_INFOBAR_FULLSCREEN; } base::string16 FullscreenInfoBarDelegate::GetMessageText() const {
diff --git a/chrome/browser/android/hung_renderer_infobar_delegate.cc b/chrome/browser/android/hung_renderer_infobar_delegate.cc index 40473a9..7b35b1c9 100644 --- a/chrome/browser/android/hung_renderer_infobar_delegate.cc +++ b/chrome/browser/android/hung_renderer_infobar_delegate.cc
@@ -6,12 +6,12 @@ #include "base/callback.h" #include "base/metrics/histogram.h" +#include "chrome/browser/android/android_theme_resources.h" #include "chrome/browser/infobars/infobar_service.h" #include "chrome/grit/generated_resources.h" #include "components/infobars/core/infobar.h" #include "content/public/browser/render_process_host.h" #include "content/public/common/result_codes.h" -#include "grit/theme_resources.h" #include "ui/base/l10n/l10n_util.h" // static @@ -48,7 +48,7 @@ } int HungRendererInfoBarDelegate::GetIconId() const { - return IDR_INFOBAR_FROZEN_TAB; + return IDR_ANDROID_INFOBAR_FROZEN_TAB; } base::string16 HungRendererInfoBarDelegate::GetMessageText() const {
diff --git a/chrome/browser/android/resource_id.h b/chrome/browser/android/resource_id.h index 68c5e466..e6dfd66 100644 --- a/chrome/browser/android/resource_id.h +++ b/chrome/browser/android/resource_id.h
@@ -2,69 +2,71 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_ANDROID_RESOURCE_ID_H_ -#define CHROME_BROWSER_ANDROID_RESOURCE_ID_H_ - // This file maps Chromium resource IDs to Android resource IDs. -#ifndef DEFINE_RESOURCE_ID -#error "DEFINE_RESOURCE_ID should be defined before including this file" + +// LINK_RESOURCE_ID is used for IDs that come from a .grd file. +#ifndef LINK_RESOURCE_ID +#error "LINK_RESOURCE_ID should be defined before including this file" +#endif +// DECLARE_RESOURCE_ID is used for IDs that don't have .grd entries, and +// are only declared in this file. +#ifndef DECLARE_RESOURCE_ID +#error "DECLARE_RESOURCE_ID should be defined before including this file" #endif // Create a mapping that identifies when a resource isn't being passed in. -DEFINE_RESOURCE_ID(0, 0) +LINK_RESOURCE_ID(0, 0) // InfoBar resources. -DEFINE_RESOURCE_ID(IDR_INFOBAR_AUTOFILL_CC, R.drawable.infobar_autofill_cc) -DEFINE_RESOURCE_ID(IDR_INFOBAR_DESKTOP_NOTIFICATIONS,\ - R.drawable.infobar_desktop_notifications) -DEFINE_RESOURCE_ID(IDR_INFOBAR_GEOLOCATION, R.drawable.infobar_geolocation) -DEFINE_RESOURCE_ID(IDR_INFOBAR_MEDIA_STREAM_CAMERA, R.drawable.infobar_camera) -DEFINE_RESOURCE_ID(IDR_INFOBAR_MEDIA_STREAM_MIC, R.drawable.infobar_microphone) -DEFINE_RESOURCE_ID(IDR_INFOBAR_MIDI, R.drawable.infobar_midi) -DEFINE_RESOURCE_ID(IDR_INFOBAR_MULTIPLE_DOWNLOADS,\ - R.drawable.infobar_multiple_downloads) -DEFINE_RESOURCE_ID(IDR_INFOBAR_PROTECTED_MEDIA_IDENTIFIER, - R.drawable.infobar_protected_media_identifier) -DEFINE_RESOURCE_ID(IDR_INFOBAR_SAVE_PASSWORD,\ - R.drawable.infobar_savepassword) -DEFINE_RESOURCE_ID(IDR_INFOBAR_WARNING, R.drawable.infobar_warning) -DEFINE_RESOURCE_ID(IDR_INFOBAR_TRANSLATE, R.drawable.infobar_translate) -DEFINE_RESOURCE_ID(IDR_BLOCKED_POPUPS, R.drawable.infobar_blocked_popups) -DEFINE_RESOURCE_ID(IDR_INFOBAR_FROZEN_TAB, R.drawable.infobar_restore) -DEFINE_RESOURCE_ID(IDR_INFOBAR_FULLSCREEN, R.drawable.infobar_fullscreen) +LINK_RESOURCE_ID(IDR_INFOBAR_AUTOFILL_CC, R.drawable.infobar_autofill_cc) +LINK_RESOURCE_ID(IDR_INFOBAR_MEDIA_STREAM_CAMERA, R.drawable.infobar_camera) +LINK_RESOURCE_ID(IDR_INFOBAR_MEDIA_STREAM_MIC, R.drawable.infobar_microphone) +LINK_RESOURCE_ID(IDR_INFOBAR_MIDI, R.drawable.infobar_midi) +LINK_RESOURCE_ID(IDR_INFOBAR_MULTIPLE_DOWNLOADS, + R.drawable.infobar_multiple_downloads) +LINK_RESOURCE_ID(IDR_INFOBAR_SAVE_PASSWORD, R.drawable.infobar_savepassword) +LINK_RESOURCE_ID(IDR_INFOBAR_WARNING, R.drawable.infobar_warning) +LINK_RESOURCE_ID(IDR_INFOBAR_TRANSLATE, R.drawable.infobar_translate) +LINK_RESOURCE_ID(IDR_BLOCKED_POPUPS, R.drawable.infobar_blocked_popups) + +// Android only infobars. +DECLARE_RESOURCE_ID(IDR_ANDROID_INFOBAR_PROTECTED_MEDIA_IDENTIFIER, + R.drawable.infobar_protected_media_identifier) +DECLARE_RESOURCE_ID(IDR_ANDROID_INFOBAR_NOTIFICATIONS, + R.drawable.infobar_desktop_notifications) +DECLARE_RESOURCE_ID(IDR_ANDROID_INFOBAR_GEOLOCATION, + R.drawable.infobar_geolocation) +DECLARE_RESOURCE_ID(IDR_ANDROID_INFOBAR_FROZEN_TAB, R.drawable.infobar_restore) +DECLARE_RESOURCE_ID(IDR_ANDROID_INFOBAR_FULLSCREEN, + R.drawable.infobar_fullscreen) // WebsiteSettingsUI images, used in ConnectionInfoPopup // Good: -DEFINE_RESOURCE_ID(IDR_PAGEINFO_GOOD, R.drawable.pageinfo_good) +LINK_RESOURCE_ID(IDR_PAGEINFO_GOOD, R.drawable.pageinfo_good) // Warnings: -DEFINE_RESOURCE_ID(IDR_PAGEINFO_WARNING_MINOR,\ - R.drawable.pageinfo_warning) +LINK_RESOURCE_ID(IDR_PAGEINFO_WARNING_MINOR, R.drawable.pageinfo_warning) // Bad: -DEFINE_RESOURCE_ID(IDR_PAGEINFO_BAD, R.drawable.pageinfo_bad) +LINK_RESOURCE_ID(IDR_PAGEINFO_BAD, R.drawable.pageinfo_bad) // Should never occur, use warning just in case: // Enterprise managed: ChromeOS only. -DEFINE_RESOURCE_ID(IDR_PAGEINFO_ENTERPRISE_MANAGED,\ - R.drawable.pageinfo_warning) +LINK_RESOURCE_ID(IDR_PAGEINFO_ENTERPRISE_MANAGED, R.drawable.pageinfo_warning) // Info: Only shown on chrome:// urls, which don't show the connection info // popup. -DEFINE_RESOURCE_ID(IDR_PAGEINFO_INFO, R.drawable.pageinfo_warning) +LINK_RESOURCE_ID(IDR_PAGEINFO_INFO, R.drawable.pageinfo_warning) // Major warning: Used on insecure pages, which don't show the connection info // popup. -DEFINE_RESOURCE_ID(IDR_PAGEINFO_WARNING_MAJOR,\ - R.drawable.pageinfo_warning) +LINK_RESOURCE_ID(IDR_PAGEINFO_WARNING_MAJOR, R.drawable.pageinfo_warning) // Autofill popup and keyboard accessory images. -DEFINE_RESOURCE_ID(IDR_AUTOFILL_CC_AMEX, R.drawable.amex_card) -DEFINE_RESOURCE_ID(IDR_AUTOFILL_CC_DISCOVER, R.drawable.discover_card) -DEFINE_RESOURCE_ID(IDR_AUTOFILL_CC_GENERIC, R.drawable.generic_card) -DEFINE_RESOURCE_ID(IDR_AUTOFILL_CC_MASTERCARD, R.drawable.mc_card) -DEFINE_RESOURCE_ID(IDR_AUTOFILL_CC_VISA, R.drawable.visa_card) -DEFINE_RESOURCE_ID(IDR_AUTOFILL_CC_SCAN_NEW, android.R.drawable.ic_menu_camera) -DEFINE_RESOURCE_ID(IDR_AUTOFILL_CC_SCAN_NEW_KEYBOARD_ACCESSORY, - org.chromium.chrome.R.drawable.ic_photo_camera) -DEFINE_RESOURCE_ID(IDR_CREDIT_CARD_CVC_HINT, R.drawable.cvc_icon) -DEFINE_RESOURCE_ID(IDR_CREDIT_CARD_CVC_HINT_AMEX, R.drawable.cvc_icon_amex) -DEFINE_RESOURCE_ID(IDR_AUTOFILL_SETTINGS, - org.chromium.chrome.R.drawable.ic_settings) - -#endif // CHROME_BROWSER_ANDROID_RESOURCE_ID_H_ +LINK_RESOURCE_ID(IDR_AUTOFILL_CC_AMEX, R.drawable.amex_card) +LINK_RESOURCE_ID(IDR_AUTOFILL_CC_DISCOVER, R.drawable.discover_card) +LINK_RESOURCE_ID(IDR_AUTOFILL_CC_GENERIC, R.drawable.generic_card) +LINK_RESOURCE_ID(IDR_AUTOFILL_CC_MASTERCARD, R.drawable.mc_card) +LINK_RESOURCE_ID(IDR_AUTOFILL_CC_VISA, R.drawable.visa_card) +LINK_RESOURCE_ID(IDR_AUTOFILL_CC_SCAN_NEW, android.R.drawable.ic_menu_camera) +LINK_RESOURCE_ID(IDR_AUTOFILL_CC_SCAN_NEW_KEYBOARD_ACCESSORY, + org.chromium.chrome.R.drawable.ic_photo_camera) +LINK_RESOURCE_ID(IDR_CREDIT_CARD_CVC_HINT, R.drawable.cvc_icon) +LINK_RESOURCE_ID(IDR_CREDIT_CARD_CVC_HINT_AMEX, R.drawable.cvc_icon_amex) +LINK_RESOURCE_ID(IDR_AUTOFILL_SETTINGS, + org.chromium.chrome.R.drawable.ic_settings)
diff --git a/chrome/browser/android/resource_mapper.cc b/chrome/browser/android/resource_mapper.cc index 545caf71..ed4e66e 100644 --- a/chrome/browser/android/resource_mapper.cc +++ b/chrome/browser/android/resource_mapper.cc
@@ -8,6 +8,7 @@ #include "base/lazy_instance.h" #include "base/logging.h" +#include "chrome/browser/android/android_theme_resources.h" #include "grit/components_scaled_resources.h" #include "grit/theme_resources.h" @@ -39,7 +40,9 @@ DCHECK(g_id_map.Get().empty()); int next_id = 0; -#define DEFINE_RESOURCE_ID(c_id,java_id) g_id_map.Get()[c_id] = next_id++; +#define LINK_RESOURCE_ID(c_id, java_id) g_id_map.Get()[c_id] = next_id++; +#define DECLARE_RESOURCE_ID(c_id, java_id) g_id_map.Get()[c_id] = next_id++; #include "chrome/browser/android/resource_id.h" -#undef DEFINE_RESOURCE_ID +#undef LINK_RESOURCE_ID +#undef DECLARE_RESOURCE_ID }
diff --git a/chrome/browser/android/tab/thumbnail_tab_helper_android.cc b/chrome/browser/android/tab/thumbnail_tab_helper_android.cc index 17c0cae..c93d41c 100644 --- a/chrome/browser/android/tab/thumbnail_tab_helper_android.cc +++ b/chrome/browser/android/tab/thumbnail_tab_helper_android.cc
@@ -5,23 +5,108 @@ #include "chrome/browser/android/tab/thumbnail_tab_helper_android.h" #include "base/android/jni_android.h" -#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "base/logging.h" #include "base/memory/ref_counted.h" -#include "chrome/browser/history/top_sites_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_android.h" +#include "chrome/browser/thumbnails/simple_thumbnail_crop.h" #include "chrome/browser/thumbnails/thumbnail_service.h" #include "chrome/browser/thumbnails/thumbnail_service_factory.h" #include "chrome/browser/thumbnails/thumbnail_tab_helper.h" -#include "components/history/core/browser/top_sites.h" +#include "chrome/browser/thumbnails/thumbnailing_algorithm.h" +#include "chrome/browser/thumbnails/thumbnailing_context.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "jni/ThumbnailTabHelper_jni.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/android/java_bitmap.h" -#include "ui/gfx/color_utils.h" #include "ui/gfx/image/image_skia.h" #include "url/gurl.h" +using thumbnails::ThumbnailingAlgorithm; +using thumbnails::ThumbnailingContext; +using thumbnails::ThumbnailService; + +namespace { + +const int kScrollbarWidthDp = 6; + +void UpdateThumbnail(const ThumbnailingContext& context, + const SkBitmap& thumbnail) { + gfx::Image image = gfx::Image::CreateFrom1xBitmap(thumbnail); + context.service->SetPageThumbnail(context, image); +} + +void ProcessCapturedBitmap( + const base::android::ScopedJavaGlobalRef<jobject>& jthumbnail_tab_helper, + scoped_refptr<ThumbnailingContext> context, + scoped_refptr<ThumbnailingAlgorithm> algorithm, + const SkBitmap& bitmap, + content::ReadbackResponse response) { + if (response != content::READBACK_SUCCESS) + return; + + // On success, we must be on the UI thread (on failure because of shutdown we + // are not on the UI thread). + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + JNIEnv* env = base::android::AttachCurrentThread(); + if (!Java_ThumbnailTabHelper_shouldSaveCapturedThumbnail( + env, jthumbnail_tab_helper.obj())) { + return; + } + + algorithm->ProcessBitmap(context, base::Bind(&UpdateThumbnail), bitmap); +} + +void CaptureThumbnailInternal( + const base::android::ScopedJavaGlobalRef<jobject>& jthumbnail_tab_helper, + content::WebContents* web_contents, + scoped_refptr<ThumbnailingContext> context, + scoped_refptr<ThumbnailingAlgorithm> algorithm, + const gfx::Size& thumbnail_size) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + content::RenderWidgetHost* render_widget_host = + web_contents->GetRenderViewHost(); + content::RenderWidgetHostView* view = render_widget_host->GetView(); + if (!view) + return; + if (!view->IsSurfaceAvailableForCopy()) + return; + + gfx::Rect copy_rect = gfx::Rect(view->GetViewBounds().size()); + // Clip the pixels that will commonly hold a scrollbar, which looks bad in + // thumbnails. + copy_rect.Inset(0, 0, kScrollbarWidthDp, 0); + if (copy_rect.IsEmpty()) + return; + + ui::ScaleFactor scale_factor = + ui::GetSupportedScaleFactor( + ui::GetScaleFactorForNativeView(view->GetNativeView())); + context->clip_result = algorithm->GetCanvasCopyInfo( + copy_rect.size(), + scale_factor, + ©_rect, + &context->requested_copy_size); + + // Workaround for a bug where CopyFromBackingStore() accepts different input + // units on Android (DIP) vs on other platforms (pixels). + // TODO(newt): remove this line once https://crbug.com/540497 is fixed. + context->requested_copy_size = thumbnail_size; + + render_widget_host->CopyFromBackingStore( + copy_rect, context->requested_copy_size, + base::Bind(&ProcessCapturedBitmap, jthumbnail_tab_helper, context, + algorithm), + kN32_SkColorType); +} + +} // namespace + // static bool RegisterThumbnailTabHelperAndroid(JNIEnv* env) { return RegisterNativesImpl(env); @@ -44,57 +129,33 @@ thumbnail_tab_helper->set_enabled(false); } -static jboolean ShouldUpdateThumbnail(JNIEnv* env, - const JavaParamRef<jclass>& clazz, - const JavaParamRef<jobject>& jprofile, - const JavaParamRef<jstring>& jurl) { - Profile* profile = ProfileAndroid::FromProfileAndroid(jprofile); - - GURL url(base::android::ConvertJavaStringToUTF8(env, jurl)); - scoped_refptr<thumbnails::ThumbnailService> thumbnail_service = - ThumbnailServiceFactory::GetForProfile(profile); - return (thumbnail_service.get() != NULL && - thumbnail_service->ShouldAcquirePageThumbnail(url)); -} - -static void UpdateThumbnail(JNIEnv* env, - const JavaParamRef<jclass>& clazz, - const JavaParamRef<jobject>& jweb_contents, - const JavaParamRef<jobject>& bitmap, - jboolean jat_top) { +static void CaptureThumbnail(JNIEnv* env, + const JavaParamRef<jclass>& clazz, + const JavaParamRef<jobject>& jthumbnail_tab_helper, + const JavaParamRef<jobject>& jweb_contents, + jint thumbnail_width_dp, + jint thumbnail_height_dp) { content::WebContents* web_contents = content::WebContents::FromJavaWebContents(jweb_contents); DCHECK(web_contents); + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); - Profile* profile = Profile::FromBrowserContext( - web_contents->GetBrowserContext()); - - gfx::JavaBitmap bitmap_lock(bitmap); - SkBitmap sk_bitmap; - gfx::Size size = bitmap_lock.size(); - SkColorType color_type = kN32_SkColorType; - sk_bitmap.setInfo( - SkImageInfo::Make(size.width(), size.height(), - color_type, kPremul_SkAlphaType), 0); - sk_bitmap.setPixels(bitmap_lock.pixels()); - - // TODO(nileshagrawal): Refactor this. - // We were using some non-public methods from ThumbnailTabHelper. We need to - // either add android specific logic to ThumbnailTabHelper or create our own - // helper which is driven by the java app (will need to pull out some logic - // from ThumbnailTabHelper to a common class). - scoped_refptr<history::TopSites> ts = TopSitesFactory::GetForProfile(profile); - if (!ts) + scoped_refptr<ThumbnailService> thumbnail_service = + ThumbnailServiceFactory::GetForProfile(profile); + if (thumbnail_service.get() == nullptr || + !thumbnail_service->ShouldAcquirePageThumbnail( + web_contents->GetLastCommittedURL())) { return; + } - // Compute the thumbnail score. - ThumbnailScore score; - score.at_top = jat_top; - score.boring_score = color_utils::CalculateBoringScore(sk_bitmap); - score.good_clipping = true; - score.load_completed = !web_contents->IsLoading(); + const gfx::Size thumbnail_size(thumbnail_width_dp, thumbnail_height_dp); + scoped_refptr<ThumbnailingAlgorithm> algorithm( + new thumbnails::SimpleThumbnailCrop(thumbnail_size)); - gfx::Image image = gfx::Image::CreateFrom1xBitmap(sk_bitmap); - const GURL& url = web_contents->GetURL(); - ts->SetPageThumbnail(url, image, score); + scoped_refptr<ThumbnailingContext> context(new ThumbnailingContext( + web_contents, thumbnail_service.get(), false /*load_interrupted*/)); + CaptureThumbnailInternal( + base::android::ScopedJavaGlobalRef<jobject>(env, jthumbnail_tab_helper), + web_contents, context, algorithm, thumbnail_size); }
diff --git a/chrome/browser/autofill/autofill_server_browsertest.cc b/chrome/browser/autofill/autofill_server_browsertest.cc index 163dd2d3..eb4299b 100644 --- a/chrome/browser/autofill/autofill_server_browsertest.cc +++ b/chrome/browser/autofill/autofill_server_browsertest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/base_switches.h" #include "base/command_line.h" #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -12,7 +13,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/autofill/core/browser/autofill_profile.h"
diff --git a/chrome/browser/captive_portal/captive_portal_browsertest.cc b/chrome/browser/captive_portal/captive_portal_browsertest.cc index 825fa8e4..1bca5ec 100644 --- a/chrome/browser/captive_portal/captive_portal_browsertest.cc +++ b/chrome/browser/captive_portal/captive_portal_browsertest.cc
@@ -7,6 +7,7 @@ #include <string> #include <vector> +#include "base/base_switches.h" #include "base/basictypes.h" #include "base/bind.h" #include "base/command_line.h" @@ -36,7 +37,6 @@ #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_paths.h" -#include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 3632038..a43d66b1 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -9,6 +9,7 @@ #include <vector> #include "base/at_exit.h" +#include "base/base_switches.h" #include "base/bind.h" #include "base/command_line.h" #include "base/debug/crash_logging.h"
diff --git a/chrome/browser/chrome_browser_main_android.cc b/chrome/browser/chrome_browser_main_android.cc index c8dcda4d..4fd6d9d 100644 --- a/chrome/browser/chrome_browser_main_android.cc +++ b/chrome/browser/chrome_browser_main_android.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/chrome_browser_main_android.h" #include "base/android/build_info.h" +#include "base/base_switches.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -14,7 +15,6 @@ #include "chrome/browser/android/seccomp_support_detector.h" #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/common/chrome_paths.h" -#include "chrome/common/chrome_switches.h" #include "components/crash/content/app/breakpad_linux.h" #include "components/crash/content/browser/crash_dump_manager_android.h" #include "components/enhanced_bookmarks/persistent_image_store.h"
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc index 5a7e6fc..5c90b54 100644 --- a/chrome/browser/chrome_browser_main_win.cc +++ b/chrome/browser/chrome_browser_main_win.cc
@@ -9,6 +9,7 @@ #include <algorithm> +#include "base/base_switches.h" #include "base/command_line.h" #include "base/environment.h" #include "base/files/file_enumerator.h"
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 71adb835..c607c2c9 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -9,6 +9,7 @@ #include <utility> #include <vector> +#include "base/base_switches.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" @@ -99,6 +100,7 @@ #include "chrome/grit/generated_resources.h" #include "chrome/installer/util/google_update_settings.h" #include "chromeos/chromeos_constants.h" +#include "components/autofill/core/common/autofill_switches.h" #include "components/cdm/browser/cdm_message_filter_android.h" #include "components/cloud_devices/common/cloud_devices_switches.h" #include "components/content_settings/core/browser/content_settings_utils.h"
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc index a24c6f4..1b6481f 100644 --- a/chrome/browser/chromeos/login/chrome_restart_request.cc +++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -7,6 +7,7 @@ #include <vector> #include "ash/ash_switches.h" +#include "base/base_switches.h" #include "base/command_line.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" @@ -74,6 +75,7 @@ ::switches::kDisableAcceleratedVideoDecode, ::switches::kDisableBlinkFeatures, ::switches::kDisableCastStreamingHWEncoding, + ::switches::kDisableCompositorAnimationTimelines, ::switches::kDisableDistanceFieldText, ::switches::kDisableGpu, ::switches::kDisableGpuMemoryBufferVideoFrames, @@ -95,7 +97,6 @@ ::switches::kDisableTouchDragDrop, ::switches::kDisableZeroCopy, ::switches::kEnableBlinkFeatures, - ::switches::kEnableCompositorAnimationTimelines, ::switches::kDisableDisplayList2dCanvas, ::switches::kEnableDisplayList2dCanvas, ::switches::kForceDisplayList2dCanvas,
diff --git a/chrome/browser/component_updater/sw_reporter_installer_win.cc b/chrome/browser/component_updater/sw_reporter_installer_win.cc index cd9f794..57e44b2 100644 --- a/chrome/browser/component_updater/sw_reporter_installer_win.cc +++ b/chrome/browser/component_updater/sw_reporter_installer_win.cc
@@ -59,11 +59,9 @@ const base::FilePath::CharType kSwReporterExeName[] = FILE_PATH_LITERAL("software_reporter_tool.exe"); -// Where to fetch the reporter's list of found uws in the registry. +// SRT registry keys and value names. const wchar_t kCleanerSuffixRegistryKey[] = L"Cleaner"; -const wchar_t kEndTimeValueName[] = L"EndTime"; const wchar_t kExitCodeValueName[] = L"ExitCode"; -const wchar_t kStartTimeValueName[] = L"StartTime"; const wchar_t kUploadResultsValueName[] = L"UploadResults"; const wchar_t kVersionValueName[] = L"Version"; @@ -201,7 +199,7 @@ HKEY_CURRENT_USER, cleaner_key_name.c_str(), KEY_ALL_ACCESS); // Cleaner is assumed to have run if we have a start time. if (cleaner_key.Valid()) { - if (cleaner_key.HasValue(kStartTimeValueName)) { + if (cleaner_key.HasValue(safe_browsing::kStartTimeValueName)) { // Get version number. if (cleaner_key.HasValue(kVersionValueName)) { DWORD version; @@ -213,14 +211,16 @@ // Get start & end time. If we don't have an end time, we can assume the // cleaner has not completed. int64 start_time_value; - cleaner_key.ReadInt64(kStartTimeValueName, &start_time_value); + cleaner_key.ReadInt64(safe_browsing::kStartTimeValueName, + &start_time_value); - bool completed = cleaner_key.HasValue(kEndTimeValueName); + bool completed = cleaner_key.HasValue(safe_browsing::kEndTimeValueName); SRTHasCompleted(completed ? SRT_COMPLETED_YES : SRT_COMPLETED_NOT_YET); if (completed) { int64 end_time_value; - cleaner_key.ReadInt64(kEndTimeValueName, &end_time_value); - cleaner_key.DeleteValue(kEndTimeValueName); + cleaner_key.ReadInt64(safe_browsing::kEndTimeValueName, + &end_time_value); + cleaner_key.DeleteValue(safe_browsing::kEndTimeValueName); base::TimeDelta run_time( base::Time::FromInternalValue(end_time_value) - base::Time::FromInternalValue(start_time_value)); @@ -235,7 +235,7 @@ exit_code); cleaner_key.DeleteValue(kExitCodeValueName); } - cleaner_key.DeleteValue(kStartTimeValueName); + cleaner_key.DeleteValue(safe_browsing::kStartTimeValueName); if (exit_code == safe_browsing::kSwReporterPostRebootCleanupNeeded || exit_code == @@ -256,9 +256,9 @@ ReportUploadsWithUma(upload_results); } } else { - if (cleaner_key.HasValue(kEndTimeValueName)) { + if (cleaner_key.HasValue(safe_browsing::kEndTimeValueName)) { SRTHasCompleted(SRT_COMPLETED_LATER); - cleaner_key.DeleteValue(kEndTimeValueName); + cleaner_key.DeleteValue(safe_browsing::kEndTimeValueName); } } }
diff --git a/chrome/browser/crash_recovery_browsertest.cc b/chrome/browser/crash_recovery_browsertest.cc index 82ee5478..36ce51f 100644 --- a/chrome/browser/crash_recovery_browsertest.cc +++ b/chrome/browser/crash_recovery_browsertest.cc
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/base_switches.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/strings/stringprintf.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/engagement/site_engagement_helper.cc b/chrome/browser/engagement/site_engagement_helper.cc index 7f1bfe5..96c6db05 100644 --- a/chrome/browser/engagement/site_engagement_helper.cc +++ b/chrome/browser/engagement/site_engagement_helper.cc
@@ -15,7 +15,9 @@ namespace { -double g_seconds_between_user_input_check = 10; +int g_seconds_between_user_input_check = 10; +int g_seconds_tracking_delay_after_navigation = 10; +int g_seconds_tracking_delay_after_show = 5; } // anonymous namespace @@ -24,7 +26,9 @@ SiteEngagementHelper::InputTracker::InputTracker(SiteEngagementHelper* helper) : helper_(helper), pause_timer_(new base::Timer(true, false)), - callbacks_added_(false) { + host_(nullptr), + is_active_(false), + is_tracking_(false) { key_press_event_callback_ = base::Bind(&SiteEngagementHelper::InputTracker::HandleKeyPressEvent, base::Unretained(this)); @@ -33,7 +37,7 @@ base::Unretained(this)); } -SiteEngagementHelper::InputTracker::~InputTracker() { } +SiteEngagementHelper::InputTracker::~InputTracker() {} // Record that there was some user input, and defer handling of the input event. // web_contents() will return nullptr if the observed contents have been @@ -45,7 +49,7 @@ // Only respond to raw key down to avoid multiple triggering on a single input // (e.g. keypress is a key down then key up). if (event.type == blink::WebInputEvent::RawKeyDown) { - PauseTracking(helper_->web_contents()->GetRenderViewHost()); + Pause(); helper_->RecordUserInput(SiteEngagementMetrics::ENGAGEMENT_KEYPRESS); } return false; @@ -59,62 +63,91 @@ if ((event.button != blink::WebMouseEvent::ButtonNone && event.type == blink::WebInputEvent::MouseDown) || event.type == blink::WebInputEvent::MouseWheel) { - PauseTracking(helper_->web_contents()->GetRenderViewHost()); + Pause(); helper_->RecordUserInput(SiteEngagementMetrics::ENGAGEMENT_MOUSE); } return false; } -void SiteEngagementHelper::InputTracker::StartTracking( - content::RenderViewHost* host) { - if (!callbacks_added_) { - host->AddKeyPressEventCallback(key_press_event_callback_); - host->AddMouseEventCallback(mouse_event_callback_); - callbacks_added_ = true; - } +void SiteEngagementHelper::InputTracker::Start(content::RenderViewHost* host, + base::TimeDelta initial_delay) { + DCHECK(!is_active_); + DCHECK(host); + host_ = host; + StartTimer(initial_delay); + is_active_ = true; } -void SiteEngagementHelper::InputTracker::PauseTracking( - content::RenderViewHost* host) { - StopTracking(host); +void SiteEngagementHelper::InputTracker::Pause() { + RemoveCallbacks(); + StartTimer(base::TimeDelta::FromSeconds(g_seconds_between_user_input_check)); +} + +void SiteEngagementHelper::InputTracker::SwitchRenderViewHost( + content::RenderViewHost* old_host, + content::RenderViewHost* new_host) { + DCHECK(is_tracking_); + DCHECK(new_host); + + bool was_tracking = is_tracking_; + if (old_host) { + DCHECK_EQ(host_, old_host); + RemoveCallbacks(); + } + + host_ = new_host; + + if (was_tracking) + AddCallbacks(); +} + +void SiteEngagementHelper::InputTracker::Stop() { + pause_timer_->Stop(); + RemoveCallbacks(); + host_ = nullptr; + is_active_ = false; +} + +void SiteEngagementHelper::InputTracker::SetPauseTimerForTesting( + scoped_ptr<base::Timer> timer) { + pause_timer_ = timer.Pass(); +} + +void SiteEngagementHelper::InputTracker::StartTimer(base::TimeDelta delay) { pause_timer_->Start( - FROM_HERE, - base::TimeDelta::FromSeconds(g_seconds_between_user_input_check), - base::Bind(&SiteEngagementHelper::InputTracker::ResumeTracking, + FROM_HERE, delay, + base::Bind(&SiteEngagementHelper::InputTracker::AddCallbacks, base::Unretained(this))); } -void SiteEngagementHelper::InputTracker::ResumeTracking() { +void SiteEngagementHelper::InputTracker::AddCallbacks() { content::WebContents* contents = helper_->web_contents(); - if (contents) - StartTracking(contents->GetRenderViewHost()); + if (!contents) + return; + + host_->AddKeyPressEventCallback(key_press_event_callback_); + host_->AddMouseEventCallback(mouse_event_callback_); + is_tracking_ = true; } -void SiteEngagementHelper::InputTracker::StopTracking( - content::RenderViewHost* host) { - pause_timer_->Stop(); - if (callbacks_added_) { - host->RemoveKeyPressEventCallback(key_press_event_callback_); - host->RemoveMouseEventCallback(mouse_event_callback_); - callbacks_added_ = false; +void SiteEngagementHelper::InputTracker::RemoveCallbacks() { + if (is_tracking_) { + host_->RemoveKeyPressEventCallback(key_press_event_callback_); + host_->RemoveMouseEventCallback(mouse_event_callback_); + is_tracking_ = false; } } -void SiteEngagementHelper::InputTracker::SetTimerForTesting( - scoped_ptr<base::Timer> timer) { - pause_timer_ = timer.Pass(); -} - SiteEngagementHelper::~SiteEngagementHelper() { content::WebContents* contents = web_contents(); if (contents) - input_tracker_.StopTracking(contents->GetRenderViewHost()); + input_tracker_.Stop(); } SiteEngagementHelper::SiteEngagementHelper(content::WebContents* contents) : content::WebContentsObserver(contents), input_tracker_(this), - record_engagement_(false) { } + record_engagement_(false) {} void SiteEngagementHelper::RecordUserInput( SiteEngagementMetrics::EngagementType type) { @@ -132,31 +165,28 @@ } } -bool SiteEngagementHelper::ShouldRecordEngagement() { - return record_engagement_; -} - void SiteEngagementHelper::DidNavigateMainFrame( const content::LoadCommittedDetails& details, const content::FrameNavigateParams& params) { - content::WebContents* contents = web_contents(); - input_tracker_.StopTracking(contents->GetRenderViewHost()); + input_tracker_.Stop(); - // Ignore all schemes except HTTP and HTTPS. record_engagement_ = params.url.SchemeIsHTTPOrHTTPS(); - if (!ShouldRecordEngagement()) + // Ignore all schemes except HTTP and HTTPS. + if (!record_engagement_) return; Profile* profile = - Profile::FromBrowserContext(contents->GetBrowserContext()); + Profile::FromBrowserContext(web_contents()->GetBrowserContext()); SiteEngagementService* service = SiteEngagementServiceFactory::GetForProfile(profile); if (service) service->HandleNavigation(params.url, params.transition); - input_tracker_.StartTracking(contents->GetRenderViewHost()); + input_tracker_.Start( + web_contents()->GetRenderViewHost(), + base::TimeDelta::FromSeconds(g_seconds_tracking_delay_after_navigation)); } void SiteEngagementHelper::RenderViewHostChanged( @@ -164,29 +194,36 @@ content::RenderViewHost* new_host) { // On changing the render view host, we need to re-register the callbacks // listening for user input. - if (ShouldRecordEngagement()) { - if (old_host) - input_tracker_.StopTracking(old_host); - input_tracker_.StartTracking(new_host); + if (input_tracker_.is_tracking()) { + input_tracker_.SwitchRenderViewHost(old_host, new_host); } } void SiteEngagementHelper::WasShown() { // Ensure that the input callbacks are registered when we come into view. - if (ShouldRecordEngagement()) - input_tracker_.StartTracking(web_contents()->GetRenderViewHost()); + if (record_engagement_) { + input_tracker_.Start( + web_contents()->GetRenderViewHost(), + base::TimeDelta::FromSeconds(g_seconds_tracking_delay_after_show)); + } } void SiteEngagementHelper::WasHidden() { // Ensure that the input callbacks are not registered when hidden. - if (ShouldRecordEngagement()) { - content::WebContents* contents = web_contents(); - if (contents) - input_tracker_.StopTracking(contents->GetRenderViewHost()); - } + input_tracker_.Stop(); } // static -void SiteEngagementHelper::SetSecondsBetweenUserInputCheck(double seconds) { +void SiteEngagementHelper::SetSecondsBetweenUserInputCheck(int seconds) { g_seconds_between_user_input_check = seconds; } + +// static +void SiteEngagementHelper::SetSecondsTrackingDelayAfterNavigation(int seconds) { + g_seconds_tracking_delay_after_navigation = seconds; +} + +// static +void SiteEngagementHelper::SetSecondsTrackingDelayAfterShow(int seconds) { + g_seconds_tracking_delay_after_show = seconds; +}
diff --git a/chrome/browser/engagement/site_engagement_helper.h b/chrome/browser/engagement/site_engagement_helper.h index bd45650..3077afb5 100644 --- a/chrome/browser/engagement/site_engagement_helper.h +++ b/chrome/browser/engagement/site_engagement_helper.h
@@ -26,7 +26,18 @@ public: ~SiteEngagementHelper() override; - static void SetSecondsBetweenUserInputCheck(double seconds); + static void SetSecondsBetweenUserInputCheck(int seconds); + static void SetSecondsTrackingDelayAfterNavigation(int seconds); + static void SetSecondsTrackingDelayAfterShow(int seconds); + + // content::WebContentsObserver overrides. + void DidNavigateMainFrame( + const content::LoadCommittedDetails& details, + const content::FrameNavigateParams& params) override; + void RenderViewHostChanged(content::RenderViewHost* old_host, + content::RenderViewHost* new_host) override; + void WasShown() override; + void WasHidden() override; private: // Class to encapsulate the user input listening. @@ -51,30 +62,45 @@ // Callback to handle mouse events from the RenderViewHost. bool HandleMouseEvent(const blink::WebMouseEvent& event); - // Register callbacks to listen for user input. - void StartTracking(content::RenderViewHost* host); + // Begin tracking input after |initial_delay|. + void Start(content::RenderViewHost* host, base::TimeDelta initial_delay); - // Pause listening for user input, restarting listening after - // g_seconds_between_user_input_check seconds. - void PauseTracking(content::RenderViewHost* host); + // Pause listening for user input, restarting listening after a delay. + void Pause(); - // Restart listening for user input. - void ResumeTracking(); + // Switches the InputTracker to another RenderViewHost, respecting the pause + // timer state. + void SwitchRenderViewHost(content::RenderViewHost* old_host, + content::RenderViewHost* new_host); // Stop listening for user input. - void StopTracking(content::RenderViewHost* host); + void Stop(); + + // Returns whether the InputTracker has been started for a RenderViewHost. + bool is_active() const { return is_active_; } + + // Returns whether input tracking callbacks have been added to + // RenderViewHost. + bool is_tracking() const { return is_tracking_; } // Set the timer object for testing purposes. - void SetTimerForTesting(scoped_ptr<base::Timer> timer); - - bool callbacks_added() { return callbacks_added_; } + void SetPauseTimerForTesting(scoped_ptr<base::Timer> timer); private: + // Starts the timer for adding callbacks to the RenderViewHost. + void StartTimer(base::TimeDelta delay); + + // Adds/removes tracking callbacks to the RenderViewHost. + void AddCallbacks(); + void RemoveCallbacks(); + SiteEngagementHelper* helper_; scoped_ptr<base::Timer> pause_timer_; + content::RenderViewHost* host_; content::RenderWidgetHost::KeyPressEventCallback key_press_event_callback_; content::RenderWidgetHost::MouseEventCallback mouse_event_callback_; - bool callbacks_added_; + bool is_active_; + bool is_tracking_; }; explicit SiteEngagementHelper(content::WebContents* web_contents); @@ -85,19 +111,6 @@ // current contents location. void RecordUserInput(SiteEngagementMetrics::EngagementType type); - bool ShouldRecordEngagement(); - - // content::WebContentsObserver overrides. - void DidNavigateMainFrame( - const content::LoadCommittedDetails& details, - const content::FrameNavigateParams& params) override; - - void RenderViewHostChanged(content::RenderViewHost* old_host, - content::RenderViewHost* new_host) override; - - void WasShown() override; - void WasHidden() override; - InputTracker input_tracker_; bool record_engagement_;
diff --git a/chrome/browser/engagement/site_engagement_service_browsertest.cc b/chrome/browser/engagement/site_engagement_service_browsertest.cc index bec367a..2da4efa2 100644 --- a/chrome/browser/engagement/site_engagement_service_browsertest.cc +++ b/chrome/browser/engagement/site_engagement_service_browsertest.cc
@@ -49,14 +49,14 @@ helper->input_tracker_.HandleMouseEvent(event); } - // Set a timer object for test purposes. - void SetHelperTimer(SiteEngagementHelper* helper, - scoped_ptr<base::Timer> timer) { - helper->input_tracker_.SetTimerForTesting(timer.Pass()); + // Set a pause timer on the input tracker for test purposes. + void SetInputTrackerPauseTimer(SiteEngagementHelper* helper, + scoped_ptr<base::Timer> timer) { + helper->input_tracker_.SetPauseTimerForTesting(timer.Pass()); } - bool CallbacksAdded(SiteEngagementHelper* helper) { - return helper->input_tracker_.callbacks_added(); + bool IsTracking(SiteEngagementHelper* helper) { + return helper->input_tracker_.is_tracking(); } }; @@ -237,10 +237,9 @@ content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - scoped_ptr<base::MockTimer> mock_timer(new base::MockTimer(true, false)); - base::MockTimer* timer = mock_timer.get(); + base::MockTimer* input_tracker_timer = new base::MockTimer(true, false); scoped_ptr<SiteEngagementHelper> helper(CreateHelper(web_contents)); - SetHelperTimer(helper.get(), mock_timer.Pass()); + SetInputTrackerPauseTimer(helper.get(), make_scoped_ptr(input_tracker_timer)); SiteEngagementService* service = SiteEngagementServiceFactory::GetForProfile(browser()->profile()); @@ -250,43 +249,198 @@ EXPECT_DOUBLE_EQ(0.5, service->GetScore(url1)); EXPECT_EQ(0, service->GetScore(url2)); - // Timer should not be running after navigation. It should start after input. - EXPECT_FALSE(timer->IsRunning()); - EXPECT_TRUE(CallbacksAdded(helper.get())); + // Timer should be running for navigation delay. + EXPECT_TRUE(input_tracker_timer->IsRunning()); + EXPECT_FALSE(IsTracking(helper.get())); + input_tracker_timer->Fire(); + + // Timer should start running again after input. + EXPECT_FALSE(input_tracker_timer->IsRunning()); + EXPECT_TRUE(IsTracking(helper.get())); HandleKeyPress(helper.get(), ui::VKEY_RETURN); - EXPECT_TRUE(timer->IsRunning()); - EXPECT_FALSE(CallbacksAdded(helper.get())); + EXPECT_TRUE(input_tracker_timer->IsRunning()); + EXPECT_FALSE(IsTracking(helper.get())); EXPECT_DOUBLE_EQ(0.55, service->GetScore(url1)); EXPECT_EQ(0, service->GetScore(url2)); - timer->Fire(); - EXPECT_FALSE(timer->IsRunning()); - EXPECT_TRUE(CallbacksAdded(helper.get())); + input_tracker_timer->Fire(); + EXPECT_FALSE(input_tracker_timer->IsRunning()); + EXPECT_TRUE(IsTracking(helper.get())); + + // Timer should start running again after input. HandleMouseEvent(helper.get(), blink::WebMouseEvent::ButtonNone, blink::WebInputEvent::MouseWheel); - EXPECT_TRUE(timer->IsRunning()); - EXPECT_FALSE(CallbacksAdded(helper.get())); + EXPECT_TRUE(input_tracker_timer->IsRunning()); + EXPECT_FALSE(IsTracking(helper.get())); EXPECT_DOUBLE_EQ(0.6, service->GetScore(url1)); EXPECT_EQ(0, service->GetScore(url2)); - timer->Fire(); - EXPECT_FALSE(timer->IsRunning()); - EXPECT_TRUE(CallbacksAdded(helper.get())); + input_tracker_timer->Fire(); + EXPECT_FALSE(input_tracker_timer->IsRunning()); + EXPECT_TRUE(IsTracking(helper.get())); + + // Timer should be running for navigation delay. ui_test_utils::NavigateToURL(browser(), url2); - EXPECT_FALSE(timer->IsRunning()); - EXPECT_TRUE(CallbacksAdded(helper.get())); + EXPECT_TRUE(input_tracker_timer->IsRunning()); + EXPECT_FALSE(IsTracking(helper.get())); EXPECT_DOUBLE_EQ(0.6, service->GetScore(url1)); EXPECT_DOUBLE_EQ(0.5, service->GetScore(url2)); + input_tracker_timer->Fire(); + EXPECT_FALSE(input_tracker_timer->IsRunning()); + EXPECT_TRUE(IsTracking(helper.get())); + HandleMouseEvent(helper.get(), blink::WebMouseEvent::ButtonRight, blink::WebInputEvent::MouseDown); - EXPECT_TRUE(timer->IsRunning()); - EXPECT_FALSE(CallbacksAdded(helper.get())); + EXPECT_TRUE(input_tracker_timer->IsRunning()); + EXPECT_FALSE(IsTracking(helper.get())); EXPECT_DOUBLE_EQ(0.6, service->GetScore(url1)); EXPECT_DOUBLE_EQ(0.55, service->GetScore(url2)); EXPECT_DOUBLE_EQ(1.15, service->GetTotalEngagementPoints()); } + +// Ensure that navigation does not trigger input tracking until after a delay. +IN_PROC_BROWSER_TEST_F(SiteEngagementServiceBrowserTest, ShowAndHide) { + GURL url1("https://www.google.com/"); + GURL url2("http://www.google.com/"); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + base::MockTimer* input_tracker_timer = new base::MockTimer(true, false); + scoped_ptr<SiteEngagementHelper> helper(CreateHelper(web_contents)); + SetInputTrackerPauseTimer(helper.get(), make_scoped_ptr(input_tracker_timer)); + + ui_test_utils::NavigateToURL(browser(), url1); + input_tracker_timer->Fire(); + + EXPECT_FALSE(input_tracker_timer->IsRunning()); + EXPECT_TRUE(IsTracking(helper.get())); + + // Hiding the tab should stop input tracking. + ui_test_utils::NavigateToURLWithDisposition( + browser(), url2, NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + + EXPECT_FALSE(IsTracking(helper.get())); + + // Showing the tab should start tracking again after another delay. + browser()->tab_strip_model()->ActivateTabAt(0, true); + EXPECT_TRUE(input_tracker_timer->IsRunning()); + EXPECT_FALSE(IsTracking(helper.get())); + + input_tracker_timer->Fire(); + EXPECT_FALSE(input_tracker_timer->IsRunning()); + EXPECT_TRUE(IsTracking(helper.get())); + + // New background tabs should not affect the current tab's input tracking. + ui_test_utils::NavigateToURLWithDisposition( + browser(), url2, NEW_BACKGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB); + EXPECT_FALSE(input_tracker_timer->IsRunning()); + EXPECT_TRUE(IsTracking(helper.get())); + + // Ensure behavior holds when tab is hidden before the initial delay timer + // fires. + ui_test_utils::NavigateToURL(browser(), url2); + EXPECT_TRUE(input_tracker_timer->IsRunning()); + EXPECT_FALSE(IsTracking(helper.get())); + + ui_test_utils::NavigateToURLWithDisposition( + browser(), url2, NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + EXPECT_FALSE(input_tracker_timer->IsRunning()); + EXPECT_FALSE(IsTracking(helper.get())); + + // Showing the tab should start tracking again after another delay. + browser()->tab_strip_model()->ActivateTabAt(0, true); + EXPECT_TRUE(input_tracker_timer->IsRunning()); + EXPECT_FALSE(IsTracking(helper.get())); + + input_tracker_timer->Fire(); + EXPECT_TRUE(IsTracking(helper.get())); +} + +// Ensure tracking behavior is correct for multiple navigations in a single tab. +IN_PROC_BROWSER_TEST_F(SiteEngagementServiceBrowserTest, SingleTabNavigation) { + GURL url1("https://www.google.com/"); + GURL url2("https://www.example.com/"); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + base::MockTimer* input_tracker_timer = new base::MockTimer(true, false); + scoped_ptr<SiteEngagementHelper> helper(CreateHelper(web_contents)); + SetInputTrackerPauseTimer(helper.get(), make_scoped_ptr(input_tracker_timer)); + + // Navigation should start the initial delay timer. + ui_test_utils::NavigateToURL(browser(), url1); + EXPECT_TRUE(input_tracker_timer->IsRunning()); + EXPECT_FALSE(IsTracking(helper.get())); + + // Navigating before the timer fires should simply reset the timer. + ui_test_utils::NavigateToURL(browser(), url2); + EXPECT_TRUE(input_tracker_timer->IsRunning()); + EXPECT_FALSE(IsTracking(helper.get())); + + // When the timer fires, callbacks are added. + input_tracker_timer->Fire(); + EXPECT_FALSE(input_tracker_timer->IsRunning()); + EXPECT_TRUE(IsTracking(helper.get())); + + // Navigation should start the initial delay timer again. + ui_test_utils::NavigateToURL(browser(), url1); + EXPECT_TRUE(input_tracker_timer->IsRunning()); + EXPECT_FALSE(IsTracking(helper.get())); +} + +// Ensure tracking behavior is correct for multiple navigations in a single tab. +IN_PROC_BROWSER_TEST_F(SiteEngagementServiceBrowserTest, SwitchRenderViewHost) { + GURL url1("https://www.google.com/"); + GURL url2("https://www.example.com/"); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + base::MockTimer* input_tracker_timer = new base::MockTimer(true, false); + scoped_ptr<SiteEngagementHelper> helper(CreateHelper(web_contents)); + SetInputTrackerPauseTimer(helper.get(), make_scoped_ptr(input_tracker_timer)); + + // Navigation starts the initial delay timer. + ui_test_utils::NavigateToURL(browser(), url1); + EXPECT_TRUE(input_tracker_timer->IsRunning()); + EXPECT_FALSE(IsTracking(helper.get())); + + content::RenderViewHost* rvh = web_contents->GetRenderViewHost(); + + // The timer should still be running after the RenderViewHost is changed. + helper->RenderViewHostChanged(rvh, rvh); + EXPECT_TRUE(input_tracker_timer->IsRunning()); + EXPECT_FALSE(IsTracking(helper.get())); + + // Firing the timer should add the callbacks. + input_tracker_timer->Fire(); + EXPECT_FALSE(input_tracker_timer->IsRunning()); + EXPECT_TRUE(IsTracking(helper.get())); + + // The callbacks should be on readded another RVH change since the timer has + // already fired. + helper->RenderViewHostChanged(rvh, rvh); + EXPECT_FALSE(input_tracker_timer->IsRunning()); + EXPECT_TRUE(IsTracking(helper.get())); + + // Ensure nothing bad happens with a destroyed RVH. + helper->RenderViewHostChanged(nullptr, rvh); + EXPECT_FALSE(input_tracker_timer->IsRunning()); + EXPECT_TRUE(IsTracking(helper.get())); + + // Ensure nothing happens when RVH change happens for a hidden tab. + helper->WasHidden(); + EXPECT_FALSE(input_tracker_timer->IsRunning()); + EXPECT_FALSE(IsTracking(helper.get())); + + helper->RenderViewHostChanged(nullptr, rvh); + EXPECT_FALSE(input_tracker_timer->IsRunning()); + EXPECT_FALSE(IsTracking(helper.get())); +}
diff --git a/chrome/browser/extensions/api/identity/identity_apitest.cc b/chrome/browser/extensions/api/identity/identity_apitest.cc index 8d84b3d..a626f928 100644 --- a/chrome/browser/extensions/api/identity/identity_apitest.cc +++ b/chrome/browser/extensions/api/identity/identity_apitest.cc
@@ -46,6 +46,7 @@ #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/common/profile_management_switches.h" #include "components/signin/core/common/signin_pref_names.h" +#include "components/signin/core/common/signin_switches.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" #include "content/public/test/test_utils.h"
diff --git a/chrome/browser/extensions/api/instance_id/instance_id_apitest.cc b/chrome/browser/extensions/api/instance_id/instance_id_apitest.cc index 367d7a0..1929671 100644 --- a/chrome/browser/extensions/api/instance_id/instance_id_apitest.cc +++ b/chrome/browser/extensions/api/instance_id/instance_id_apitest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/base_switches.h" #include "base/memory/scoped_ptr.h" #include "base/run_loop.h" #include "chrome/browser/extensions/api/instance_id/instance_id_api.h" @@ -11,7 +12,6 @@ #include "chrome/browser/services/gcm/fake_gcm_profile_service.h" #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" #include "chrome/browser/services/gcm/instance_id/instance_id_profile_service_factory.h" -#include "chrome/common/chrome_switches.h" #include "chrome/test/base/ui_test_utils.h" #include "components/gcm_driver/instance_id/fake_gcm_driver_for_instance_id.h" #include "components/version_info/version_info.h"
diff --git a/chrome/browser/extensions/chrome_extension_web_contents_observer.cc b/chrome/browser/extensions/chrome_extension_web_contents_observer.cc index 52e2126..a178f0d3 100644 --- a/chrome/browser/extensions/chrome_extension_web_contents_observer.cc +++ b/chrome/browser/extensions/chrome_extension_web_contents_observer.cc
@@ -45,11 +45,13 @@ auto policy = content::ChildProcessSecurityPolicy::GetInstance(); // Components of chrome that are implemented as extensions or platform apps - // are allowed to use chrome://resources/ URLs. + // are allowed to use chrome://resources/ and chrome://theme/ URLs. if ((extension->is_extension() || extension->is_platform_app()) && Manifest::IsComponentLocation(extension->location())) { policy->GrantOrigin(process_id, url::Origin(GURL(content::kChromeUIResourcesURL))); + policy->GrantOrigin(process_id, + url::Origin(GURL(chrome::kChromeUIThemeURL))); } // Extensions, legacy packaged apps, and component platform apps are allowed
diff --git a/chrome/browser/extensions/extension_startup_browsertest.cc b/chrome/browser/extensions/extension_startup_browsertest.cc index ad5f1ab..7918358 100644 --- a/chrome/browser/extensions/extension_startup_browsertest.cc +++ b/chrome/browser/extensions/extension_startup_browsertest.cc
@@ -4,6 +4,7 @@ #include <vector> +#include "base/base_switches.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h"
diff --git a/chrome/browser/extensions/install_verifier.cc b/chrome/browser/extensions/install_verifier.cc index 0739647..b5bdbd7 100644 --- a/chrome/browser/extensions/install_verifier.cc +++ b/chrome/browser/extensions/install_verifier.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <string> +#include "base/base_switches.h" #include "base/bind.h" #include "base/command_line.h" #include "base/metrics/field_trial.h"
diff --git a/chrome/browser/first_run/first_run_browsertest.cc b/chrome/browser/first_run/first_run_browsertest.cc index 25897c1..716a1a9a 100644 --- a/chrome/browser/first_run/first_run_browsertest.cc +++ b/chrome/browser/first_run/first_run_browsertest.cc
@@ -4,6 +4,7 @@ #include <string> +#include "base/base_switches.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/macros.h"
diff --git a/chrome/browser/geolocation/geolocation_infobar_delegate.cc b/chrome/browser/geolocation/geolocation_infobar_delegate.cc index b6959ca5..b64ae70 100644 --- a/chrome/browser/geolocation/geolocation_infobar_delegate.cc +++ b/chrome/browser/geolocation/geolocation_infobar_delegate.cc
@@ -4,12 +4,12 @@ #include "chrome/browser/geolocation/geolocation_infobar_delegate.h" +#include "chrome/browser/android/android_theme_resources.h" #include "chrome/browser/infobars/infobar_service.h" #include "chrome/grit/generated_resources.h" #include "components/infobars/core/infobar.h" #include "components/url_formatter/elide_url.h" #include "grit/generated_resources.h" -#include "grit/theme_resources.h" #include "ui/base/l10n/l10n_util.h" // static @@ -38,7 +38,7 @@ } int GeolocationInfoBarDelegate::GetIconId() const { - return IDR_INFOBAR_GEOLOCATION; + return IDR_ANDROID_INFOBAR_GEOLOCATION; } base::string16 GeolocationInfoBarDelegate::GetMessageText() const {
diff --git a/chrome/browser/media/encrypted_media_istypesupported_browsertest.cc b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc similarity index 90% rename from chrome/browser/media/encrypted_media_istypesupported_browsertest.cc rename to chrome/browser/media/encrypted_media_supported_types_browsertest.cc index f8a7461..78658bd3 100644 --- a/chrome/browser/media/encrypted_media_istypesupported_browsertest.cc +++ b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
@@ -93,10 +93,9 @@ }; // namespace -// TODO(jrummell): Rename these tests and this file. http://crbug.com/367158. -class EncryptedMediaIsTypeSupportedTest : public InProcessBrowserTest { +class EncryptedMediaSupportedTypesTest : public InProcessBrowserTest { protected: - EncryptedMediaIsTypeSupportedTest() : is_pepper_cdm_registered_(false) { + EncryptedMediaSupportedTypesTest() : is_pepper_cdm_registered_(false) { audio_webm_codecs_.push_back("opus"); audio_webm_codecs_.push_back("vorbis"); @@ -257,17 +256,17 @@ }; // For ClearKey, nothing additional is required. -class EncryptedMediaIsTypeSupportedClearKeyTest - : public EncryptedMediaIsTypeSupportedTest { +class EncryptedMediaSupportedTypesClearKeyTest + : public EncryptedMediaSupportedTypesTest { }; // For ExternalClearKey tests, ensure that the ClearKey adapter is loaded. -class EncryptedMediaIsTypeSupportedExternalClearKeyTest - : public EncryptedMediaIsTypeSupportedTest { +class EncryptedMediaSupportedTypesExternalClearKeyTest + : public EncryptedMediaSupportedTypesTest { #if defined(ENABLE_PEPPER_CDMS) protected: void SetUpCommandLine(base::CommandLine* command_line) override { - EncryptedMediaIsTypeSupportedTest::SetUpCommandLine(command_line); + EncryptedMediaSupportedTypesTest::SetUpCommandLine(command_line); // Platform-specific filename relative to the chrome executable. const char adapter_file_name[] = @@ -288,17 +287,17 @@ // TODO(sandersd): Register the Widevine CDM if it is a component. A component // CDM registered using RegisterPepperCdm() declares support for audio codecs, // but not the other codecs we expect. http://crbug.com/356833. -class EncryptedMediaIsTypeSupportedWidevineTest - : public EncryptedMediaIsTypeSupportedTest { +class EncryptedMediaSupportedTypesWidevineTest + : public EncryptedMediaSupportedTypesTest { }; #if defined(ENABLE_PEPPER_CDMS) // Registers ClearKey CDM with the wrong path (filename). -class EncryptedMediaIsTypeSupportedClearKeyCDMRegisteredWithWrongPathTest - : public EncryptedMediaIsTypeSupportedTest { +class EncryptedMediaSupportedTypesClearKeyCDMRegisteredWithWrongPathTest + : public EncryptedMediaSupportedTypesTest { protected: void SetUpCommandLine(base::CommandLine* command_line) override { - EncryptedMediaIsTypeSupportedTest::SetUpCommandLine(command_line); + EncryptedMediaSupportedTypesTest::SetUpCommandLine(command_line); RegisterPepperCdm(command_line, "clearkeycdmadapterwrongname.dll", "application/x-ppapi-clearkey-cdm", @@ -307,11 +306,11 @@ }; // Registers Widevine CDM with the wrong path (filename). -class EncryptedMediaIsTypeSupportedWidevineCDMRegisteredWithWrongPathTest - : public EncryptedMediaIsTypeSupportedTest { +class EncryptedMediaSupportedTypesWidevineCDMRegisteredWithWrongPathTest + : public EncryptedMediaSupportedTypesTest { protected: void SetUpCommandLine(base::CommandLine* command_line) override { - EncryptedMediaIsTypeSupportedTest::SetUpCommandLine(command_line); + EncryptedMediaSupportedTypesTest::SetUpCommandLine(command_line); RegisterPepperCdm(command_line, "widevinecdmadapterwrongname.dll", "application/x-ppapi-widevine-cdm", @@ -320,7 +319,7 @@ }; #endif // defined(ENABLE_PEPPER_CDMS) -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedClearKeyTest, Basic) { +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesClearKeyTest, Basic) { EXPECT_SUCCESS(IsSupportedKeySystemWithMediaMimeType( kVideoWebMMimeType, no_codecs(), kClearKey)); EXPECT_SUCCESS(IsSupportedKeySystemWithMediaMimeType( @@ -331,7 +330,7 @@ kAudioMP4MimeType, no_codecs(), kClearKey)); } -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedClearKeyTest, +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesClearKeyTest, InvalidKeySystems) { // Case sensitive. EXPECT_UNKNOWN_KEYSYSTEM(IsSupportedKeySystemWithMediaMimeType( @@ -364,7 +363,7 @@ kVideoWebMMimeType, no_codecs(), "org.w3.clearkey.foo")); } -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedClearKeyTest, Video_WebM) { +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesClearKeyTest, Video_WebM) { // Valid video types. EXPECT_SUCCESS(IsSupportedKeySystemWithMediaMimeType( kVideoWebMMimeType, video_webm_codecs(), kClearKey)); @@ -382,7 +381,7 @@ kVideoWebMMimeType, video_mp4_codecs(), kClearKey)); } -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedClearKeyTest, Audio_WebM) { +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesClearKeyTest, Audio_WebM) { // Valid audio types. EXPECT_SUCCESS(IsSupportedKeySystemWithMediaMimeType( kAudioWebMMimeType, audio_webm_codecs(), kClearKey)); @@ -400,7 +399,7 @@ kAudioWebMMimeType, video_mp4_codecs(), kClearKey)); } -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedClearKeyTest, Video_MP4) { +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesClearKeyTest, Video_MP4) { // Valid video types. EXPECT_PROPRIETARY(IsSupportedKeySystemWithMediaMimeType( kVideoMP4MimeType, video_mp4_codecs(), kClearKey)); @@ -418,7 +417,7 @@ kVideoMP4MimeType, video_webm_codecs(), kClearKey)); } -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedClearKeyTest, Audio_MP4) { +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesClearKeyTest, Audio_MP4) { // Valid audio types. EXPECT_PROPRIETARY(IsSupportedKeySystemWithMediaMimeType( kAudioMP4MimeType, audio_mp4_codecs(), kClearKey)); @@ -441,7 +440,7 @@ // // When defined(ENABLE_PEPPER_CDMS), this also tests the Pepper CDM check. -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedExternalClearKeyTest, +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesExternalClearKeyTest, Basic) { EXPECT_ECK(IsSupportedKeySystemWithMediaMimeType( kVideoWebMMimeType, no_codecs(), kExternalClearKey)); @@ -453,7 +452,7 @@ kAudioMP4MimeType, no_codecs(), kExternalClearKey)); } -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedExternalClearKeyTest, +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesExternalClearKeyTest, InvalidKeySystems) { // Case sensitive. EXPECT_UNKNOWN_KEYSYSTEM(IsSupportedKeySystemWithMediaMimeType( @@ -482,7 +481,7 @@ kVideoWebMMimeType, no_codecs(), "org.chromium.externalclearkey.foo")); } -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedExternalClearKeyTest, +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesExternalClearKeyTest, Video_WebM) { // Valid video types. EXPECT_ECK(IsSupportedKeySystemWithMediaMimeType( @@ -501,7 +500,7 @@ kVideoWebMMimeType, video_mp4_codecs(), kExternalClearKey)); } -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedExternalClearKeyTest, +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesExternalClearKeyTest, Audio_WebM) { // Valid audio types. EXPECT_ECK(IsSupportedKeySystemWithMediaMimeType( @@ -520,7 +519,7 @@ kAudioWebMMimeType, video_mp4_codecs(), kExternalClearKey)); } -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedExternalClearKeyTest, +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesExternalClearKeyTest, Video_MP4) { // Valid video types. EXPECT_ECK_PROPRIETARY(IsSupportedKeySystemWithMediaMimeType( @@ -539,7 +538,7 @@ kVideoMP4MimeType, video_webm_codecs(), kExternalClearKey)); } -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedExternalClearKeyTest, +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesExternalClearKeyTest, Audio_MP4) { // Valid audio types. EXPECT_ECK_PROPRIETARY(IsSupportedKeySystemWithMediaMimeType( @@ -562,8 +561,7 @@ // Widevine // -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedWidevineTest, - Basic) { +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesWidevineTest, Basic) { EXPECT_WV_SUCCESS(IsSupportedKeySystemWithMediaMimeType( kVideoWebMMimeType, no_codecs(), kWidevine)); EXPECT_WV_SUCCESS(IsSupportedKeySystemWithMediaMimeType( @@ -574,7 +572,7 @@ kAudioMP4MimeType, no_codecs(), kWidevine)); } -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedWidevineTest, Video_WebM) { +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesWidevineTest, Video_WebM) { // Valid video types. EXPECT_WV_SUCCESS(IsSupportedKeySystemWithMediaMimeType( kVideoWebMMimeType, video_webm_codecs(), kWidevine)); @@ -592,7 +590,7 @@ kVideoWebMMimeType, video_mp4_codecs(), kWidevine)); } -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedWidevineTest, Audio_WebM) { +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesWidevineTest, Audio_WebM) { // Valid audio types. EXPECT_WV_SUCCESS(IsSupportedKeySystemWithMediaMimeType( kAudioWebMMimeType, audio_webm_codecs(), kWidevine)); @@ -610,7 +608,7 @@ kAudioWebMMimeType, video_mp4_codecs(), kWidevine)); } -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedWidevineTest, Video_MP4) { +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesWidevineTest, Video_MP4) { // Valid video types. EXPECT_WV_PROPRIETARY(IsSupportedKeySystemWithMediaMimeType( kVideoMP4MimeType, video_mp4_codecs(), kWidevine)); @@ -628,7 +626,7 @@ kVideoMP4MimeType, video_webm_codecs(), kWidevine)); } -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedWidevineTest, Audio_MP4) { +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesWidevineTest, Audio_MP4) { // Valid audio types. EXPECT_WV_PROPRIETARY(IsSupportedKeySystemWithMediaMimeType( kAudioMP4MimeType, audio_mp4_codecs(), kWidevine)); @@ -650,7 +648,7 @@ // Since this test fixture does not register the CDMs on the command line, the // check for the CDMs in chrome_key_systems.cc should fail, and they should not // be registered with KeySystems. -IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedTest, +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesTest, PepperCDMsNotRegistered) { EXPECT_UNKNOWN_KEYSYSTEM(IsSupportedKeySystemWithMediaMimeType( kVideoWebMMimeType, no_codecs(), kExternalClearKey)); @@ -671,7 +669,7 @@ // check for the CDMs in chrome_key_systems.cc should fail, and they should not // be registered with KeySystems. IN_PROC_BROWSER_TEST_F( - EncryptedMediaIsTypeSupportedClearKeyCDMRegisteredWithWrongPathTest, + EncryptedMediaSupportedTypesClearKeyCDMRegisteredWithWrongPathTest, PepperCDMsRegisteredButAdapterNotPresent) { EXPECT_UNKNOWN_KEYSYSTEM(IsSupportedKeySystemWithMediaMimeType( kVideoWebMMimeType, no_codecs(), kExternalClearKey)); @@ -685,7 +683,7 @@ // component, in which case it is registered internally. #if !defined(WIDEVINE_CDM_AVAILABLE) || defined(WIDEVINE_CDM_IS_COMPONENT) IN_PROC_BROWSER_TEST_F( - EncryptedMediaIsTypeSupportedWidevineCDMRegisteredWithWrongPathTest, + EncryptedMediaSupportedTypesWidevineCDMRegisteredWithWrongPathTest, PepperCDMsRegisteredButAdapterNotPresent) { EXPECT_UNKNOWN_KEYSYSTEM(IsSupportedKeySystemWithMediaMimeType( kVideoWebMMimeType, no_codecs(), kWidevine)); @@ -694,7 +692,8 @@ EXPECT_SUCCESS(IsSupportedKeySystemWithMediaMimeType( kVideoWebMMimeType, no_codecs(), kClearKey)); } -#endif // !defined(WIDEVINE_CDM_AVAILABLE) || defined(WIDEVINE_CDM_IS_COMPONENT) +#endif // !defined(WIDEVINE_CDM_AVAILABLE) || + // defined(WIDEVINE_CDM_IS_COMPONENT) #endif // defined(ENABLE_PEPPER_CDMS) } // namespace chrome
diff --git a/chrome/browser/media/protected_media_identifier_infobar_delegate.cc b/chrome/browser/media/protected_media_identifier_infobar_delegate.cc index 0932b99..a182244 100644 --- a/chrome/browser/media/protected_media_identifier_infobar_delegate.cc +++ b/chrome/browser/media/protected_media_identifier_infobar_delegate.cc
@@ -4,13 +4,13 @@ #include "chrome/browser/media/protected_media_identifier_infobar_delegate.h" +#include "chrome/browser/android/android_theme_resources.h" #include "chrome/browser/infobars/infobar_service.h" #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" #include "components/infobars/core/infobar.h" #include "components/url_formatter/elide_url.h" #include "grit/components_strings.h" -#include "grit/theme_resources.h" #include "ui/base/l10n/l10n_util.h" // static @@ -43,7 +43,7 @@ } int ProtectedMediaIdentifierInfoBarDelegate::GetIconId() const { - return IDR_INFOBAR_PROTECTED_MEDIA_IDENTIFIER; + return IDR_ANDROID_INFOBAR_PROTECTED_MEDIA_IDENTIFIER; } base::string16 ProtectedMediaIdentifierInfoBarDelegate::GetMessageText() const {
diff --git a/chrome/browser/media/router/issues_observer.cc b/chrome/browser/media/router/issues_observer.cc index 0d496d8..1590b0cd 100644 --- a/chrome/browser/media/router/issues_observer.cc +++ b/chrome/browser/media/router/issues_observer.cc
@@ -11,10 +11,16 @@ IssuesObserver::IssuesObserver(MediaRouter* router) : router_(router) { DCHECK(router_); - router_->RegisterIssuesObserver(this); } IssuesObserver::~IssuesObserver() { +} + +void IssuesObserver::RegisterObserver() { + router_->RegisterIssuesObserver(this); +} + +void IssuesObserver::UnregisterObserver() { router_->UnregisterIssuesObserver(this); }
diff --git a/chrome/browser/media/router/issues_observer.h b/chrome/browser/media/router/issues_observer.h index d8b4258..5b51e63 100644 --- a/chrome/browser/media/router/issues_observer.h +++ b/chrome/browser/media/router/issues_observer.h
@@ -18,6 +18,9 @@ explicit IssuesObserver(MediaRouter* router); virtual ~IssuesObserver(); + void RegisterObserver(); + void UnregisterObserver(); + // Called when there is an updated Media Router Issue. // If |issue| is nullptr, then there is currently no issue. virtual void OnIssueUpdated(const Issue* issue) {}
diff --git a/chrome/browser/media/router/media_router_mojo_impl_unittest.cc b/chrome/browser/media/router/media_router_mojo_impl_unittest.cc index 64be2663..32fd0d5 100644 --- a/chrome/browser/media/router/media_router_mojo_impl_unittest.cc +++ b/chrome/browser/media/router/media_router_mojo_impl_unittest.cc
@@ -283,6 +283,9 @@ TEST_F(MediaRouterMojoImplTest, HandleIssue) { MockIssuesObserver issue_observer1(router()); MockIssuesObserver issue_observer2(router()); + issue_observer1.RegisterObserver(); + issue_observer2.RegisterObserver(); + interfaces::IssuePtr mojo_issue1 = CreateMojoIssue("title 1"); const Issue& expected_issue1 = mojo_issue1.To<Issue>(); @@ -322,6 +325,9 @@ OnIssueUpdated(Pointee(EqualsIssue(expected_issue2)))); media_router_proxy_->OnIssue(mojo_issue2.Pass()); ProcessEventLoop(); + + issue_observer1.UnregisterObserver(); + issue_observer2.UnregisterObserver(); } TEST_F(MediaRouterMojoImplTest, RegisterAndUnregisterMediaSinksObserver) {
diff --git a/chrome/browser/memory/tab_discard_state.cc b/chrome/browser/memory/tab_discard_state.cc index 5cf2df3..449c545c 100644 --- a/chrome/browser/memory/tab_discard_state.cc +++ b/chrome/browser/memory/tab_discard_state.cc
@@ -61,10 +61,16 @@ static int reload_count = 0; UMA_HISTOGRAM_CUSTOM_COUNTS("TabManager.Discarding.ReloadCount", ++reload_count, 1, 1000, 50); + auto delta = base::TimeTicks::Now() - discard_state->last_discard_time_; + // Capped to one day for now, will adjust if necessary. + UMA_HISTOGRAM_CUSTOM_TIMES("TabManager.Discarding.DiscardToReloadTime", + delta, base::TimeDelta::FromSeconds(1), + base::TimeDelta::FromDays(1), 100); } else if (!discard_state->is_discarded_ && state) { static int discard_count = 0; UMA_HISTOGRAM_CUSTOM_COUNTS("TabManager.Discarding.DiscardCount", ++discard_count, 1, 1000, 50); + discard_state->last_discard_time_ = base::TimeTicks::Now(); } discard_state->is_discarded_ = state;
diff --git a/chrome/browser/memory/tab_discard_state.h b/chrome/browser/memory/tab_discard_state.h index 95770be..12dd9976 100644 --- a/chrome/browser/memory/tab_discard_state.h +++ b/chrome/browser/memory/tab_discard_state.h
@@ -74,6 +74,9 @@ // Last time the tab started or stopped playing audio (we record the // transition time). base::TimeTicks last_audio_change_time_; + + // The last time the tab was discarded. + base::TimeTicks last_discard_time_; }; } // namespace memory
diff --git a/chrome/browser/notifications/notification_permission_infobar_delegate.cc b/chrome/browser/notifications/notification_permission_infobar_delegate.cc index 532b3934..105e48d 100644 --- a/chrome/browser/notifications/notification_permission_infobar_delegate.cc +++ b/chrome/browser/notifications/notification_permission_infobar_delegate.cc
@@ -4,11 +4,11 @@ #include "chrome/browser/notifications/notification_permission_infobar_delegate.h" +#include "chrome/browser/android/android_theme_resources.h" #include "chrome/browser/infobars/infobar_service.h" #include "chrome/grit/generated_resources.h" #include "components/infobars/core/infobar.h" #include "components/url_formatter/elide_url.h" -#include "grit/theme_resources.h" #include "net/base/escape.h" #include "ui/base/l10n/l10n_util.h" @@ -39,7 +39,7 @@ {} int NotificationPermissionInfobarDelegate::GetIconId() const { - return IDR_INFOBAR_DESKTOP_NOTIFICATIONS; + return IDR_ANDROID_INFOBAR_NOTIFICATIONS; } base::string16 NotificationPermissionInfobarDelegate::GetMessageText() const {
diff --git a/chrome/browser/notifications/platform_notification_service_impl.cc b/chrome/browser/notifications/platform_notification_service_impl.cc index cc5d2ae..f30b74b 100644 --- a/chrome/browser/notifications/platform_notification_service_impl.cc +++ b/chrome/browser/notifications/platform_notification_service_impl.cc
@@ -387,6 +387,8 @@ notification.set_buttons(buttons); + notification.set_is_web_notification(true); + // On desktop, notifications with require_interaction==true stay on-screen // rather than minimizing to the notification center after a timeout. // On mobile, this is ignored (notifications are minimized at all times).
diff --git a/chrome/browser/permissions/permission_context_base.cc b/chrome/browser/permissions/permission_context_base.cc index e544ed6c..761b489 100644 --- a/chrome/browser/permissions/permission_context_base.cc +++ b/chrome/browser/permissions/permission_context_base.cc
@@ -147,7 +147,10 @@ #if !defined(OS_ANDROID) PermissionBubbleManager* bubble_manager = PermissionBubbleManager::FromWebContents(web_contents); - DCHECK(bubble_manager); + // TODO(felt): sometimes |bubble_manager| is null. This check is meant to + // prevent crashes. See crbug.com/457091. + if (!bubble_manager) + return; scoped_ptr<PermissionBubbleRequest> request_ptr( new PermissionBubbleRequestImpl( requesting_origin, user_gesture, permission_type_,
diff --git a/chrome/browser/permissions/permission_manager.cc b/chrome/browser/permissions/permission_manager.cc index 26ed924..9ccf74d6 100644 --- a/chrome/browser/permissions/permission_manager.cc +++ b/chrome/browser/permissions/permission_manager.cc
@@ -302,12 +302,9 @@ bool PermissionManager::IsPermissionBubbleManagerMissing( content::WebContents* web_contents) { -#if defined(OS_ANDROID) - // Can't be missing if it isn't needed to begin with. + // TODO(felt): Remove this method entirely. Leaving it to make a minimal + // last-minute merge to 46. See crbug.com/457091 and crbug.com/534631. return false; -#else - return PermissionBubbleManager::FromWebContents(web_contents) == nullptr; -#endif } void PermissionManager::OnContentSettingChanged(
diff --git a/chrome/browser/prefetch/prefetch_browsertest.cc b/chrome/browser/prefetch/prefetch_browsertest.cc index 8d2408b2..91b6aaf3 100644 --- a/chrome/browser/prefetch/prefetch_browsertest.cc +++ b/chrome/browser/prefetch/prefetch_browsertest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/base_switches.h" #include "base/command_line.h" #include "base/prefs/pref_service.h" #include "base/strings/utf_string_conversions.h" @@ -9,7 +10,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/prefs/command_line_pref_store.cc b/chrome/browser/prefs/command_line_pref_store.cc index 9fc1c87f..687bd27 100644 --- a/chrome/browser/prefs/command_line_pref_store.cc +++ b/chrome/browser/prefs/command_line_pref_store.cc
@@ -15,6 +15,7 @@ #include "base/values.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" +#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h" #include "components/proxy_config/proxy_config_dictionary.h" #include "components/proxy_config/proxy_config_pref_names.h" #include "ui/base/ui_base_switches.h"
diff --git a/chrome/browser/profiles/profile_window.cc b/chrome/browser/profiles/profile_window.cc index 9885761..4de2f78 100644 --- a/chrome/browser/profiles/profile_window.cc +++ b/chrome/browser/profiles/profile_window.cc
@@ -25,7 +25,6 @@ #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/profile_chooser_constants.h" #include "chrome/browser/ui/user_manager.h" -#include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "components/flags_ui/pref_service_flags_storage.h" @@ -33,6 +32,7 @@ #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/common/profile_management_switches.h" +#include "components/signin/core/common/signin_switches.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/user_metrics.h"
diff --git a/chrome/browser/resources/md_downloads/crisper.js b/chrome/browser/resources/md_downloads/crisper.js index d6c6389..d0a64e3 100644 --- a/chrome/browser/resources/md_downloads/crisper.js +++ b/chrome/browser/resources/md_downloads/crisper.js
@@ -10844,12 +10844,12 @@ }, /** @private */ - onCancelClick_: function() { + onCancelTap_: function() { downloads.ActionService.getInstance().cancel(this.data.id); }, /** @private */ - onDiscardDangerous_: function() { + onDiscardDangerousTap_: function() { downloads.ActionService.getInstance().discardDangerous(this.data.id); }, @@ -10866,38 +10866,38 @@ * @param {Event} e * @private */ - onFileLinkClick_: function(e) { + onFileLinkTap_: function(e) { e.preventDefault(); downloads.ActionService.getInstance().openFile(this.data.id); }, /** @private */ - onPauseClick_: function() { + onPauseTap_: function() { downloads.ActionService.getInstance().pause(this.data.id); }, /** @private */ - onRemoveClick_: function() { + onRemoveTap_: function() { downloads.ActionService.getInstance().remove(this.data.id); }, /** @private */ - onResumeClick_: function() { + onResumeTap_: function() { downloads.ActionService.getInstance().resume(this.data.id); }, /** @private */ - onRetryClick_: function() { + onRetryTap_: function() { downloads.ActionService.getInstance().download(this.data.url); }, /** @private */ - onSaveDangerous_: function() { + onSaveDangerousTap_: function() { downloads.ActionService.getInstance().saveDangerous(this.data.id); }, /** @private */ - onShowClick_: function() { + onShowTap_: function() { downloads.ActionService.getInstance().show(this.data.id); }, }); @@ -15378,7 +15378,7 @@ }, /** @private */ - onClearAllClick_: function() { + onClearAllTap_: function() { assert(this.canClearAll()); downloads.ActionService.getInstance().clearAll(); }, @@ -15395,7 +15395,7 @@ }, /** @private */ - onOpenDownloadsFolderClick_: function() { + onOpenDownloadsFolderTap_: function() { downloads.ActionService.getInstance().openDownloadsFolder(); },
diff --git a/chrome/browser/resources/md_downloads/item.html b/chrome/browser/resources/md_downloads/item.html index 1d6dfa3..c090672 100644 --- a/chrome/browser/resources/md_downloads/item.html +++ b/chrome/browser/resources/md_downloads/item.html
@@ -26,7 +26,7 @@ <div id="title-area"><!-- Can't have any line breaks. --><a is="action-link" id="file-link" href="[[data.url]]" - on-click="onFileLinkClick_" + on-tap="onFileLinkTap_" hidden="[[!completelyOnDisk_]]">[[data.file_name]]</a><!-- Before #name. --><span id="name" @@ -46,22 +46,22 @@ <div id="safe" class="controls" hidden="[[isDangerous_]]"> <a is="action-link" id="show" i18n-content="controlShowInFolder" - on-click="onShowClick_" hidden="[[!completelyOnDisk_]]"></a> + on-tap="onShowTap_" hidden="[[!completelyOnDisk_]]"></a> <template is="dom-if" if="[[data.retry]]"> <paper-button id="retry" - on-click="onRetryClick_">[[i18n_.retry]]</paper-button> + on-tap="onRetryTap_">[[i18n_.retry]]</paper-button> </template> <template is="dom-if" if="[[isInProgress_]]"> <paper-button id="pause" - on-click="onPauseClick_">[[i18n_.pause]]</paper-button> + on-tap="onPauseTap_">[[i18n_.pause]]</paper-button> </template> <template is="dom-if" if="[[data.resume]]"> <paper-button id="resume" - on-click="onResumeClick_">[[i18n_.resume]]</paper-button> + on-tap="onResumeTap_">[[i18n_.resume]]</paper-button> </template> <template is="dom-if" if="[[showCancel_]]"> <paper-button id="cancel" - on-click="onCancelClick_">[[i18n_.cancel]]</paper-button> + on-tap="onCancelTap_">[[i18n_.cancel]]</paper-button> </template> <span id="controlled-by"><!-- Text populated dynamically. --></span> </div> @@ -70,17 +70,17 @@ <div id="dangerous" class="controls"> <!-- Dangerous file types (e.g. .exe, .jar). --> <template is="dom-if" if="[[!isMalware_]]"> - <paper-button id="discard" on-click="onDiscardDangerous_" + <paper-button id="discard" on-tap="onDiscardDangerousTap_" class="discard">[[i18n_.discard]]</paper-button> - <paper-button id="save" on-click="onSaveDangerous_" + <paper-button id="save" on-tap="onSaveDangerousTap_" class="keep">[[i18n_.save]]</paper-button> </template> <!-- Things that safe browsing has determined to be dangerous. --> <template is="dom-if" if="[[isMalware_]]"> - <paper-button id="danger-remove" on-click="onDiscardDangerous_" + <paper-button id="danger-remove" on-tap="onDiscardDangerousTap_" class="discard">[[i18n_.remove]]</paper-button> - <paper-button id="restore" on-click="onSaveDangerous_" + <paper-button id="restore" on-tap="onSaveDangerousTap_" class="keep">[[i18n_.restore]</paper-button> </template> </div> @@ -91,7 +91,7 @@ <paper-icon-button id="remove" icon="clear" i18n-values="title:controlRemoveFromList" style$="[[computeRemoveStyle_(isDangerous_, showCancel_)]]" - on-click="onRemoveClick_"></paper-icon-button> + on-tap="onRemoveTap_"></paper-icon-button> </div> <div id="incognito" i18n-values="title:inIncognito"
diff --git a/chrome/browser/resources/md_downloads/item.js b/chrome/browser/resources/md_downloads/item.js index a750e61..7b8d0079 100644 --- a/chrome/browser/resources/md_downloads/item.js +++ b/chrome/browser/resources/md_downloads/item.js
@@ -263,12 +263,12 @@ }, /** @private */ - onCancelClick_: function() { + onCancelTap_: function() { downloads.ActionService.getInstance().cancel(this.data.id); }, /** @private */ - onDiscardDangerous_: function() { + onDiscardDangerousTap_: function() { downloads.ActionService.getInstance().discardDangerous(this.data.id); }, @@ -285,38 +285,38 @@ * @param {Event} e * @private */ - onFileLinkClick_: function(e) { + onFileLinkTap_: function(e) { e.preventDefault(); downloads.ActionService.getInstance().openFile(this.data.id); }, /** @private */ - onPauseClick_: function() { + onPauseTap_: function() { downloads.ActionService.getInstance().pause(this.data.id); }, /** @private */ - onRemoveClick_: function() { + onRemoveTap_: function() { downloads.ActionService.getInstance().remove(this.data.id); }, /** @private */ - onResumeClick_: function() { + onResumeTap_: function() { downloads.ActionService.getInstance().resume(this.data.id); }, /** @private */ - onRetryClick_: function() { + onRetryTap_: function() { downloads.ActionService.getInstance().download(this.data.url); }, /** @private */ - onSaveDangerous_: function() { + onSaveDangerousTap_: function() { downloads.ActionService.getInstance().saveDangerous(this.data.id); }, /** @private */ - onShowClick_: function() { + onShowTap_: function() { downloads.ActionService.getInstance().show(this.data.id); }, });
diff --git a/chrome/browser/resources/md_downloads/toolbar.html b/chrome/browser/resources/md_downloads/toolbar.html index 5161a21..53234f8 100644 --- a/chrome/browser/resources/md_downloads/toolbar.html +++ b/chrome/browser/resources/md_downloads/toolbar.html
@@ -17,9 +17,9 @@ </div> <div id="actions"> <paper-button class="clear-all" i18n-content="clearAll" - on-click="onClearAllClick_"></paper-button> + on-tap="onClearAllTap_"></paper-button> <paper-button i18n-content="openDownloadsFolder" - on-click="onOpenDownloadsFolderClick_"></paper-button> + on-tap="onOpenDownloadsFolderTap_"></paper-button> </div> <div id="search"> <cr-search-field id="search-input" @@ -29,9 +29,9 @@ class="dropdown-trigger"></paper-icon-button> <paper-menu class="dropdown-content"> <paper-item class="clear-all" i18n-content="clearAll" - on-click="onClearAllClick_"></paper-item> + on-tap="onClearAllTap_"></paper-item> <paper-item i18n-content="openDownloadsFolder" - on-click="onOpenDownloadsFolderClick_"></paper-item> + on-tap="onOpenDownloadsFolderTap_"></paper-item> </paper-menu> </paper-menu-button> </div>
diff --git a/chrome/browser/resources/md_downloads/toolbar.js b/chrome/browser/resources/md_downloads/toolbar.js index f9437c02..ff9173e 100644 --- a/chrome/browser/resources/md_downloads/toolbar.js +++ b/chrome/browser/resources/md_downloads/toolbar.js
@@ -40,7 +40,7 @@ }, /** @private */ - onClearAllClick_: function() { + onClearAllTap_: function() { assert(this.canClearAll()); downloads.ActionService.getInstance().clearAll(); }, @@ -57,7 +57,7 @@ }, /** @private */ - onOpenDownloadsFolderClick_: function() { + onOpenDownloadsFolderTap_: function() { downloads.ActionService.getInstance().openDownloadsFolder(); },
diff --git a/chrome/browser/resources/md_downloads/vulcanize_readme.md b/chrome/browser/resources/md_downloads/vulcanize_readme.md index 858d6f06..1a20f9c 100644 --- a/chrome/browser/resources/md_downloads/vulcanize_readme.md +++ b/chrome/browser/resources/md_downloads/vulcanize_readme.md
@@ -7,6 +7,7 @@ ## Required software Vulcanization currently requires: + - node.js: v0.10.25 (can be found with `node --version`) - npm: 1.3.10 (can be found with `npm --version`) - vulcanize: 1.12.3 (can be found with `vulcanize --version`)
diff --git a/chrome/browser/resources/md_downloads/vulcanized.html b/chrome/browser/resources/md_downloads/vulcanized.html index fe3dd30..37e4737 100644 --- a/chrome/browser/resources/md_downloads/vulcanized.html +++ b/chrome/browser/resources/md_downloads/vulcanized.html
@@ -2130,7 +2130,7 @@ </div> <div id="details"> - <div id="title-area"><a is="action-link" id="file-link" href="[[data.url]]" on-click="onFileLinkClick_" hidden="[[!completelyOnDisk_]]">[[data.file_name]]</a><span id="name" hidden="[[completelyOnDisk_]]">[[data.file_name]]</span> + <div id="title-area"><a is="action-link" id="file-link" href="[[data.url]]" on-tap="onFileLinkTap_" hidden="[[!completelyOnDisk_]]">[[data.file_name]]</a><span id="name" hidden="[[completelyOnDisk_]]">[[data.file_name]]</span> <span id="tag">[[computeTag_(data.state, data.last_reason_text, data.file_externally_removed)]]</span> </div> @@ -2143,18 +2143,18 @@ </template> <div id="safe" class="controls" hidden="[[isDangerous_]]"> - <a is="action-link" id="show" i18n-content="controlShowInFolder" on-click="onShowClick_" hidden="[[!completelyOnDisk_]]"></a> + <a is="action-link" id="show" i18n-content="controlShowInFolder" on-tap="onShowTap_" hidden="[[!completelyOnDisk_]]"></a> <template is="dom-if" if="[[data.retry]]"> - <paper-button id="retry" on-click="onRetryClick_">[[i18n_.retry]]</paper-button> + <paper-button id="retry" on-tap="onRetryTap_">[[i18n_.retry]]</paper-button> </template> <template is="dom-if" if="[[isInProgress_]]"> - <paper-button id="pause" on-click="onPauseClick_">[[i18n_.pause]]</paper-button> + <paper-button id="pause" on-tap="onPauseTap_">[[i18n_.pause]]</paper-button> </template> <template is="dom-if" if="[[data.resume]]"> - <paper-button id="resume" on-click="onResumeClick_">[[i18n_.resume]]</paper-button> + <paper-button id="resume" on-tap="onResumeTap_">[[i18n_.resume]]</paper-button> </template> <template is="dom-if" if="[[showCancel_]]"> - <paper-button id="cancel" on-click="onCancelClick_">[[i18n_.cancel]]</paper-button> + <paper-button id="cancel" on-tap="onCancelTap_">[[i18n_.cancel]]</paper-button> </template> <span id="controlled-by"></span> </div> @@ -2163,21 +2163,21 @@ <div id="dangerous" class="controls"> <template is="dom-if" if="[[!isMalware_]]"> - <paper-button id="discard" on-click="onDiscardDangerous_" class="discard">[[i18n_.discard]]</paper-button> - <paper-button id="save" on-click="onSaveDangerous_" class="keep">[[i18n_.save]]</paper-button> + <paper-button id="discard" on-tap="onDiscardDangerousTap_" class="discard">[[i18n_.discard]]</paper-button> + <paper-button id="save" on-tap="onSaveDangerousTap_" class="keep">[[i18n_.save]]</paper-button> </template> <template is="dom-if" if="[[isMalware_]]"> - <paper-button id="danger-remove" on-click="onDiscardDangerous_" class="discard">[[i18n_.remove]]</paper-button> - <paper-button id="restore" on-click="onSaveDangerous_" class="keep">[[i18n_.restore]</paper-button> + <paper-button id="danger-remove" on-tap="onDiscardDangerousTap_" class="discard">[[i18n_.remove]]</paper-button> + <paper-button id="restore" on-tap="onSaveDangerousTap_" class="keep">[[i18n_.restore]</paper-button> </template> </div> </template> </div> <div id="remove-wrapper" class="icon-wrapper"> - <paper-icon-button id="remove" icon="clear" i18n-values="title:controlRemoveFromList" style$="[[computeRemoveStyle_(isDangerous_, showCancel_)]]" on-click="onRemoveClick_"></paper-icon-button> + <paper-icon-button id="remove" icon="clear" i18n-values="title:controlRemoveFromList" style$="[[computeRemoveStyle_(isDangerous_, showCancel_)]]" on-tap="onRemoveTap_"></paper-icon-button> </div> <div id="incognito" i18n-values="title:inIncognito" hidden="[[!data.otr]]"></div> @@ -3254,16 +3254,16 @@ <h1 i18n-content="title"></h1> </div> <div id="actions"> - <paper-button class="clear-all" i18n-content="clearAll" on-click="onClearAllClick_"></paper-button> - <paper-button i18n-content="openDownloadsFolder" on-click="onOpenDownloadsFolderClick_"></paper-button> + <paper-button class="clear-all" i18n-content="clearAll" on-tap="onClearAllTap_"></paper-button> + <paper-button i18n-content="openDownloadsFolder" on-tap="onOpenDownloadsFolderTap_"></paper-button> </div> <div id="search"> <cr-search-field id="search-input" i18n-values="label:search;clear-label:clearSearch"></cr-search-field> <paper-menu-button id="more" horizontal-align="[[overflowAlign_]]"> <paper-icon-button icon="more-vert" i18n-values="title:moreActions" class="dropdown-trigger"></paper-icon-button> <paper-menu class="dropdown-content"> - <paper-item class="clear-all" i18n-content="clearAll" on-click="onClearAllClick_"></paper-item> - <paper-item i18n-content="openDownloadsFolder" on-click="onOpenDownloadsFolderClick_"></paper-item> + <paper-item class="clear-all" i18n-content="clearAll" on-tap="onClearAllTap_"></paper-item> + <paper-item i18n-content="openDownloadsFolder" on-tap="onOpenDownloadsFolderTap_"></paper-item> </paper-menu> </paper-menu-button> </div>
diff --git a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html index f65ae61e..f110a3c6 100644 --- a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html +++ b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html
@@ -39,7 +39,7 @@ <paper-menu id="cast-mode-list" hidden$="[[computeCastModeHidden_(currentView_)]]"> <template is="dom-repeat" id="defaultCastModeList" - items="[[computeDefaultCastModeList_(castModeList)]]"> + items="[[computeDefaultCastModeList_(castModeList_)]]"> <paper-item on-click="onCastModeClick_"> <iron-icon class="cast-mode-icon" icon="[[computeCastModeIcon_(item)]]"> @@ -48,11 +48,11 @@ </paper-item> </template> <div id="share-screen-text" - hidden$="[[computeShareScreenSubheadingHidden_(castModeList)]]"> + hidden$="[[computeShareScreenSubheadingHidden_(castModeList_)]]"> <span>[[shareYourScreenSubheadingText_]]</span> </div> <template is="dom-repeat" id="nonDefaultCastModeList" - items="[[computeNonDefaultCastModeList_(castModeList)]]"> + items="[[computeNonDefaultCastModeList_(castModeList_)]]"> <paper-item on-click="onCastModeClick_"> <iron-icon class="cast-mode-icon" icon="[[computeCastModeIcon_(item)]]"> @@ -70,7 +70,7 @@ <div id="sink-list-view" hidden$="[[computeSinkListViewHidden_(currentView_, issue)]]"> <div id="device-missing" - hidden$="[[!computeSinkListHidden_(sinkList)]]"> + hidden$="[[!computeSinkListHidden_(sinksToShow_)]]"> <paper-spinner id="searching-devices-spinner" active hidden$="[[computeSpinnerHidden_(justOpened_)]]"> </paper-spinner> @@ -81,7 +81,7 @@ </div> <paper-menu id="sink-list" hidden$="[[computeSinkListHidden_(currentView_, issue)]]"> - <template is="dom-repeat" id="sinkList" items="[[sinkList]]"> + <template is="dom-repeat" id="sinkList" items="[[sinksToShow_]]"> <paper-item class="sink" on-click="onSinkClick_"> <div class="sink-content"> <div>
diff --git a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js index 0a98d75..3e2b959 100644 --- a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js +++ b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
@@ -9,15 +9,6 @@ properties: { /** - * The list of CastModes to show. - * @type {!Array<!media_router.CastMode>} - */ - castModeList: { - type: Array, - value: [], - }, - - /** * The possible states of media-router-container. Used to determine which * components of media-router-container to show. * This is a property of media-router-container because it is used in @@ -38,6 +29,26 @@ }, /** + * The list of available sinks. + * @type {!Array<!media_router.Sink>} + */ + allSinks: { + type: Array, + value: [], + observer: 'reindexSinksAndRebuildSinksToShow_', + }, + + /** + * The list of CastModes to show. + * @private {!Array<!media_router.CastMode>} + */ + castModeList_: { + type: Array, + value: [], + observer: 'checkCurrentCastMode_', + }, + + /** * The ID of the Sink currently being launched. * @private {string} */ @@ -158,14 +169,11 @@ }, /** - * The value of the selected cast mode in |castModeList|, or -1 if the - * user has not explicitly selected a cast mode. + * The value of the selected cast mode in |castModeList_|. * @private {number} */ selectedCastModeValue_: { type: Number, - value: -1, - observer: 'showSinkList_', }, /** @@ -178,16 +186,6 @@ }, /** - * The list of available sinks. - * @type {!Array<!media_router.Sink>} - */ - sinkList: { - type: Array, - value: [], - observer: 'rebuildSinkMap_', - }, - - /** * Maps media_router.Sink.id to corresponding media_router.Sink. * @private {!Object<!string, !media_router.Sink>} */ @@ -198,12 +196,21 @@ /** * Maps media_router.Sink.id to corresponding media_router.Route. - * @private {!Object<!string, ?media_router.Route>} + * @private {!Object<!string, !media_router.Route>} */ sinkToRouteMap_: { type: Object, value: {}, }, + + /** + * Sinks to show for the currently selected cast mode. + * @private {!Array<!media_router.Sink>} + */ + sinksToShow_: { + type: Array, + value: [], + }, }, ready: function() { @@ -219,6 +226,18 @@ }, /** + * Checks that the currently selected cast mode is still in the + * updated list of available cast modes. If not, then update the selected + * cast mode to the first available cast mode on the list. + */ + checkCurrentCastMode_: function() { + if (this.castModeList_.length > 0 && + !this.findCastModeByType_(this.selectedCastModeValue_)) { + this.setSelectedCastMode_(this.castModeList_[0]); + } + }, + + /** * @param {CONTAINER_VIEW_} view The current view. * @return {string} The current arrow-drop-* icon to use. * @private @@ -242,7 +261,7 @@ * icon for. * @return {string} The Polymer <iron-icon> icon to use. The format is * <iconset>:<icon>, where <iconset> is the set ID and <icon> is the name - * of the icon. <iconset>: may be ommitted if <icon> is from the default + * of the icon. <iconset>: may be omitted if <icon> is from the default * set. * @private */ @@ -425,8 +444,8 @@ * @return {boolean} Whether or not to hide the sink list. * @private */ - computeSinkListHidden_: function(sinkList) { - return sinkList.length == 0; + computeSinkListHidden_: function(sinksToShow) { + return sinksToShow.length == 0; }, /** @@ -450,6 +469,37 @@ }, /** + * Helper function to locate the CastMode object with the given type in + * castModeList. + * + * @param {number} castModeType Type of cast mode to look for. + * @return {?media_router.CastMode} CastMode object with the given type in + * castModeList, or undefined if not found. + */ + findCastModeByType_: function(castModeType) { + return this.castModeList_.find(function(element, index, array) { + return element.type == castModeType; + }); + }, + + /** + * Sets the list of available cast modes and the initial cast mode. + * + * @param {!Array<!media_router.CastMode>} availableCastModes The list + * of available cast modes. + * @param {number} initialCastModeType The initial cast mode when dialog is + * opened. + */ + initializeCastModes: function(availableCastModes, initialCastModeType) { + this.castModeList_ = availableCastModes; + var castMode = this.findCastModeByType_(initialCastModeType); + if (!castMode) + return; + + this.setSelectedCastMode_(castMode); + }, + + /** * Updates |currentView_| if the dialog had just opened and there's * only one local route. * @@ -478,9 +528,8 @@ if (!clickedMode) return; - this.headerText = clickedMode.description; - this.headerTextTooltip = clickedMode.host; - this.selectedCastModeValue_ = clickedMode.type; + this.setSelectedCastMode_(clickedMode); + this.showSinkList_(); }, /** @@ -577,19 +626,53 @@ this.sinkToRouteMap_ = tempSinkToRouteMap; this.maybeShowRouteDetailsOnOpen_(localRoute); + this.rebuildSinksToShow_(); }, /** - * Called when |sinkList| is updated. Rebuilds |sinkMap_|. + * Rebuilds the list of sinks to be shown for the current cast mode. + * A sink should be shown if it is compatible with the current cast mode, or + * if the sink is associated with a route. + */ + rebuildSinksToShow_: function() { + var sinksToShow = []; + this.allSinks.forEach(function(element, index, array) { + if (element.castModes.indexOf(this.selectedCastModeValue_) != -1 || + this.sinkToRouteMap_[element.id]) { + sinksToShow.push(element); + } + }, this); + this.sinksToShow_ = sinksToShow; + }, + + /** + * Called when |allSinks| is updated. * * @private */ - rebuildSinkMap_: function() { + reindexSinksAndRebuildSinksToShow_: function() { this.sinkMap_ = {}; - this.sinkList.forEach(function(sink) { + this.allSinks.forEach(function(sink) { this.sinkMap_[sink.id] = sink; }, this); + + this.rebuildSinksToShow_(); + }, + + /** + * Updates the selected cast mode, and updates the header text fields + * according to the cast mode. + * + * @param {!media_router.CastMode} castMode + */ + setSelectedCastMode_: function(castMode) { + if (castMode.type != this.selectedCastModeValue_) { + this.headerText = castMode.description; + this.headerTextTooltip = castMode.host; + this.selectedCastModeValue_ = castMode.type; + this.rebuildSinksToShow_(); + } }, /**
diff --git a/chrome/browser/resources/media_router/media_router_ui_interface.js b/chrome/browser/resources/media_router/media_router_ui_interface.js index 78008e10..7406159 100644 --- a/chrome/browser/resources/media_router/media_router_ui_interface.js +++ b/chrome/browser/resources/media_router/media_router_ui_interface.js
@@ -50,27 +50,25 @@ /** * Populates the WebUI with data obtained from Media Router. * - * @param {headerText: string, - * headerTextTooltip: string, - * deviceMissingUrl: string, + * @param {deviceMissingUrl: string, * sinks: !Array<!media_router.Sink>, * routes: !Array<!media_router.Route>, - * castModes: !Array<!media_router.CastMode>} data + * castModes: !Array<!media_router.CastMode>, + * initialCastModeType: number} data * Parameters in data: - * headerText - text to be displayed in the header of the WebUI. - * headerTextTooltip - tooltip to be displayed for the header of the WebUI. * deviceMissingUrl - url to be opened on "Device missing?" clicked. * sinks - list of sinks to be displayed. * routes - list of routes that are associated with the sinks. * castModes - list of available cast modes. + * initialCastModeType - cast mode to show initially. Expected to be + * included in |castModes|. */ function setInitialData(data) { - container.headerText = data['headerText']; - container.headerTextTooltip = data['headerTextTooltip']; container.deviceMissingUrl = data['deviceMissingUrl']; - container.sinkList = data['sinks']; + container.allSinks = data['sinks']; container.routeList = data['routes']; - container.castModeList = data['castModes']; + container.initializeCastModes(data['castModes'], + data['initialCastModeType']); } /** @@ -98,7 +96,7 @@ * @param {!Array<!media_router.Sink>} sinkList */ function setSinkList(sinkList) { - container.sinkList = sinkList; + container.allSinks = sinkList; } return { @@ -158,7 +156,7 @@ * * @param {string} sinkId The sink ID. * @param {number} selectedCastMode The value of the cast mode the user - * selected, or -1 if the user has not explicitly selected a mode. + * selected. */ function requestRoute(sinkId, selectedCastMode) { chrome.send('requestRoute',
diff --git a/chrome/browser/resources/settings/a11y_page/a11y_page.html b/chrome/browser/resources/settings/a11y_page/a11y_page.html index d7ae920..5afc4c7 100644 --- a/chrome/browser/resources/settings/a11y_page/a11y_page.html +++ b/chrome/browser/resources/settings/a11y_page/a11y_page.html
@@ -2,7 +2,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://md-settings/controls/settings_checkbox.html"> -<dom-module id="cr-settings-a11y-page"> +<dom-module id="settings-a11y-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css" href="a11y_page.css"> <template>
diff --git a/chrome/browser/resources/settings/a11y_page/a11y_page.js b/chrome/browser/resources/settings/a11y_page/a11y_page.js index f7286ad..8fb7448 100644 --- a/chrome/browser/resources/settings/a11y_page/a11y_page.js +++ b/chrome/browser/resources/settings/a11y_page/a11y_page.js
@@ -4,21 +4,21 @@ /** * @fileoverview - * 'cr-settings-a11y-page' is the settings page containing accessibility + * 'settings-a11y-page' is the settings page containing accessibility * settings. * * Example: * * <iron-animated-pages> - * <cr-settings-a11y-page prefs="{{prefs}}"></cr-settings-a11y-page> + * <settings-a11y-page prefs="{{prefs}}"></settings-a11y-page> * ... other pages ... * </iron-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-a11y-page + * @element settings-a11y-page */ Polymer({ - is: 'cr-settings-a11y-page', + is: 'settings-a11y-page', properties: { /**
diff --git a/chrome/browser/resources/settings/advanced_page/advanced_page.html b/chrome/browser/resources/settings/advanced_page/advanced_page.html index ae69661b..30eb95d 100644 --- a/chrome/browser/resources/settings/advanced_page/advanced_page.html +++ b/chrome/browser/resources/settings/advanced_page/advanced_page.html
@@ -10,40 +10,40 @@ <link rel="import" href="chrome://md-settings/date_time_page/date_time_page.html"> </if> -<dom-module id="cr-settings-advanced-page"> +<dom-module id="settings-advanced-page"> <link rel="import" type="css" href="advanced_page.css"> <template> <if expr="chromeos"> <settings-section i18n-values="page-title:dateTimePageTitle" current-route="[[currentRoute]]" section="dateTime"> - <cr-settings-date-time-page prefs="{{prefs}}"> - </cr-settings-date-time-page> + <settings-date-time-page prefs="{{prefs}}"> + </settings-date-time-page> </settings-section> </if> <settings-section i18n-values="page-title:siteSettingsLocation" current-route="[[currentRoute]]" section="location"> - <cr-settings-location-page prefs="{{prefs}}"> - </cr-settings-location-page> + <settings-location-page prefs="{{prefs}}"> + </settings-location-page> </settings-section> <settings-section i18n-values="page-title:privacyPageTitle" current-route="[[currentRoute]]" section="privacy"> - <cr-settings-privacy-page prefs="{{prefs}}" + <settings-privacy-page prefs="{{prefs}}" current-route="{{currentRoute}}"> - </cr-settings-privacy-page> + </settings-privacy-page> </settings-section> <settings-section i18n-values="page-title:languagesPageTitle" current-route="[[currentRoute]]" section="languages"> - <cr-settings-languages-page prefs="{{prefs}}" + <settings-languages-page prefs="{{prefs}}" current-route="{{currentRoute}}"> - </cr-settings-languages-page> + </settings-languages-page> </settings-section> <settings-section i18n-values="page-title:downloadsPageTitle" current-route="[[currentRoute]]" section="downloads"> - <cr-settings-downloads-page prefs="{{prefs}}"> - </cr-settings-downloads-page> + <settings-downloads-page prefs="{{prefs}}"> + </settings-downloads-page> </settings-section> <if expr="chromeos"> @@ -51,7 +51,7 @@ on desktop. --> <settings-section i18n-values="page-title:a11yPageTitle" current-route="[[currentRoute]]" section="a11y"> - <cr-settings-a11y-page prefs="{{prefs}}"></cr-settings-a11y-page> + <settings-a11y-page prefs="{{prefs}}"></settings-a11y-page> </settings-section> </if> </template>
diff --git a/chrome/browser/resources/settings/advanced_page/advanced_page.js b/chrome/browser/resources/settings/advanced_page/advanced_page.js index 0943c0dd..92be225 100644 --- a/chrome/browser/resources/settings/advanced_page/advanced_page.js +++ b/chrome/browser/resources/settings/advanced_page/advanced_page.js
@@ -4,22 +4,22 @@ /** * @fileoverview - * 'cr-settings-advanced-page' is the settings page containing the advanced + * 'settings-advanced-page' is the settings page containing the advanced * settings. * * Example: * * <iron-animated-pages> - * <cr-settings-advanced-page prefs="{{prefs}}"> - * </cr-settings-advanced-page> + * <settings-advanced-page prefs="{{prefs}}"> + * </settings-advanced-page> * ... other pages ... * </iron-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-advanced-page + * @element settings-advanced-page */ Polymer({ - is: 'cr-settings-advanced-page', + is: 'settings-advanced-page', properties: { /**
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_page.html b/chrome/browser/resources/settings/appearance_page/appearance_page.html index 144db018..769d362 100644 --- a/chrome/browser/resources/settings/appearance_page/appearance_page.html +++ b/chrome/browser/resources/settings/appearance_page/appearance_page.html
@@ -5,7 +5,7 @@ <link rel="import" href="chrome://md-settings/controls/settings_input.html"> <link rel="import" href="chrome://md-settings/controls/settings_radio_group.html"> -<dom-module id="cr-settings-appearance-page"> +<dom-module id="settings-appearance-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css"
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_page.js b/chrome/browser/resources/settings/appearance_page/appearance_page.js index d12a1acc..e3a3bff 100644 --- a/chrome/browser/resources/settings/appearance_page/appearance_page.js +++ b/chrome/browser/resources/settings/appearance_page/appearance_page.js
@@ -3,22 +3,22 @@ // found in the LICENSE file. /** - * 'cr-settings-appearance-page' is the settings page containing appearance + * 'settings-appearance-page' is the settings page containing appearance * settings. * * Example: * * <iron-animated-pages> - * <cr-settings-appearance-page prefs="{{prefs}}"> - * </cr-settings-appearance-page> + * <settings-appearance-page prefs="{{prefs}}"> + * </settings-appearance-page> * ... other pages ... * </iron-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-appearance-page + * @element settings-appearance-page */ Polymer({ - is: 'cr-settings-appearance-page', + is: 'settings-appearance-page', properties: { /**
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.html b/chrome/browser/resources/settings/basic_page/basic_page.html index 843a322b..cf63ca38 100644 --- a/chrome/browser/resources/settings/basic_page/basic_page.html +++ b/chrome/browser/resources/settings/basic_page/basic_page.html
@@ -13,7 +13,7 @@ <link rel="import" href="chrome://md-settings/signin_page/signin_page.html"> </if> -<dom-module id="cr-settings-basic-page"> +<dom-module id="settings-basic-page"> <link rel="import" type="css" href="basic_page.css"> <template> <if expr="not chromeos"> @@ -26,33 +26,33 @@ <if expr="chromeos"> <settings-section i18n-values="page-title:internetPageTitle" current-route="[[currentRoute]]" section="internet"> - <cr-settings-internet-page current-route="{{currentRoute}}"> - </cr-settings-internet-page> + <settings-internet-page current-route="{{currentRoute}}"> + </settings-internet-page> </settings-section> </if> <settings-section i18n-values="page-title:appearancePageTitle" current-route="[[currentRoute]]" section="appearance"> - <cr-settings-appearance-page prefs="{{prefs}}"> - </cr-settings-appearance-page> + <settings-appearance-page prefs="{{prefs}}"> + </settings-appearance-page> </settings-section> <settings-section i18n-values="page-title:onStartup" current-route="[[currentRoute]]" section="on-startup"> - <cr-settings-on-startup-page + <settings-on-startup-page prefs="{{prefs}}" current-route="{{currentRoute}}"> - </cr-settings-on-startup-page> + </settings-on-startup-page> </settings-section> <settings-section i18n-values="page-title:searchPageTitle" current-route="[[currentRoute]]" section="search"> - <cr-settings-search-page current-route="{{currentRoute}}"> - </cr-settings-search-page> + <settings-search-page current-route="{{currentRoute}}"> + </settings-search-page> </settings-section> <if expr="chromeos"> <settings-section i18n-values="page-title:usersPageTitle" current-route="[[currentRoute]]" section="users"> - <cr-settings-users-page prefs="{{prefs}}"></cr-settings-users-page> + <settings-users-page prefs="{{prefs}}"></settings-users-page> </settings-section> </if> </template>
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.js b/chrome/browser/resources/settings/basic_page/basic_page.js index 024794ac..c23e61b 100644 --- a/chrome/browser/resources/settings/basic_page/basic_page.js +++ b/chrome/browser/resources/settings/basic_page/basic_page.js
@@ -4,20 +4,20 @@ /** * @fileoverview - * 'cr-settings-basic-page' is the settings page containing the basic settings. + * 'settings-basic-page' is the settings page containing the basic settings. * * Example: * * <iron-animated-pages> - * <cr-settings-basic-page prefs="{{prefs}}"></cr-settings-basic-page> + * <settings-basic-page prefs="{{prefs}}"></settings-basic-page> * ... other pages ... * </iron-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-basic-page + * @element settings-basic-page */ Polymer({ - is: 'cr-settings-basic-page', + is: 'settings-basic-page', properties: { /**
diff --git a/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.html b/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.html index 3c120ef..70a5b6ea 100644 --- a/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.html +++ b/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.html
@@ -3,7 +3,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-tabs/paper-tabs.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-pages/iron-pages.html"> -<dom-module id="cr-settings-certificate-manager-page"> +<dom-module id="settings-certificate-manager-page"> <link rel="import" type="css" href="certificate_manager_page.css"> <template> <paper-tabs selected="{{selected}}">
diff --git a/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.js b/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.js index 253e283..8c9f3134 100644 --- a/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.js +++ b/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.js
@@ -4,22 +4,22 @@ /** * @fileoverview - * 'cr-settings-certificate-manager-page' is the settings page containing SSL + * 'settings-certificate-manager-page' is the settings page containing SSL * certificate settings. * * Example: * * <iron-animated-pages> - * <cr-settings-certificate-manager-page prefs="{{prefs}}"> - * </cr-settings-certificate-manager-page> + * <settings-certificate-manager-page prefs="{{prefs}}"> + * </settings-certificate-manager-page> * ... other pages ... * </iron-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-certificate-manager-page + * @element settings-certificate-manager-page */ Polymer({ - is: 'cr-settings-certificate-manager-page', + is: 'settings-certificate-manager-page', properties: { /**
diff --git a/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.html b/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.html index e4c0488..03d9915 100644 --- a/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.html +++ b/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.html
@@ -5,7 +5,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-dropdown-menu/paper-dropdown-menu.html"> <link rel="import" href="chrome://md-settings/controls/settings_checkbox.html"> -<dom-module id="cr-settings-clear-browsing-data-page"> +<dom-module id="settings-clear-browsing-data-page"> <link rel="import" type="css" href="clear_browsing_data_page.css"> <template> <div>
diff --git a/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.js b/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.js index df6ae06..7e76486 100644 --- a/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.js +++ b/chrome/browser/resources/settings/clear_browsing_data_page/clear_browsing_data_page.js
@@ -4,22 +4,22 @@ /** * @fileoverview - * 'cr-settings-clear-browsing-data-page' provides options to delete browsing + * 'settings-clear-browsing-data-page' provides options to delete browsing * data that has been cached by chromium. * * Example: * * <iron-animated-pages> - * <cr-settings-clear-browsing-data-page prefs="{{prefs}}"> - * </cr-settings-clear-browsing-data-page> + * <settings-clear-browsing-data-page prefs="{{prefs}}"> + * </settings-clear-browsing-data-page> * ... other pages ... * </iron-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-privacy-page + * @element settings-privacy-page */ Polymer({ - is: 'cr-settings-clear-browsing-data-page', + is: 'settings-clear-browsing-data-page', properties: { /**
diff --git a/chrome/browser/resources/settings/controls/settings_checkbox.html b/chrome/browser/resources/settings/controls/settings_checkbox.html index 133f839..25a3cae 100644 --- a/chrome/browser/resources/settings/controls/settings_checkbox.html +++ b/chrome/browser/resources/settings/controls/settings_checkbox.html
@@ -9,7 +9,7 @@ <link rel="import" type="css" href="settings_checkbox.css"> <template> <cr-events id="events"></cr-events> - <cr-settings-pref-tracker pref="[[pref]]"></cr-settings-pref-tracker> + <settings-pref-tracker pref="[[pref]]"></settings-pref-tracker> <div id="outerDiv" class="layout horizontal center"> <paper-checkbox id="checkbox" checked="{{checked}}"
diff --git a/chrome/browser/resources/settings/controls/settings_input.html b/chrome/browser/resources/settings/controls/settings_input.html index 055d7986..3db53397 100644 --- a/chrome/browser/resources/settings/controls/settings_input.html +++ b/chrome/browser/resources/settings/controls/settings_input.html
@@ -8,7 +8,7 @@ <link rel="import" type="css" href="settings_input.css"> <template> <cr-events id="events"></cr-events> - <cr-settings-pref-tracker pref="[[pref]]"></cr-settings-pref-tracker> + <settings-pref-tracker pref="[[pref]]"></settings-pref-tracker> <div id="outerDiv" class="layout horizontal center"> <paper-input id="input" auto-validate value="{{value}}"
diff --git a/chrome/browser/resources/settings/date_time_page/date_time_page.html b/chrome/browser/resources/settings/date_time_page/date_time_page.html index fa80295..6363c3f32 100644 --- a/chrome/browser/resources/settings/date_time_page/date_time_page.html +++ b/chrome/browser/resources/settings/date_time_page/date_time_page.html
@@ -2,7 +2,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html"> <link rel="import" href="chrome://md-settings/controls/settings_checkbox.html"> -<dom-module id="cr-settings-date-time-page"> +<dom-module id="settings-date-time-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css" href="date_time_page.css">
diff --git a/chrome/browser/resources/settings/date_time_page/date_time_page.js b/chrome/browser/resources/settings/date_time_page/date_time_page.js index 73e7a10..cd0b5b7d 100644 --- a/chrome/browser/resources/settings/date_time_page/date_time_page.js +++ b/chrome/browser/resources/settings/date_time_page/date_time_page.js
@@ -4,22 +4,22 @@ /** * @fileoverview - * 'cr-settings-date-time-page' is the settings page containing date-time + * 'settings-date-time-page' is the settings page containing date-time * settings. * * Example: * * <core-animated-pages> - * <cr-settings-date-time-page prefs="{{prefs}}"> - * </cr-settings-date-time-page> + * <settings-date-time-page prefs="{{prefs}}"> + * </settings-date-time-page> * ... other pages ... * </core-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-date-time-page + * @element settings-date-time-page */ Polymer({ - is: 'cr-settings-date-time-page', + is: 'settings-date-time-page', properties: { /**
diff --git a/chrome/browser/resources/settings/date_time_page/demo.html b/chrome/browser/resources/settings/date_time_page/demo.html index 919675d9..e9129b3 100644 --- a/chrome/browser/resources/settings/date_time_page/demo.html +++ b/chrome/browser/resources/settings/date_time_page/demo.html
@@ -6,7 +6,7 @@ <script src="demo.js"></script> </head> <body unresolved> - <cr-settings-prefs></cr-settings-prefs> - <cr-settings-date-time-page></cr-settings-date-time-page> + <settings-prefs></settings-prefs> + <settings-date-time-page></settings-date-time-page> </body> </html>
diff --git a/chrome/browser/resources/settings/date_time_page/demo.js b/chrome/browser/resources/settings/date_time_page/demo.js index 612cabe..b95aa392 100644 --- a/chrome/browser/resources/settings/date_time_page/demo.js +++ b/chrome/browser/resources/settings/date_time_page/demo.js
@@ -4,6 +4,6 @@ // Wire up the prefs to the date/time page. window.addEventListener('polymer-ready', function() { - var page = document.querySelector('cr-settings-date-time-page'); - page.prefs = document.querySelector('cr-settings-prefs'); + var page = document.querySelector('settings-date-time-page'); + page.prefs = document.querySelector('settings-prefs'); });
diff --git a/chrome/browser/resources/settings/downloads_page/downloads_page.html b/chrome/browser/resources/settings/downloads_page/downloads_page.html index fad2c97..45b1ccd7 100644 --- a/chrome/browser/resources/settings/downloads_page/downloads_page.html +++ b/chrome/browser/resources/settings/downloads_page/downloads_page.html
@@ -4,7 +4,7 @@ <link rel="import" href="chrome://md-settings/controls/settings_checkbox.html"> <link rel="import" href="chrome://md-settings/controls/settings_input.html"> -<dom-module id="cr-settings-downloads-page"> +<dom-module id="settings-downloads-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css" href="downloads_page.css">
diff --git a/chrome/browser/resources/settings/downloads_page/downloads_page.js b/chrome/browser/resources/settings/downloads_page/downloads_page.js index 252f04c..a12d76d3 100644 --- a/chrome/browser/resources/settings/downloads_page/downloads_page.js +++ b/chrome/browser/resources/settings/downloads_page/downloads_page.js
@@ -4,22 +4,22 @@ /** * @fileoverview - * 'cr-settings-downloads-page' is the settings page containing downloads + * 'settings-downloads-page' is the settings page containing downloads * settings. * * Example: * * <iron-animated-pages> - * <cr-settings-downloads-page prefs="{{prefs}}"> - * </cr-settings-downloads-page> + * <settings-downloads-page prefs="{{prefs}}"> + * </settings-downloads-page> * ... other pages ... * </iron-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-downloads-page + * @element settings-downloads-page */ Polymer({ - is: 'cr-settings-downloads-page', + is: 'settings-downloads-page', properties: { /**
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.html b/chrome/browser/resources/settings/internet_page/internet_detail_page.html index 9cd13af..9304312e 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.html
@@ -15,7 +15,7 @@ <link rel="import" href="network_proxy.html"> <link rel="import" href="network_siminfo.html"> -<dom-module id="cr-settings-internet-detail-page"> +<dom-module id="settings-internet-detail-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css" href="internet_detail_page.css"> <template> @@ -77,20 +77,20 @@ </paper-button> <span class="flex"></span> <paper-button hidden$="[[!showViewAccount_(networkProperties)]]" - on-tap="onViewAccountClicked_"> + on-tap="onViewAccountTap_"> View Account </paper-button> <paper-button hidden$="[[!showActivate_(networkProperties)]]" - on-tap="onActivateClicked_"> + on-tap="onActivateTap_"> Activate </paper-button> <paper-button hidden$="[[!showConnect_(networkProperties)]]" disabled="[[!enableConnect_(networkProperties)]]" - on-tap="onConnectClicked_"> + on-tap="onConnectTap_"> Connect </paper-button> <paper-button hidden$="[[!showDisconnect_(networkProperties)]]" - on-tap="onDisconnectClicked_"> + on-tap="onDisconnectTap_"> Disconnect </paper-button> </div>
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.js b/chrome/browser/resources/settings/internet_page/internet_detail_page.js index 8fa56e8..5c272b7 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.js +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.js
@@ -4,11 +4,11 @@ /** * @fileoverview - * 'cr-settings-internet-detail' is the settings subpage containing details + * 'settings-internet-detail' is the settings subpage containing details * for a network. * * @group Chrome Settings Elements - * @element cr-settings-internet-detail + * @element settings-internet-detail */ (function() { 'use strict'; @@ -16,7 +16,7 @@ /** @const */ var CARRIER_VERIZON = 'Verizon Wireless'; Polymer({ - is: 'cr-settings-internet-detail-page', + is: 'settings-internet-detail-page', properties: { /** @@ -244,8 +244,7 @@ * @private */ isConnectedState_: function(properties) { - return !!properties && properties.ConnectionState == - CrOnc.ConnectionState.CONNECTED; + return properties.ConnectionState == CrOnc.ConnectionState.CONNECTED; }, /** @@ -254,7 +253,7 @@ * @private */ showConnect_: function(properties) { - return !!properties && properties.Type != CrOnc.Type.ETHERNET && + return properties.Type != CrOnc.Type.ETHERNET && properties.ConnectionState == CrOnc.ConnectionState.NOT_CONNECTED; }, @@ -327,39 +326,39 @@ * @private */ showDisconnect_: function(properties) { - return !!properties && properties.Type != CrOnc.Type.ETHERNET && + return properties.Type != CrOnc.Type.ETHERNET && properties.ConnectionState != CrOnc.ConnectionState.NOT_CONNECTED; }, /** - * Callback when the Connect button is clicked. + * Callback when the Connect button is tapped. * @private */ - onConnectClicked_: function() { + onConnectTap_: function() { chrome.networkingPrivate.startConnect(this.guid); }, /** - * Callback when the Disconnect button is clicked. + * Callback when the Disconnect button is tapped. * @private */ - onDisconnectClicked_: function() { + onDisconnectTap_: function() { chrome.networkingPrivate.startDisconnect(this.guid); }, /** - * Callback when the Activate button is clicked. + * Callback when the Activate button is tapped. * @private */ - onActivateClicked_: function() { + onActivateTap_: function() { chrome.networkingPrivate.startActivate(this.guid); }, /** - * Callback when the View Account button is clicked. + * Callback when the View Account button is tapped. * @private */ - onViewAccountClicked_: function() { + onViewAccountTap_: function() { // startActivate() will show the account page for activated networks. chrome.networkingPrivate.startActivate(this.guid); }, @@ -487,8 +486,7 @@ * @private */ showShared_: function(properties) { - return !!properties && (properties.Source == 'Device' || - properties.Source == 'DevicePolicy'); + return properties.Source == 'Device' || properties.Source == 'DevicePolicy'; }, /** @@ -497,7 +495,7 @@ * @private */ showAutoConnect_: function(properties) { - return !!properties && properties.Type != CrOnc.Type.ETHERNET && + return properties.Type != CrOnc.Type.ETHERNET && properties.Source != CrOnc.Source.NONE; }, @@ -509,7 +507,7 @@ showPreferNetwork_: function(properties) { // TODO(stevenjb): Resolve whether or not we want to allow "preferred" for // properties.Type == CrOnc.Type.ETHERNET. - return !!properties && properties.Source != CrOnc.Source.NONE; + return properties.Source != CrOnc.Source.NONE; }, /** @@ -637,7 +635,7 @@ * @private */ hasNetworkSection_: function(properties) { - return !!properties && properties.Type != CrOnc.Type.VPN; + return properties.Type != CrOnc.Type.VPN; }, /** @@ -647,7 +645,7 @@ * @private */ isType_: function(properties, type) { - return !!properties && properties.Type == type; + return properties.Type == type; }, /**
diff --git a/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html b/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html index ed58dca..b6ace42 100644 --- a/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_known_networks_page.html
@@ -4,7 +4,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html"> <link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_network_list.html"> -<dom-module id="cr-settings-internet-known-networks-page"> +<dom-module id="settings-internet-known-networks-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css" href="internet_known_networks_page.css"> <template>
diff --git a/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js b/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js index 46eddc5..508abed 100644 --- a/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js +++ b/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js
@@ -4,14 +4,14 @@ /** * @fileoverview - * 'cr-settings-internet-known-networks' is the settings subpage listing the + * 'settings-internet-known-networks' is the settings subpage listing the * known networks for a type (currently always WiFi). * * @group Chrome Settings Elements - * @element cr-settings-internet-known-networks + * @element settings-internet-known-networks */ Polymer({ - is: 'cr-settings-internet-known-networks-page', + is: 'settings-internet-known-networks-page', properties: { /**
diff --git a/chrome/browser/resources/settings/internet_page/internet_page.html b/chrome/browser/resources/settings/internet_page/internet_page.html index 1a54d51..4c48d8a 100644 --- a/chrome/browser/resources/settings/internet_page/internet_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_page.html
@@ -7,7 +7,7 @@ <link rel="import" href="internet_known_networks_page.html"> <link rel="import" href="network_summary.html"> -<dom-module id="cr-settings-internet-page"> +<dom-module id="settings-internet-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <template> @@ -21,18 +21,18 @@ <neon-animatable id="network-detail"> <settings-subheader i18n-values="page-title:internetDetailPageTitle"> </settings-subheader> - <cr-settings-internet-detail-page guid="[[detailGuid]]" + <settings-internet-detail-page guid="[[detailGuid]]" on-close="onBackTap_"> - </cr-settings-internet-detail-page> + </settings-internet-detail-page> </neon-animatable> <neon-animatable id="known-networks"> <settings-subheader i18n-values="page-title:internetKnownNetworksPageTitle"> </settings-subheader> - <cr-settings-internet-known-networks-page + <settings-internet-known-networks-page network-type="[[knownNetworksType]]" on-show-detail="onShowDetail_"> - </cr-settings-internet-known-networks-page> + </settings-internet-known-networks-page> </neon-animatable> </settings-animated-pages> </template>
diff --git a/chrome/browser/resources/settings/internet_page/internet_page.js b/chrome/browser/resources/settings/internet_page/internet_page.js index dd66f4be..1581df4 100644 --- a/chrome/browser/resources/settings/internet_page/internet_page.js +++ b/chrome/browser/resources/settings/internet_page/internet_page.js
@@ -4,22 +4,22 @@ /** * @fileoverview - * 'cr-settings-internet-page' is the settings page containing internet + * 'settings-internet-page' is the settings page containing internet * settings. * * Example: * * <core-animated-pages> - * <cr-settings-internet-page prefs='{{prefs}}'> - * </cr-settings-internet-page> + * <settings-internet-page prefs='{{prefs}}'> + * </settings-internet-page> * ... other pages ... * </core-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-internet-page + * @element settings-internet-page */ Polymer({ - is: 'cr-settings-internet-page', + is: 'settings-internet-page', properties: { /**
diff --git a/chrome/browser/resources/settings/internet_page/network_apnlist.html b/chrome/browser/resources/settings/internet_page/network_apnlist.html index 2d53bbe..48295be3 100644 --- a/chrome/browser/resources/settings/internet_page/network_apnlist.html +++ b/chrome/browser/resources/settings/internet_page/network_apnlist.html
@@ -25,7 +25,7 @@ edit-field-types="[[otherApnEditTypes_]]" on-property-change="onOtherApnChange_"> </network-property-list> - <paper-button on-tap="onSaveOther_">Save</paper-button> + <paper-button on-tap="onSaveOtherTap_">Save</paper-button> </div> </div> </template>
diff --git a/chrome/browser/resources/settings/internet_page/network_apnlist.js b/chrome/browser/resources/settings/internet_page/network_apnlist.js index e95ff7df..67bf2e2 100644 --- a/chrome/browser/resources/settings/internet_page/network_apnlist.js +++ b/chrome/browser/resources/settings/internet_page/network_apnlist.js
@@ -206,15 +206,15 @@ */ onOtherApnChange_: function(event) { this.set('otherApn.' + event.detail.field, event.detail.value); - // Don't send a change event for 'Other' until the 'Save' button is clicked. + // Don't send a change event for 'Other' until the 'Save' button is tapped. }, /** - * Event triggered when the Other APN 'Save' button is clicked. + * Event triggered when the Other APN 'Save' button is tapped. * @param {Event} event * @private */ - onSaveOther_: function(event) { + onSaveOtherTap_: function(event) { this.sendApnChange_(this.selectedApn); },
diff --git a/chrome/browser/resources/settings/internet_page/network_property_list.css b/chrome/browser/resources/settings/internet_page/network_property_list.css index 4bd06dc..edad310 100644 --- a/chrome/browser/resources/settings/internet_page/network_property_list.css +++ b/chrome/browser/resources/settings/internet_page/network_property_list.css
@@ -3,8 +3,6 @@ * found in the LICENSE file. */ span { - @apply(--paper-font-subhead); - @apply(--paper-input-container-input); margin: 0 5px 5px 0; }
diff --git a/chrome/browser/resources/settings/internet_page/network_property_list.html b/chrome/browser/resources/settings/internet_page/network_property_list.html index 79db6d9..bc89ad75 100644 --- a/chrome/browser/resources/settings/internet_page/network_property_list.html +++ b/chrome/browser/resources/settings/internet_page/network_property_list.html
@@ -1,7 +1,6 @@ <link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/paper-styles.html"> <dom-module name="network-property-list"> <link rel="import" type="css" href="network_property_list.css">
diff --git a/chrome/browser/resources/settings/internet_page/network_property_list.js b/chrome/browser/resources/settings/internet_page/network_property_list.js index 87b64216..51faf09 100644 --- a/chrome/browser/resources/settings/internet_page/network_property_list.js +++ b/chrome/browser/resources/settings/internet_page/network_property_list.js
@@ -17,6 +17,7 @@ properties: { /** * The dictionary containing the properties to display. + * @type {!Object|undefined} */ propertyDict: { type: Object @@ -80,18 +81,18 @@ }, /** - * @param {!Object|undefined} propertyDict + * @param {!Object} propertyDict * @param {string} key The property key. * @return {boolean} Whether or not the property exists in |propertyDict|. * @private */ hasPropertyValue_: function(propertyDict, key) { - var value = (propertyDict && this.get(key, propertyDict)) || undefined; - return (value !== undefined && value !== ''); + var value = this.get(key, propertyDict); + return value !== undefined && value !== ''; }, /** - * @param {!Object|undefined} propertyDict + * @param {!Object} propertyDict * @param {!Object} editFieldTypes The editFieldTypes object. * @param {string} key The property key. * @return {boolean} Whether or not to show the property. Editable properties @@ -105,7 +106,7 @@ }, /** - * @param {!Object|undefined} propertyDict + * @param {!Object} propertyDict * @param {!Object} editFieldTypes The editFieldTypes object. * @param {string} key The property key. * @return {boolean} True if |key| exists in |propertiesDict| and is not @@ -120,7 +121,7 @@ }, /** - * @param {!Object|undefined} propertyDict + * @param {!Object} propertyDict * @param {!Object} editFieldTypes The editFieldTypes object. * @param {string} key The property key. * @param {string} type The field type. @@ -133,14 +134,12 @@ }, /** - * @param {!Object|undefined} propertyDict + * @param {!Object} propertyDict * @param {string} key The property key. * @return {string} The text to display for the property value. * @private */ getPropertyValue_: function(propertyDict, key) { - if (!propertyDict) - return ''; var value = this.get(key, propertyDict); if (value === undefined) return '';
diff --git a/chrome/browser/resources/settings/internet_page/network_proxy.css b/chrome/browser/resources/settings/internet_page/network_proxy.css index 9098be4..0b3794a 100644 --- a/chrome/browser/resources/settings/internet_page/network_proxy.css +++ b/chrome/browser/resources/settings/internet_page/network_proxy.css
@@ -14,8 +14,6 @@ } span { - @apply(--paper-font-subhead); - @apply(--paper-input-container-input); margin: 5px; }
diff --git a/chrome/browser/resources/settings/internet_page/network_proxy.html b/chrome/browser/resources/settings/internet_page/network_proxy.html index 61ae5fd..826a535 100644 --- a/chrome/browser/resources/settings/internet_page/network_proxy.html +++ b/chrome/browser/resources/settings/internet_page/network_proxy.html
@@ -2,7 +2,6 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/paper-styles.html"> <link rel="import" href="chrome://resources/cr_elements/v1_0/network/cr_onc_types.html"> <link rel="import" href="network_property_list.html"> <link rel="import" href="network_proxy_input.html"> @@ -71,7 +70,7 @@ <div class="layout horizontal baseline"> <paper-input id="proxyExclusion" class="flex" no-label-float> </paper-input> - <paper-button on-tap="onAddProxyExclusion_"> + <paper-button on-tap="onAddProxyExclusionTap_"> Add Exception </paper-button> </div>
diff --git a/chrome/browser/resources/settings/internet_page/network_proxy.js b/chrome/browser/resources/settings/internet_page/network_proxy.js index c7c02e6..940b9ba 100644 --- a/chrome/browser/resources/settings/internet_page/network_proxy.js +++ b/chrome/browser/resources/settings/internet_page/network_proxy.js
@@ -220,7 +220,7 @@ * @param {Event} event The add proxy exclusion event. * @private */ - onAddProxyExclusion_: function(event) { + onAddProxyExclusionTap_: function(event) { var value = this.$.proxyExclusion.value; if (!value) return;
diff --git a/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.html b/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.html index 07b9273..35dad0e 100644 --- a/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.html +++ b/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.html
@@ -1,6 +1,5 @@ <link rel="import" href="chrome://resources/polymer/v1_0/polymer/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-styles/paper-styles.html"> <dom-module id="network-proxy-exclusions"> <link rel="import" type="css" href="network_proxy_exclusions.css"> @@ -9,7 +8,7 @@ <template is="dom-repeat" items="[[exclusions]]"> <div class="layout horizontal"> <span class="flex">[[item]]</span> - <iron-icon icon="clear" on-click="removeItem_"></iron-icon> + <iron-icon icon="clear" on-tap="onRemoveTap_"></iron-icon> </div> </template> </div>
diff --git a/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.js b/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.js index b765e1d..2d408b7 100644 --- a/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.js +++ b/chrome/browser/resources/settings/internet_page/network_proxy_exclusions.js
@@ -29,7 +29,7 @@ * @param {!{model: !{index: number}}} event * @private */ - removeItem_: function(event) { + onRemoveTap_: function(event) { var index = event.model.index; this.splice('exclusions', index, 1); this.fire('proxy-change');
diff --git a/chrome/browser/resources/settings/internet_page/network_proxy_input.css b/chrome/browser/resources/settings/internet_page/network_proxy_input.css index 16302de..518cedf 100644 --- a/chrome/browser/resources/settings/internet_page/network_proxy_input.css +++ b/chrome/browser/resources/settings/internet_page/network_proxy_input.css
@@ -7,8 +7,6 @@ } span { - @apply(--paper-font-subhead); - @apply(--paper-input-container-input); margin-right: 5px; }
diff --git a/chrome/browser/resources/settings/internet_page/network_proxy_input.html b/chrome/browser/resources/settings/internet_page/network_proxy_input.html index 6eeef81a..21f196c 100644 --- a/chrome/browser/resources/settings/internet_page/network_proxy_input.html +++ b/chrome/browser/resources/settings/internet_page/network_proxy_input.html
@@ -1,6 +1,5 @@ <link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/paper-styles.html"> <dom-module id="network-proxy-input"> <link rel="import" type="css" href="network_proxy_input.css">
diff --git a/chrome/browser/resources/settings/internet_page/network_siminfo.html b/chrome/browser/resources/settings/internet_page/network_siminfo.html index 03450ad..300a61f2 100644 --- a/chrome/browser/resources/settings/internet_page/network_siminfo.html +++ b/chrome/browser/resources/settings/internet_page/network_siminfo.html
@@ -1,5 +1,6 @@ <link rel="import" href="chrome://resources/polymer/v1_0/polymer/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/iron-icons/notification-icons.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-checkbox/paper-checkbox.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-dialog/paper-dialog.html"> @@ -12,19 +13,19 @@ <template> <div id="outerDiv" class="layout vertical"> <div class="layout horizontal center" - hidden$="[[state.Cellular.SIMPresent]]"> + hidden$="[[networkProperties.Cellular.SIMPresent]]"> <!-- SIM missing UI --> - <iron-icon icon="sim-card-alert"></iron-icon> + <iron-icon icon="notification:sim-card-alert"></iron-icon> <span>Missing SIM card</span> </div> <div class="layout vertical" - hidden$="[[!state.Cellular.SIMPresent]]"> + hidden$="[[!networkProperties.Cellular.SIMPresent]]"> <div id="lockedDiv" class="layout horizontal center" hidden$="[[!isSimLocked_(networkProperties)]]"> <!-- SIM locked --> <iron-icon icon="lock"></iron-icon> <span>SIM card is locked.</span> - <paper-button on-tap="unlockPin_">Unlock</paper-button> + <paper-button on-tap="onUnlockPinTap_">Unlock</paper-button> </div> <div class="layout vertical" hidden$="[[isSimLocked_(networkProperties)]]"> @@ -37,7 +38,7 @@ <div class="layout horizontal center" hidden$="[[!networkProperties.Cellular.SIMLockStatus.LockEnabled]]"> <!-- SIM lock enabled --> - <paper-button on-tap="onChangePin_">Change PIN</paper-button> + <paper-button on-tap="onChangePinTap_">Change PIN</paper-button> </div> </div> </div>
diff --git a/chrome/browser/resources/settings/internet_page/network_siminfo.js b/chrome/browser/resources/settings/internet_page/network_siminfo.js index d93268c..06b463a4 100644 --- a/chrome/browser/resources/settings/internet_page/network_siminfo.js +++ b/chrome/browser/resources/settings/internet_page/network_siminfo.js
@@ -150,7 +150,7 @@ * @param {Event} event * @private */ - onChangePin_: function(event) { + onChangePinTap_: function(event) { if (!this.networkProperties || !this.networkProperties.Cellular) return; this.error = ErrorType.NONE; @@ -203,7 +203,7 @@ * @param {Event} event * @private */ - unlockPin_: function(event) { + onUnlockPinTap_: function(event) { this.error = ErrorType.NONE; this.$.unlockPinDialog.open(); },
diff --git a/chrome/browser/resources/settings/internet_page/network_summary_item.html b/chrome/browser/resources/settings/internet_page/network_summary_item.html index 9ab31df..73dede1 100644 --- a/chrome/browser/resources/settings/internet_page/network_summary_item.html +++ b/chrome/browser/resources/settings/internet_page/network_summary_item.html
@@ -11,7 +11,7 @@ <template> <div class="layout vertical" hidden$="[[isHidden]]"> <div id="details" class="layout horizontal center" - on-click="onDetailsClicked_"> + on-tap="onDetailsTap_"> <cr-network-list-item id="detailsItem" network-state="[[networkState]]"> </cr-network-list-item> @@ -26,7 +26,7 @@ <paper-toggle-button id="deviceEnabledButton" checked="[[deviceIsEnabled_(deviceState)]]" class$="[[getDeviceEnabledButtonClass_(deviceState)]]" - on-tap="onDeviceEnabledToggled_"> + on-tap="onDeviceEnabledTap_"> </paper-toggle-button> </div> </div> @@ -40,7 +40,7 @@ <div class="layout horizontal"> <paper-button hidden$="[[!showKnownNetworks_(networkState, expanded)]]" - on-tap="onKnownNetworksClicked_"> + on-tap="onKnownNetworksTap_"> Known networks </paper-button> </div>
diff --git a/chrome/browser/resources/settings/internet_page/network_summary_item.js b/chrome/browser/resources/settings/internet_page/network_summary_item.js index 67e7a1b0..ccb10ea 100644 --- a/chrome/browser/resources/settings/internet_page/network_summary_item.js +++ b/chrome/browser/resources/settings/internet_page/network_summary_item.js
@@ -168,11 +168,11 @@ }, /** - * Event triggered when the details div is clicked. + * Event triggered when the details div is tapped. * @param {Event} event The enable button event. * @private */ - onDetailsClicked_: function(event) { + onDetailsTap_: function(event) { if ((event.target.id == 'expandListButton') || (this.deviceState && !this.deviceIsEnabled_(this.deviceState))) { // Already handled or disabled, do nothing. @@ -188,10 +188,10 @@ }, /** - * Event triggered when the known networks button is clicked. + * Event triggered when the known networks button is tapped. * @private */ - onKnownNetworksClicked_: function() { + onKnownNetworksTap_: function() { this.fire('show-known-networks', {type: CrOnc.Type.WI_FI}); }, @@ -210,12 +210,12 @@ * @param {!Object} event The enable button event. * @private */ - onDeviceEnabledToggled_: function(event) { + onDeviceEnabledTap_: function(event) { var deviceIsEnabled = this.deviceIsEnabled_(this.deviceState); var type = this.deviceState ? this.deviceState.Type : ''; this.fire('device-enabled-toggled', {enabled: !deviceIsEnabled, type: type}); - // Make sure this does not propagate to onDetailsClicked_. + // Make sure this does not propagate to onDetailsTap_. event.stopPropagation(); },
diff --git a/chrome/browser/resources/settings/languages_page/language_detail_page.html b/chrome/browser/resources/settings/languages_page/language_detail_page.html index 51b1767..e3ea064 100644 --- a/chrome/browser/resources/settings/languages_page/language_detail_page.html +++ b/chrome/browser/resources/settings/languages_page/language_detail_page.html
@@ -14,8 +14,8 @@ <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css" href="language_detail_page.css"> <template> - <cr-settings-languages id="languages" languages="{{languages}}"> - </cr-settings-languages> + <settings-languages id="languages" languages="{{languages}}"> + </settings-languages> <if expr="chromeos or is_win"> <div id="languageSettings"> <label hidden$="[[!detail.language.supportsUI]]">
diff --git a/chrome/browser/resources/settings/languages_page/language_detail_page.js b/chrome/browser/resources/settings/languages_page/language_detail_page.js index aadcc60..b30d2a9 100644 --- a/chrome/browser/resources/settings/languages_page/language_detail_page.js +++ b/chrome/browser/resources/settings/languages_page/language_detail_page.js
@@ -23,7 +23,7 @@ /** * Read-only reference to the languages model provided by the - * 'cr-settings-languages' instance. + * 'settings-languages' instance. * @type {LanguagesModel|undefined} */ languages: Object,
diff --git a/chrome/browser/resources/settings/languages_page/languages.html b/chrome/browser/resources/settings/languages_page/languages.html index d426d5e..d44724c 100644 --- a/chrome/browser/resources/settings/languages_page/languages.html +++ b/chrome/browser/resources/settings/languages_page/languages.html
@@ -3,9 +3,9 @@ <link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html"> <link rel="import" href="chrome://md-settings/prefs/prefs.html"> -<dom-module id="cr-settings-languages-singleton"> +<dom-module id="settings-languages-singleton"> <template> - <cr-settings-prefs prefs="{{prefs}}"></cr-settings-prefs> + <settings-prefs prefs="{{prefs}}"></settings-prefs> </template> <script src="languages.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/languages_page/languages.js b/chrome/browser/resources/settings/languages_page/languages.js index c65c0e74..3314136 100644 --- a/chrome/browser/resources/settings/languages_page/languages.js +++ b/chrome/browser/resources/settings/languages_page/languages.js
@@ -3,7 +3,7 @@ // found in the LICENSE file. /** - * @fileoverview 'cr-settings-languages' provides convenient access to + * @fileoverview 'settings-languages' provides convenient access to * Chrome's language and input method settings. * * Instances of this element have a 'languages' property, which reflects the @@ -15,13 +15,13 @@ * changes made internally to 'languages' propagate to your host element: * * <template> - * <cr-settings-languages languages="{{languages}}"> - * </cr-settings-languages> + * <settings-languages languages="{{languages}}"> + * </settings-languages> * <div>[[languages.someProperty]]</div> * </template> * * @group Chrome Settings Elements - * @element cr-settings-languages + * @element settings-languages */ /** @typedef {{spellCheckEnabled: boolean, translateEnabled: boolean}} */ @@ -71,7 +71,7 @@ * language model to the host of this element as the 'languages' property. */ Polymer({ - is: 'cr-settings-languages', + is: 'settings-languages', properties: { /** @@ -80,7 +80,7 @@ */ singleton_: { type: Object, - value: document.createElement('cr-settings-languages-singleton'), + value: document.createElement('settings-languages-singleton'), }, /** @@ -183,14 +183,14 @@ 'settings.language.preferred_languages' : 'intl.accept_languages'; /** - * Singleton element created when cr-settings-languages is registered. + * Singleton element created when settings-languages is registered. * Generates the languages model on start-up, and updates it whenever Chrome's * pref store and other settings change. These updates propagate to each - * <cr-settings-language> instance so that their 'languages' property updates + * <settings-language> instance so that their 'languages' property updates * like any other Polymer property. */ Polymer({ - is: 'cr-settings-languages-singleton', + is: 'settings-languages-singleton', properties: { /**
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.html b/chrome/browser/resources/settings/languages_page/languages_page.html index bc456e45..1c80e96 100644 --- a/chrome/browser/resources/settings/languages_page/languages_page.html +++ b/chrome/browser/resources/settings/languages_page/languages_page.html
@@ -14,13 +14,13 @@ <link rel="import" href="languages.html"> <link rel="import" href="manage_languages_page.html"> -<dom-module id="cr-settings-languages-page"> +<dom-module id="settings-languages-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css" href="languages_page.css"> <template> - <cr-settings-languages id="languages" languages="{{languages}}"> - </cr-settings-languages> + <settings-languages id="languages" languages="{{languages}}"> + </settings-languages> <settings-animated-pages id="pages" current-route="{{currentRoute}}" section="languages"> <neon-animatable id="main"> @@ -80,8 +80,8 @@ <neon-animatable id="manage-languages"> <settings-subheader i18n-values="page-title:manageLanguagesPageTitle"> </settings-subheader> - <cr-settings-manage-languages-page id="manageLanguagesPage" - prefs="{{prefs}}"></cr-settings-manage-languages-page> + <settings-manage-languages-page id="manageLanguagesPage" + prefs="{{prefs}}"></settings-manage-languages-page> </neon-animatable> <neon-animatable id="language-detail"> <settings-subheader id="language-detail-subheader"
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.js b/chrome/browser/resources/settings/languages_page/languages_page.js index 427c9153..9186884 100644 --- a/chrome/browser/resources/settings/languages_page/languages_page.js +++ b/chrome/browser/resources/settings/languages_page/languages_page.js
@@ -3,17 +3,17 @@ // found in the LICENSE file. /** - * @fileoverview 'cr-settings-languages-page' is the settings page + * @fileoverview 'settings-languages-page' is the settings page * for language and input method settings. * * @group Chrome Settings Elements - * @element cr-settings-languages-page + * @element settings-languages-page */ (function() { 'use strict'; Polymer({ - is: 'cr-settings-languages-page', + is: 'settings-languages-page', properties: { /** @@ -34,7 +34,7 @@ /** * Read-only reference to the languages model provided by the - * 'cr-settings-languages' instance. + * 'settings-languages' instance. * @type {LanguagesModel|undefined} */ languages: {
diff --git a/chrome/browser/resources/settings/languages_page/manage_languages_page.html b/chrome/browser/resources/settings/languages_page/manage_languages_page.html index 8fa80eb..04a60a6 100644 --- a/chrome/browser/resources/settings/languages_page/manage_languages_page.html +++ b/chrome/browser/resources/settings/languages_page/manage_languages_page.html
@@ -9,13 +9,13 @@ <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="languages.html"> -<dom-module id="cr-settings-manage-languages-page"> +<dom-module id="settings-manage-languages-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css" href="manage_languages_page.css"> <template> - <cr-settings-languages id="languages" languages="{{languages}}"> - </cr-settings-languages> + <settings-languages id="languages" languages="{{languages}}"> + </settings-languages> <div class="content"> <h2 i18n-content="enabledLanguages"></h2> <div class="item-list">
diff --git a/chrome/browser/resources/settings/languages_page/manage_languages_page.js b/chrome/browser/resources/settings/languages_page/manage_languages_page.js index 1fe8ba4..9dda84c1 100644 --- a/chrome/browser/resources/settings/languages_page/manage_languages_page.js +++ b/chrome/browser/resources/settings/languages_page/manage_languages_page.js
@@ -3,14 +3,14 @@ // found in the LICENSE file. /** - * @fileoverview 'cr-settings-manage-languages-page' is a sub-page for enabling + * @fileoverview 'settings-manage-languages-page' is a sub-page for enabling * and disabling languages. * * @group Chrome Settings Elements - * @element cr-settings-manage-languages-page + * @element settings-manage-languages-page */ Polymer({ - is: 'cr-settings-manage-languages-page', + is: 'settings-manage-languages-page', properties: { /**
diff --git a/chrome/browser/resources/settings/location_page/location_page.html b/chrome/browser/resources/settings/location_page/location_page.html index 4c4e0ca..6adde9e7 100644 --- a/chrome/browser/resources/settings/location_page/location_page.html +++ b/chrome/browser/resources/settings/location_page/location_page.html
@@ -7,7 +7,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-submenu.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html"> -<dom-module id="cr-settings-location-page"> +<dom-module id="settings-location-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css" href="location_page.css">
diff --git a/chrome/browser/resources/settings/location_page/location_page.js b/chrome/browser/resources/settings/location_page/location_page.js index 1d8201b..368bfa3e 100644 --- a/chrome/browser/resources/settings/location_page/location_page.js +++ b/chrome/browser/resources/settings/location_page/location_page.js
@@ -4,19 +4,19 @@ /** * @fileoverview - * 'cr-settings-location-page' is the settings page for location access. + * 'settings-location-page' is the settings page for location access. * * Example: * - * <cr-settings-location-page prefs="{{prefs}}"> - * </cr-settings-location-page> + * <settings-location-page prefs="{{prefs}}"> + * </settings-location-page> * ... other pages ... * * @group Chrome Settings Elements - * @element cr-settings-location-page + * @element settings-location-page */ Polymer({ - is: 'cr-settings-location-page', + is: 'settings-location-page', properties: { /**
diff --git a/chrome/browser/resources/settings/on_startup_page/on_startup_page.html b/chrome/browser/resources/settings/on_startup_page/on_startup_page.html index c99975a..7df7904 100644 --- a/chrome/browser/resources/settings/on_startup_page/on_startup_page.html +++ b/chrome/browser/resources/settings/on_startup_page/on_startup_page.html
@@ -7,7 +7,7 @@ <link rel="import" href="chrome://md-settings/settings_page/settings_animated_pages.html"> <link rel="import" href="chrome://md-settings/settings_page/settings_subheader.html"> -<dom-module id="cr-settings-on-startup-page"> +<dom-module id="settings-on-startup-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css" href="on_startup_shared.css"> @@ -36,8 +36,8 @@ <neon-animatable id="startup-urls"> <settings-subheader i18n-values="page-title:onStartupSetPages"> </settings-subheader> - <cr-settings-startup-urls-page prefs="{{prefs}}"> - </cr-settings-startup-urls-page> + <settings-startup-urls-page prefs="{{prefs}}"> + </settings-startup-urls-page> </neon-animatable> </settings-animated-pages> </template>
diff --git a/chrome/browser/resources/settings/on_startup_page/on_startup_page.js b/chrome/browser/resources/settings/on_startup_page/on_startup_page.js index 95e516d..d1645b93 100644 --- a/chrome/browser/resources/settings/on_startup_page/on_startup_page.js +++ b/chrome/browser/resources/settings/on_startup_page/on_startup_page.js
@@ -4,21 +4,21 @@ /** * @fileoverview - * 'cr-settings-on-startup-page' is a settings page. + * 'settings-on-startup-page' is a settings page. * * Example: * * <neon-animated-pages> - * <cr-settings-on-startup-page prefs="{{prefs}}"> - * </cr-settings-on-startup-page> + * <settings-on-startup-page prefs="{{prefs}}"> + * </settings-on-startup-page> * ... other pages ... * </neon-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-on-startup-page + * @element settings-on-startup-page */ Polymer({ - is: 'cr-settings-on-startup-page', + is: 'settings-on-startup-page', properties: { /**
diff --git a/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html b/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html index dca01c7e..e34f683 100644 --- a/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html +++ b/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html
@@ -2,7 +2,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-icon-item.html"> -<dom-module id="cr-settings-startup-urls-page"> +<dom-module id="settings-startup-urls-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css" href="on_startup_shared.css"> <template>
diff --git a/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js b/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js index fd5e903..a8d1873 100644 --- a/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js +++ b/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js
@@ -3,22 +3,22 @@ // found in the LICENSE file. /** - * @fileoverview 'cr-settings-startup-urls-page' is the settings page + * @fileoverview 'settings-startup-urls-page' is the settings page * containing the urls that will be opened when chrome is started. * * Example: * * <neon-animated-pages> - * <cr-settings-startup-urls-page prefs="{{prefs}}"> - * </cr-settings-startup-urls-page> + * <settings-startup-urls-page prefs="{{prefs}}"> + * </settings-startup-urls-page> * ... other pages ... * </neon-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-startup-urls-page + * @element settings-startup-urls-page */ Polymer({ - is: 'cr-settings-startup-urls-page', + is: 'settings-startup-urls-page', properties: { /**
diff --git a/chrome/browser/resources/settings/pref_tracker/pref_tracker.html b/chrome/browser/resources/settings/pref_tracker/pref_tracker.html index a1f68d2..978dafe 100644 --- a/chrome/browser/resources/settings/pref_tracker/pref_tracker.html +++ b/chrome/browser/resources/settings/pref_tracker/pref_tracker.html
@@ -1,6 +1,6 @@ <link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html"> <link rel="import" href="chrome://md-settings/prefs/prefs_types.html"> -<dom-module id="cr-settings-pref-tracker"> +<dom-module id="settings-pref-tracker"> <script src="pref_tracker.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/pref_tracker/pref_tracker.js b/chrome/browser/resources/settings/pref_tracker/pref_tracker.js index b7124759..34d9473 100644 --- a/chrome/browser/resources/settings/pref_tracker/pref_tracker.js +++ b/chrome/browser/resources/settings/pref_tracker/pref_tracker.js
@@ -4,21 +4,21 @@ /** * @fileoverview - * `cr-settings-pref-tracker` is a utility element used to track the + * `settings-pref-tracker` is a utility element used to track the * initialization of a specified preference and throw an error if the pref * is not defined after prefs have all been fetched. * * Example: * - * <cr-settings-pref-tracker pref="{{prefs.settings.foo.bar}}"> - * </cr-settings-pref-tracker> + * <settings-pref-tracker pref="{{prefs.settings.foo.bar}}"> + * </settings-pref-tracker> * - * @element cr-settings-pref-tracker + * @element settings-pref-tracker */ (function() { Polymer({ - is: 'cr-settings-pref-tracker', + is: 'settings-pref-tracker', properties: { /**
diff --git a/chrome/browser/resources/settings/prefs/prefs.js b/chrome/browser/resources/settings/prefs/prefs.js index ffb64dc9..d46ff88 100644 --- a/chrome/browser/resources/settings/prefs/prefs.js +++ b/chrome/browser/resources/settings/prefs/prefs.js
@@ -4,7 +4,7 @@ /** * @fileoverview - * 'cr-settings-prefs' exposes a singleton model of Chrome settings and + * 'settings-prefs' exposes a singleton model of Chrome settings and * preferences, which listens to changes to Chrome prefs whitelisted in * chrome.settingsPrivate. When changing prefs in this element's 'prefs' * property via the UI, the singleton model tries to set those preferences in @@ -13,12 +13,12 @@ * * Example: * - * <cr-settings-prefs prefs="{{prefs}}"></cr-settings-prefs> + * <settings-prefs prefs="{{prefs}}"></settings-prefs> * <settings-checkbox pref="{{prefs.homepage_is_newtabpage}}"> * </settings-checkbox> * * @group Chrome Settings Elements - * @element cr-settings-prefs + * @element settings-prefs */ (function() { @@ -125,7 +125,7 @@ } Polymer({ - is: 'cr-settings-prefs', + is: 'settings-prefs', properties: { /** @@ -142,7 +142,7 @@ */ singleton_: { type: Object, - value: document.createElement('cr-settings-prefs-singleton'), + value: document.createElement('settings-prefs-singleton'), }, }, @@ -157,7 +157,7 @@ }, /** - * Binds this.prefs to the cr-settings-prefs-singleton's shared prefs once + * Binds this.prefs to the settings-prefs-singleton's shared prefs once * preferences are initialized. * @private */ @@ -174,7 +174,7 @@ }, /** - * Stops listening for changes to cr-settings-prefs-singleton's shared + * Stops listening for changes to settings-prefs-singleton's shared * prefs. * @private */ @@ -196,7 +196,7 @@ }, /** - * Forwards changes to this.prefs to cr-settings-prefs-singleton. + * Forwards changes to this.prefs to settings-prefs-singleton. * @private */ prefsChanged_: function(info) { @@ -224,7 +224,7 @@ /** * Uninitializes this element to remove it from tests. Also resets - * cr-settings-prefs-singleton, allowing newly created elements to + * settings-prefs-singleton, allowing newly created elements to * re-initialize it. */ resetForTesting: function() { @@ -238,7 +238,7 @@ * prefs state. */ Polymer({ - is: 'cr-settings-prefs-singleton', + is: 'settings-prefs-singleton', properties: { /**
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html index 66f1edcc..b1b149b 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.html +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -10,7 +10,7 @@ <link rel="import" href="chrome://md-settings/settings_page/settings_subheader.html"> <link rel="import" href="chrome://md-settings/site_settings_page/site_settings_page.html"> -<dom-module id="cr-settings-privacy-page"> +<dom-module id="settings-privacy-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css" href="privacy_page.css"> @@ -84,19 +84,19 @@ <neon-animatable id="manage-certificates"> <settings-subheader i18n-values="page-title:manageCertificates"> </settings-subheader> - <cr-settings-certificate-manager-page> - </cr-settings-certificate-manager-page> + <settings-certificate-manager-page> + </settings-certificate-manager-page> </neon-animatable> <neon-animatable id="site-settings"> <settings-subheader i18n-values="page-title:siteSettings"> </settings-subheader> - <cr-settings-site-settings-page></cr-settings-site-settings-page> + <settings-site-settings-page></settings-site-settings-page> </neon-animatable> <neon-animatable id="clear-browsing-data"> <settings-subheader i18n-values="page-title:clearBrowsingData"> </settings-subheader> - <cr-settings-clear-browsing-data-page prefs="{{prefs}}"> - </cr-settings-clear-browsing-data-page> + <settings-clear-browsing-data-page prefs="{{prefs}}"> + </settings-clear-browsing-data-page> </neon-animatable> </settings-animated-pages> </template>
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.js b/chrome/browser/resources/settings/privacy_page/privacy_page.js index a608276..5669824 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.js +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.js
@@ -4,22 +4,22 @@ /** * @fileoverview - * 'cr-settings-privacy-page' is the settings page containing privacy and + * 'settings-privacy-page' is the settings page containing privacy and * security settings. * * Example: * * <iron-animated-pages> - * <cr-settings-privacy-page prefs="{{prefs}}"> - * </cr-settings-privacy-page> + * <settings-privacy-page prefs="{{prefs}}"> + * </settings-privacy-page> * ... other pages ... * </iron-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-privacy-page + * @element settings-privacy-page */ Polymer({ - is: 'cr-settings-privacy-page', + is: 'settings-privacy-page', properties: { /**
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engine_adder.js b/chrome/browser/resources/settings/search_engines_page/search_engine_adder.js index 080a2de..927912e5 100644 --- a/chrome/browser/resources/settings/search_engines_page/search_engine_adder.js +++ b/chrome/browser/resources/settings/search_engines_page/search_engine_adder.js
@@ -7,7 +7,7 @@ * engine. * * @group Chrome Settings Elements - * @element cr-settings-search-engine-adder + * @element settings-search-engine-adder */ Polymer({ is: 'cr-search-engine-adder',
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engines_page.html b/chrome/browser/resources/settings/search_engines_page/search_engines_page.html index 58f097d..7929519 100644 --- a/chrome/browser/resources/settings/search_engines_page/search_engines_page.html +++ b/chrome/browser/resources/settings/search_engines_page/search_engines_page.html
@@ -2,7 +2,7 @@ <link rel="import" href="search_engine_adder.html"> <link rel="import" href="search_engines_list.html"> -<dom-module id="cr-settings-search-engines-page"> +<dom-module id="settings-search-engines-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <template> <div class="content">
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engines_page.js b/chrome/browser/resources/settings/search_engines_page/search_engines_page.js index abd6bac..9aeb8599 100644 --- a/chrome/browser/resources/settings/search_engines_page/search_engines_page.js +++ b/chrome/browser/resources/settings/search_engines_page/search_engines_page.js
@@ -3,22 +3,22 @@ // found in the LICENSE file. /** - * @fileoverview 'cr-settings-search-engines-page' is the settings page + * @fileoverview 'settings-search-engines-page' is the settings page * containing search engines settings. * * Example: * * <core-animated-pages> - * <cr-settings-search-engines-page prefs="{{prefs}}"> - * </cr-settings-search-engines-page> + * <settings-search-engines-page prefs="{{prefs}}"> + * </settings-search-engines-page> * ... other pages ... * </core-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-search-engines-page + * @element settings-search-engines-page */ Polymer({ - is: 'cr-settings-search-engines-page', + is: 'settings-search-engines-page', properties: { /** @type {!Array<!SearchEngine>} */
diff --git a/chrome/browser/resources/settings/search_page/search_page.html b/chrome/browser/resources/settings/search_page/search_page.html index ef08987..1753bd8 100644 --- a/chrome/browser/resources/settings/search_page/search_page.html +++ b/chrome/browser/resources/settings/search_page/search_page.html
@@ -6,7 +6,7 @@ <link rel="import" href="chrome://md-settings/settings_page/settings_animated_pages.html"> <link rel="import" href="chrome://md-settings/settings_page/settings_subheader.html"> -<dom-module id="cr-settings-search-page"> +<dom-module id="settings-search-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css" href="search_page.css"> @@ -32,7 +32,7 @@ <neon-animatable id="search-engines"> <settings-subheader i18n-values="page-title:searchEnginesLabel"> </settings-subheader> - <cr-settings-search-engines-page></cr-settings-search-engines-page> + <settings-search-engines-page></settings-search-engines-page> <paper-button class="search-engines-advanced" i18n-content="advancedPageTitle" on-tap="onSearchEnginesAdvancedTap_" raised>
diff --git a/chrome/browser/resources/settings/search_page/search_page.js b/chrome/browser/resources/settings/search_page/search_page.js index 34983d0..7f069b60 100644 --- a/chrome/browser/resources/settings/search_page/search_page.js +++ b/chrome/browser/resources/settings/search_page/search_page.js
@@ -4,20 +4,20 @@ /** * @fileoverview - * 'cr-settings-search-page' is the settings page containing search settings. + * 'settings-search-page' is the settings page containing search settings. * * Example: * * <iron-animated-pages> - * <cr-settings-search-page prefs="{{prefs}}"></cr-settings-search-page> + * <settings-search-page prefs="{{prefs}}"></settings-search-page> * ... other pages ... * </iron-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-search-page + * @element settings-search-page */ Polymer({ - is: 'cr-settings-search-page', + is: 'settings-search-page', properties: { /**
diff --git a/chrome/browser/resources/settings/settings.html b/chrome/browser/resources/settings/settings.html index 231b3d9..ec9542c 100644 --- a/chrome/browser/resources/settings/settings.html +++ b/chrome/browser/resources/settings/settings.html
@@ -15,8 +15,8 @@ <dom-module id="cr-settings"> <template> - <cr-settings-prefs id="prefs" prefs="{{prefs_}}"></cr-settings-prefs> - <cr-settings-ui prefs="{{prefs_}}"></cr-settings-ui> + <settings-prefs id="prefs" prefs="{{prefs_}}"></settings-prefs> + <settings-ui prefs="{{prefs_}}"></settings-ui> </template> <script src="settings.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.html b/chrome/browser/resources/settings/settings_main/settings_main.html index cc17ba24..1bbdc278 100644 --- a/chrome/browser/resources/settings/settings_main/settings_main.html +++ b/chrome/browser/resources/settings/settings_main/settings_main.html
@@ -3,18 +3,18 @@ <link rel="import" href="chrome://md-settings/advanced_page/advanced_page.html"> <link rel="import" href="chrome://md-settings/basic_page/basic_page.html"> -<dom-module id="cr-settings-main"> +<dom-module id="settings-main"> <link rel="import" type="css" href="settings_main.css"> <template> <content select="paper-icon-button"></content> <iron-pages id="pageContainer" attr-for-selected="data-route-page" selected="[[getSelectedPage_(currentRoute)]]"> - <cr-settings-basic-page data-route-page="basic" prefs="{{prefs}}" + <settings-basic-page data-route-page="basic" prefs="{{prefs}}" current-route="{{currentRoute}}"> - </cr-settings-basic-page> - <cr-settings-advanced-page data-route-page="advanced" prefs="{{prefs}}" + </settings-basic-page> + <settings-advanced-page data-route-page="advanced" prefs="{{prefs}}" current-route="{{currentRoute}}"> - </cr-settings-advanced-page> + </settings-advanced-page> </iron-pages> </template> <script src="settings_main.js"></script>
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.js b/chrome/browser/resources/settings/settings_main/settings_main.js index 77bd76134..1033b51 100644 --- a/chrome/browser/resources/settings/settings_main/settings_main.js +++ b/chrome/browser/resources/settings/settings_main/settings_main.js
@@ -4,20 +4,20 @@ /** * @fileoverview - * 'cr-settings-main' displays the selected settings page. + * 'settings-main' displays the selected settings page. * * Example: * - * <cr-settings-main pages="[[pages]]" selected-page-id="{{selectedId}}"> - * </cr-settings-main> + * <settings-main pages="[[pages]]" selected-page-id="{{selectedId}}"> + * </settings-main> * - * See cr-settings-drawer for example of use in 'paper-drawer-panel'. + * See settings-drawer for example of use in 'paper-drawer-panel'. * * @group Chrome Settings Elements - * @element cr-settings-main + * @element settings-main */ Polymer({ - is: 'cr-settings-main', + is: 'settings-main', properties: { /**
diff --git a/chrome/browser/resources/settings/settings_menu/settings_menu.html b/chrome/browser/resources/settings/settings_menu/settings_menu.html index 6d0ebbaf..12628ddf 100644 --- a/chrome/browser/resources/settings/settings_menu/settings_menu.html +++ b/chrome/browser/resources/settings/settings_menu/settings_menu.html
@@ -10,7 +10,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/device-icons.html"> </if> -<dom-module id="cr-settings-menu"> +<dom-module id="settings-menu"> <link rel="import" type="css" href="settings_menu.css"> <template> <paper-menu name="root-menu">
diff --git a/chrome/browser/resources/settings/settings_menu/settings_menu.js b/chrome/browser/resources/settings/settings_menu/settings_menu.js index 73a4f5b6..9c873a1 100644 --- a/chrome/browser/resources/settings/settings_menu/settings_menu.js +++ b/chrome/browser/resources/settings/settings_menu/settings_menu.js
@@ -4,18 +4,18 @@ /** * @fileoverview - * 'cr-settings-menu' shows a menu with a hardcoded set of pages and subpages. + * 'settings-menu' shows a menu with a hardcoded set of pages and subpages. * * Example: * - * <cr-settings-menu selected-page-id="{{selectedPageId}}"> - * </cr-settings-menu> + * <settings-menu selected-page-id="{{selectedPageId}}"> + * </settings-menu> * * @group Chrome Settings Elements - * @element cr-settings-menu + * @element settings-menu */ Polymer({ - is: 'cr-settings-menu', + is: 'settings-menu', properties: { /**
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd index 97449f5..f6d5deba 100644 --- a/chrome/browser/resources/settings/settings_resources.grd +++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -364,6 +364,14 @@ <structure name="IDR_SETTINGS_SYNC_PAGE_CSS" file="sync_page/sync_page.css" type="chrome_html" /> + <structure name="IDR_SETTINGS_SYNC_PRIVATE_API_JS" + file="sync_page/sync_private_api.js" + type="chrome_html" /> + <structure name="IDR_SETTINGS_SYNC_PRIVATE_API_HTML" + file="sync_page/sync_private_api.html" + type="chrome_html" + flattenhtml="true" + allowexternalscript="true" /> <structure name="IDR_SETTINGS_SETTINGS_HTML" file="settings.html" type="chrome_html" />
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.css b/chrome/browser/resources/settings/settings_ui/settings_ui.css index b679e44a..7b94109f 100644 --- a/chrome/browser/resources/settings/settings_ui/settings_ui.css +++ b/chrome/browser/resources/settings/settings_ui/settings_ui.css
@@ -27,6 +27,6 @@ position: relative; } -cr-settings-main paper-icon-button { +settings-main paper-icon-button { z-index: 10; }
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.html b/chrome/browser/resources/settings/settings_ui/settings_ui.html index 0bb5ed8..5a65e761b 100644 --- a/chrome/browser/resources/settings/settings_ui/settings_ui.html +++ b/chrome/browser/resources/settings/settings_ui/settings_ui.html
@@ -10,7 +10,7 @@ <link rel="import" href="chrome://md-settings/settings_page/settings_router.html"> <link rel="import" href="chrome://md-settings/settings_ui/breadcrumb.html"> -<dom-module id="cr-settings-ui"> +<dom-module id="settings-ui"> <link rel="import" type="css" href="settings_ui.css"> <template> <settings-router current-route="{{currentRoute}}" @@ -23,11 +23,11 @@ </settings-breadcrumb> </paper-toolbar> <paper-drawer-panel drawer-width="256px"> - <cr-settings-menu drawer class="flex" current-route="{{currentRoute}}"> - </cr-settings-menu> - <cr-settings-main main prefs="{{prefs}}" current-route="{{currentRoute}}"> + <settings-menu drawer class="flex" current-route="{{currentRoute}}"> + </settings-menu> + <settings-main main prefs="{{prefs}}" current-route="{{currentRoute}}"> <paper-icon-button icon="menu" paper-drawer-toggle></paper-icon-button> - </cr-settings-main> + </settings-main> </paper-drawer-panel> </template> <script src="settings_ui.js"></script>
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.js b/chrome/browser/resources/settings/settings_ui/settings_ui.js index bc21caa7..513aa52 100644 --- a/chrome/browser/resources/settings/settings_ui/settings_ui.js +++ b/chrome/browser/resources/settings/settings_ui/settings_ui.js
@@ -4,17 +4,17 @@ /** * @fileoverview - * 'cr-settings-ui' implements the UI for the Settings page. + * 'settings-ui' implements the UI for the Settings page. * * Example: * - * <cr-settings-ui prefs="{{prefs}}"></cr-settings-ui> + * <settings-ui prefs="{{prefs}}"></settings-ui> * * @group Chrome Settings Elements - * @element cr-settings-ui + * @element settings-ui */ Polymer({ - is: 'cr-settings-ui', + is: 'settings-ui', properties: { /**
diff --git a/chrome/browser/resources/settings/signin_page/signin_page.html b/chrome/browser/resources/settings/signin_page/signin_page.html index 87fab1b..adba474 100644 --- a/chrome/browser/resources/settings/signin_page/signin_page.html +++ b/chrome/browser/resources/settings/signin_page/signin_page.html
@@ -18,8 +18,8 @@ <neon-animatable id="sync"> <settings-subheader i18n-values="page-title:syncPageTitle"> </settings-subheader> - <cr-settings-sync-page current-route="[[currentRoute]]"> - </cr-settings-sync-page> + <settings-sync-page current-route="[[currentRoute]]"> + </settings-sync-page> </neon-animatable> </settings-animated-pages> </template>
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.html b/chrome/browser/resources/settings/site_settings_page/site_settings_page.html index 5f19eb55..bd29e73 100644 --- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.html +++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.html
@@ -4,7 +4,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/communication-icons.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/social-icons.html"> -<dom-module id="cr-settings-site-settings-page"> +<dom-module id="settings-site-settings-page"> <link rel="import" type="css" href="site_settings_page.css"> <template> <div class="settings-list">
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js index 19a6177..665c7abc 100644 --- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js +++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
@@ -4,22 +4,22 @@ /** * @fileoverview - * 'cr-settings-site-settings-page' is the settings page containing privacy and + * 'settings-site-settings-page' is the settings page containing privacy and * security site settings. * * Example: * * <iron-animated-pages> - * <cr-settings-site-settings-page prefs="{{prefs}}"> - * </cr-settings-site-settings-page> + * <settings-site-settings-page prefs="{{prefs}}"> + * </settings-site-settings-page> * ... other pages ... * </iron-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-site-settings-page + * @element settings-site-settings-page */ Polymer({ - is: 'cr-settings-site-settings-page', + is: 'settings-site-settings-page', properties: { /**
diff --git a/chrome/browser/resources/settings/sync_page/sync_page.html b/chrome/browser/resources/settings/sync_page/sync_page.html index e565d6a..c8a856c 100644 --- a/chrome/browser/resources/settings/sync_page/sync_page.html +++ b/chrome/browser/resources/settings/sync_page/sync_page.html
@@ -5,7 +5,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html"> <link rel="import" href="chrome://md-settings/controls/settings_checkbox.html"> -<dom-module id="cr-settings-sync-page"> +<dom-module id="settings-sync-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css" href="sync_page.css">
diff --git a/chrome/browser/resources/settings/sync_page/sync_page.js b/chrome/browser/resources/settings/sync_page/sync_page.js index 062f3d22..d63575d 100644 --- a/chrome/browser/resources/settings/sync_page/sync_page.js +++ b/chrome/browser/resources/settings/sync_page/sync_page.js
@@ -4,18 +4,18 @@ /** * @fileoverview - * 'cr-settings-sync-page' is the settings page containing sync settings. + * 'settings-sync-page' is the settings page containing sync settings. * * Example: * * <iron-animated-pages> - * <cr-settings-sync-page></cr-settings-sync-page> + * <settings-sync-page></settings-sync-page> * ... other pages ... * </iron-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-sync-page + * @element settings-sync-page */ Polymer({ - is: 'cr-settings-sync-page', + is: 'settings-sync-page', });
diff --git a/chrome/browser/resources/settings/sync_page/sync_private_api.html b/chrome/browser/resources/settings/sync_page/sync_private_api.html new file mode 100644 index 0000000..b2c4a00 --- /dev/null +++ b/chrome/browser/resources/settings/sync_page/sync_private_api.html
@@ -0,0 +1 @@ +<script src="chrome://md-settings/sync_page/sync_private_api.js"></script>
diff --git a/chrome/browser/resources/settings/sync_page/sync_private_api.js b/chrome/browser/resources/settings/sync_page/sync_private_api.js new file mode 100644 index 0000000..d89302b --- /dev/null +++ b/chrome/browser/resources/settings/sync_page/sync_private_api.js
@@ -0,0 +1,176 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +cr.define('settings', function() { + /** + * API which encapsulates messaging between JS and C++ for the sync page. + * @constructor + */ + function SyncPrivateApi() {} + + /** + * The state of sync. This is the data structure sent back and forth between + * C++ and JS. Its naming and structure is not optimal, but changing it would + * require changes to the C++ handler, which is already functional. + * @typedef {{ + * appsEnforced: boolean, + * appsRegistered: boolean, + * appsSynced: boolean, + * autofillEnforced: boolean, + * autofillRegistered: boolean, + * autofillSynced: boolean, + * bookmarksEnforced: boolean, + * bookmarksRegistered: boolean, + * bookmarksSynced: boolean, + * encryptAllData: boolean, + * encryptAllDataAllowed: boolean, + * enterGooglePassphraseBody: (string|undefined), + * enterPassphraseBody: (string|undefined), + * extensionsEnforced: boolean, + * extensionsRegistered: boolean, + * extensionsSynced: boolean, + * fullEncryptionBody: string, + * isGooglePassphrase: (boolean|undefined), + * passphrase: (string|undefined), + * passphraseFailed: boolean, + * passwordsEnforced: boolean, + * passwordsRegistered: boolean, + * passwordsSynced: boolean, + * preferencesEnforced: boolean, + * preferencesRegistered: boolean, + * preferencesSynced: boolean, + * showPassphrase: boolean, + * syncAllDataTypes: boolean, + * syncNothing: boolean, + * tabsEnforced: boolean, + * tabsRegistered: boolean, + * tabsSynced: boolean, + * themesEnforced: boolean, + * themesRegistered: boolean, + * themesSynced: boolean, + * typedUrlsEnforced: boolean, + * typedUrlsRegistered: boolean, + * typedUrlsSynced: boolean, + * usePassphrase: boolean, + * wifiCredentialsEnforced: (boolean|undefined), + * wifiCredentialsSynced: (boolean|undefined) + * }} + */ + SyncPrivateApi.SyncPrefs; + + /** + * @enum {string} + */ + SyncPrivateApi.PageStatus = { + CONFIGURE: 'configure', + TIMED_OUT: 'timeout', + DONE: 'done', + PASSPHRASE_ERROR: 'passphraseError', + }; + + /** @private {?function(SyncPrivateApi.SyncPrefs)} */ + SyncPrivateApi.syncPrefsCallback_ = null; + + /** @private {?function(SyncPrivateApi.PageStatus)} */ + SyncPrivateApi.setPageStatusCallback_ = null; + + /** + * Function to invoke when the sync page has been navigated to. This registers + * the UI as the "active" sync UI so that if the user tries to open another + * sync UI, this one will be shown instead. + */ + SyncPrivateApi.didNavigateToSyncPage = function() { + chrome.send('SyncSetupShowSetupUI'); + }; + + /** + * Function to invoke when leaving the sync page so that the C++ layer can be + * notified that the sync UI is no longer open. + */ + SyncPrivateApi.didNavigateAwayFromSyncPage = function() { + SyncPrivateApi.setPageStatusCallback_ = null; + chrome.send('SyncSetupDidClosePage'); + }; + + /** + * Sets the callback to be invoked when sync data has been fetched. + * @param {!function(SyncPrivateApi.SyncPrefs)} callback + */ + SyncPrivateApi.setSyncPrefsCallback = function(callback) { + SyncPrivateApi.syncPrefsCallback_ = callback; + }; + + /** + * Handler for when state has been fetched from C++. + * @param {!SyncPrivateApi.SyncPrefs} syncPrefsFromCpp + * @private + */ + SyncPrivateApi.sendSyncPrefs_ = function(syncPrefsFromCpp) { + if (SyncPrivateApi.syncPrefsCallback_) + SyncPrivateApi.syncPrefsCallback_(syncPrefsFromCpp); + }; + + /** + * Sets the sync state by sending it to the C++ layer. + * @param {!SyncPrivateApi.SyncPrefs} syncPrefs + * @param {!function(SyncPrivateApi.PageStatus)} callback + */ + SyncPrivateApi.setSyncPrefs = function(syncPrefs, callback) { + SyncPrivateApi.setPageStatusCallback_ = callback; + chrome.send('SyncSetupConfigure', [JSON.stringify(syncPrefs)]); + }; + + /** + * Handler for when setSyncPrefs() has either succeeded or failed. + * @param {!SyncPrivateApi.SyncPrefs} state + * @private + */ + SyncPrivateApi.setPageStatus_ = function(state) { + if (SyncPrivateApi.setPageStatusCallback_) + SyncPrivateApi.setPageStatusCallback_(state); + + SyncPrivateApi.setPageStatusCallback_ = null; + }; + + /** + * Legacy object called by SyncSetupHandler. It's an inconsistent name, but + * needed to allow a single handler to support both old and new Sync settings. + * TODO(tommycli): Remove when old Sync in Options is removed. + */ + function SyncSetupOverlay() {} + + /** + * This function encapsulates the logic that maps from the legacy + * SyncSettingsHandler to an API natural to the new Polymer implementation. + * @param {!SyncPrivateApi.PageStatus} status + * @param {!SyncPrivateApi.SyncPrefs} prefs + */ + SyncSetupOverlay.showSyncSetupPage = function(status, prefs) { + switch (status) { + case SyncPrivateApi.PageStatus.TIMED_OUT: + case SyncPrivateApi.PageStatus.DONE: + SyncPrivateApi.setPageStatus_(status); + break; + case SyncPrivateApi.PageStatus.CONFIGURE: + if (prefs.passphraseFailed) { + SyncPrivateApi.setPageStatus_( + SyncPrivateApi.PageStatus.PASSPHRASE_ERROR); + return; + } + + SyncPrivateApi.sendSyncPrefs_(prefs); + break; + default: + // Other statuses (i.e. "spinner") are ignored. + } + }; + + return { + SyncPrivateApi: SyncPrivateApi, + SyncSetupOverlay: SyncSetupOverlay, + }; +}); + +// Must be global for the legacy C++ handler to call. +var SyncSetupOverlay = settings.SyncSetupOverlay;
diff --git a/chrome/browser/resources/settings/users_page/user_list.html b/chrome/browser/resources/settings/users_page/user_list.html index 6663ceac..88f1bf52 100644 --- a/chrome/browser/resources/settings/users_page/user_list.html +++ b/chrome/browser/resources/settings/users_page/user_list.html
@@ -2,7 +2,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html"> -<dom-module id="cr-settings-user-list"> +<dom-module id="settings-user-list"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css" href="user_list.css">
diff --git a/chrome/browser/resources/settings/users_page/user_list.js b/chrome/browser/resources/settings/users_page/user_list.js index dae00f5b..35bce2380 100644 --- a/chrome/browser/resources/settings/users_page/user_list.js +++ b/chrome/browser/resources/settings/users_page/user_list.js
@@ -4,19 +4,19 @@ /** * @fileoverview - * 'cr-settings-user-list' shows a list of users whitelisted on this Chrome OS + * 'settings-user-list' shows a list of users whitelisted on this Chrome OS * device. * * Example: * - * <cr-settings-user-list prefs="{{prefs}}"> - * </cr-settings-user-list> + * <settings-user-list prefs="{{prefs}}"> + * </settings-user-list> * * @group Chrome Settings Elements - * @element cr-settings-user-list + * @element settings-user-list */ Polymer({ - is: 'cr-settings-user-list', + is: 'settings-user-list', properties: { /**
diff --git a/chrome/browser/resources/settings/users_page/users_page.html b/chrome/browser/resources/settings/users_page/users_page.html index eba63ee..2f33ad1 100644 --- a/chrome/browser/resources/settings/users_page/users_page.html +++ b/chrome/browser/resources/settings/users_page/users_page.html
@@ -7,7 +7,7 @@ <link rel="import" href="chrome://md-settings/settings_page/settings_section.html"> <link rel="import" href="user_list.html"> -<dom-module id="cr-settings-users-page"> +<dom-module id="settings-users-page"> <link rel="import" type="css" href="chrome://md-settings/settings_page/settings_page.css"> <link rel="import" type="css" href="users_page.css"> @@ -44,9 +44,9 @@ </div> <div class="users"> <div> - <cr-settings-user-list prefs="[[prefs]]" + <settings-user-list prefs="[[prefs]]" disabled="[[editingUsersDisabled]]"> - </cr-settings-user-list> + </settings-user-list> </div> <div> <paper-input id="addUserInput" i18n-values="label:addUsersLabel"
diff --git a/chrome/browser/resources/settings/users_page/users_page.js b/chrome/browser/resources/settings/users_page/users_page.js index 44681b25..da31d39 100644 --- a/chrome/browser/resources/settings/users_page/users_page.js +++ b/chrome/browser/resources/settings/users_page/users_page.js
@@ -4,22 +4,22 @@ /** * @fileoverview - * 'cr-settings-users-page' is the settings page for managing user accounts on + * 'settings-users-page' is the settings page for managing user accounts on * the device. * * Example: * * <neon-animated-pages> - * <cr-settings-users-page prefs="{{prefs}}"> - * </cr-settings-users-page> + * <settings-users-page prefs="{{prefs}}"> + * </settings-users-page> * ... other pages ... * </neon-animated-pages> * * @group Chrome Settings Elements - * @element cr-settings-users-page + * @element settings-users-page */ Polymer({ - is: 'cr-settings-users-page', + is: 'settings-users-page', behaviors: [ Polymer.IronA11yKeysBehavior
diff --git a/chrome/browser/safe_browsing/srt_fetcher_win.cc b/chrome/browser/safe_browsing/srt_fetcher_win.cc index e21be259..f999b77 100644 --- a/chrome/browser/safe_browsing/srt_fetcher_win.cc +++ b/chrome/browser/safe_browsing/srt_fetcher_win.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/safe_browsing/srt_fetcher_win.h" +#include <vector> + #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback_helpers.h" @@ -46,9 +48,25 @@ const wchar_t kSoftwareRemovalToolRegistryKey[] = L"Software\\Google\\Software Removal Tool"; +const wchar_t kEndTimeValueName[] = L"EndTime"; +const wchar_t kStartTimeValueName[] = L"StartTime"; namespace { +// Used to send UMA information about missing start and end time registry values +// for the reporter. +enum SwReporterRunningTimeRegistryError { + REPORTER_RUNNING_TIME_ERROR_NO_ERROR = 0, + REPORTER_RUNNING_TIME_ERROR_REGISTRY_KEY_INVALID = 1, + REPORTER_RUNNING_TIME_ERROR_MISSING_START_TIME = 2, + REPORTER_RUNNING_TIME_ERROR_MISSING_END_TIME = 3, + REPORTER_RUNNING_TIME_ERROR_MISSING_BOTH_TIMES = 4, + REPORTER_RUNNING_TIME_ERROR_MAX, +}; + +const char kRunningTimeErrorMetricName[] = + "SoftwareReporter.RunningTimeRegistryError"; + // Overrides for the reporter launcher and prompt triggers free function, used // by tests. ReporterLauncher g_reporter_launcher_; @@ -287,6 +305,63 @@ new SRTFetcher(profile); } +// Report the SwReporter run time with UMA both as reported by the tool via +// the registry and as measured by |ReporterRunner|. +void ReportSwReporterRuntime(const base::TimeDelta& reporter_running_time) { + UMA_HISTOGRAM_LONG_TIMES("SoftwareReporter.RunningTimeAccordingToChrome", + reporter_running_time); + + base::win::RegKey reporter_key( + HKEY_CURRENT_USER, kSoftwareRemovalToolRegistryKey, KEY_ALL_ACCESS); + if (!reporter_key.Valid()) { + UMA_HISTOGRAM_ENUMERATION(kRunningTimeErrorMetricName, + REPORTER_RUNNING_TIME_ERROR_REGISTRY_KEY_INVALID, + REPORTER_RUNNING_TIME_ERROR_MAX); + return; + } + + bool has_start_time = false; + int64 start_time_value = 0; + if (reporter_key.HasValue(kStartTimeValueName) && + reporter_key.ReadInt64(kStartTimeValueName, &start_time_value) == + ERROR_SUCCESS) { + has_start_time = true; + reporter_key.DeleteValue(kStartTimeValueName); + } + + bool has_end_time = false; + int64 end_time_value = 0; + if (reporter_key.HasValue(kEndTimeValueName) && + reporter_key.ReadInt64(kEndTimeValueName, &end_time_value) == + ERROR_SUCCESS) { + has_end_time = true; + reporter_key.DeleteValue(kEndTimeValueName); + } + + if (has_start_time && has_end_time) { + base::TimeDelta registry_run_time = + base::Time::FromInternalValue(end_time_value) - + base::Time::FromInternalValue(start_time_value); + UMA_HISTOGRAM_LONG_TIMES("SoftwareReporter.RunningTime", registry_run_time); + UMA_HISTOGRAM_ENUMERATION(kRunningTimeErrorMetricName, + REPORTER_RUNNING_TIME_ERROR_NO_ERROR, + REPORTER_RUNNING_TIME_ERROR_MAX); + } else if (!has_start_time && !has_end_time) { + UMA_HISTOGRAM_ENUMERATION(kRunningTimeErrorMetricName, + REPORTER_RUNNING_TIME_ERROR_MISSING_BOTH_TIMES, + REPORTER_RUNNING_TIME_ERROR_MAX); + } else if (!has_start_time) { + UMA_HISTOGRAM_ENUMERATION(kRunningTimeErrorMetricName, + REPORTER_RUNNING_TIME_ERROR_MISSING_START_TIME, + REPORTER_RUNNING_TIME_ERROR_MAX); + } else { + DCHECK(!has_end_time); + UMA_HISTOGRAM_ENUMERATION(kRunningTimeErrorMetricName, + REPORTER_RUNNING_TIME_ERROR_MISSING_END_TIME, + REPORTER_RUNNING_TIME_ERROR_MAX); + } +} + // This class tries to run the reporter and reacts to its exit code. It // schedules subsequent runs as needed, or retries as soon as a browser is // available when none is on first try. @@ -335,9 +410,11 @@ // This method is called on the UI thread when the reporter run has completed. // This is run as a task posted from an interruptible worker thread so should // be resilient to unexpected shutdown. - void ReporterDone(int exit_code) { + void ReporterDone(const base::Time& reporter_start_time, int exit_code) { DCHECK(thread_checker_.CalledOnValidThread()); + base::TimeDelta reporter_running_time = + base::Time::Now() - reporter_start_time; // Don't continue when the reporter process failed to launch, but still try // again after the regular delay. It's not worth retrying earlier, risking // running too often if it always fails, since not many users fail here. @@ -356,6 +433,7 @@ local_state->SetInt64(prefs::kSwReporterLastTimeTriggered, base::Time::Now().ToInternalValue()); } + ReportSwReporterRuntime(reporter_running_time); if (!IsInSRTPromptFieldTrialGroups()) { // Knowing about disabled field trial is more important than reporter not @@ -421,7 +499,8 @@ base::PostTaskAndReplyWithResult( blocking_task_runner_.get(), FROM_HERE, base::Bind(&LaunchAndWaitForExit, exe_path_, version_), - base::Bind(&ReporterRunner::ReporterDone, base::Unretained(this))); + base::Bind(&ReporterRunner::ReporterDone, base::Unretained(this), + base::Time::Now())); } else { main_thread_task_runner_->PostDelayedTask( FROM_HERE,
diff --git a/chrome/browser/safe_browsing/srt_fetcher_win.h b/chrome/browser/safe_browsing/srt_fetcher_win.h index 76f2813..a2e180b 100644 --- a/chrome/browser/safe_browsing/srt_fetcher_win.h +++ b/chrome/browser/safe_browsing/srt_fetcher_win.h
@@ -19,8 +19,10 @@ namespace safe_browsing { -// The registry key for the Reporter and Cleaner. +// SRT registry keys and value names. extern const wchar_t kSoftwareRemovalToolRegistryKey[]; +extern const wchar_t kEndTimeValueName[]; +extern const wchar_t kStartTimeValueName[]; // Reporter exit codes. const int kSwReporterCleanupNeeded = 0;
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc index 3ea6584..9dec1aa 100644 --- a/chrome/browser/sessions/session_restore_browsertest.cc +++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -4,6 +4,7 @@ #include <vector> +#include "base/base_switches.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/memory/memory_pressure_listener.h"
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc index 6d50c0b..8b79012 100644 --- a/chrome/browser/ssl/ssl_browser_tests.cc +++ b/chrome/browser/ssl/ssl_browser_tests.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/base_switches.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback.h"
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc index c8c24c6..e3593a6 100644 --- a/chrome/browser/supervised_user/supervised_user_service.cc +++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -41,6 +41,7 @@ #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/browser/signin_manager_base.h" +#include "components/signin/core/common/signin_switches.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/user_metrics.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc b/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc index a734f1b0..3a4eea6a 100644 --- a/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc +++ b/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/base_switches.h" #include "base/bind.h" #include "base/command_line.h" #include "base/prefs/pref_service.h"
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 3e5991d..42718b9 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -535,6 +535,8 @@ "exclusive_access/fullscreen_controller_state_tests.h", "exclusive_access/fullscreen_controller_test.cc", "exclusive_access/fullscreen_controller_test.h", + "test/test_confirm_bubble_model.cc", + "test/test_confirm_bubble_model.h", ] }
diff --git a/chrome/browser/ui/android/infobars/confirm_infobar.cc b/chrome/browser/ui/android/infobars/confirm_infobar.cc index 508de2b9..8052f6f 100644 --- a/chrome/browser/ui/android/infobars/confirm_infobar.cc +++ b/chrome/browser/ui/android/infobars/confirm_infobar.cc
@@ -58,7 +58,8 @@ env, delegate->GetLinkText()); ScopedJavaLocalRef<jobject> java_bitmap; - if (!delegate->GetIcon().IsEmpty()) { + if (delegate->GetIconId() == infobars::InfoBarDelegate::kNoIconID && + !delegate->GetIcon().IsEmpty()) { java_bitmap = gfx::ConvertToJavaBitmap(delegate->GetIcon().ToSkBitmap()); }
diff --git a/chrome/browser/ui/app_list/app_list_service_mac.mm b/chrome/browser/ui/app_list/app_list_service_mac.mm index b6673cdf..b5c6d95 100644 --- a/chrome/browser/ui/app_list/app_list_service_mac.mm +++ b/chrome/browser/ui/app_list/app_list_service_mac.mm
@@ -250,7 +250,7 @@ const NSSize ns_window_size = [window frame].size; gfx::Size window_size(ns_window_size.width, ns_window_size.height); int primary_display_height = - NSMaxY([[[NSScreen screens] objectAtIndex:0] frame]); + NSMaxY([[[NSScreen screens] firstObject] frame]); AppListServiceMac::FindAnchorPoint(window_size, display, primary_display_height,
diff --git a/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm b/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm index 337fe2e..bad78a5d 100644 --- a/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm +++ b/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm
@@ -57,7 +57,7 @@ NSRect GfxToCocoaBounds(gfx::Rect bounds) { typedef AppWindow::BoundsSpecification BoundsSpecification; - NSRect main_screen_rect = [[[NSScreen screens] objectAtIndex:0] frame]; + NSRect main_screen_rect = [[[NSScreen screens] firstObject] frame]; // If coordinates are unspecified, center window on primary screen. if (bounds.x() == BoundsSpecification::kUnspecifiedPosition) @@ -452,7 +452,7 @@ gfx::Rect NativeAppWindowCocoa::GetRestoredBounds() const { // Flip coordinates based on the primary screen. - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* screen = [[NSScreen screens] firstObject]; NSRect frame = restored_bounds_; gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame)); bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame)); @@ -469,7 +469,7 @@ gfx::Rect NativeAppWindowCocoa::GetBounds() const { // Flip coordinates based on the primary screen. - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* screen = [[NSScreen screens] firstObject]; NSRect frame = [window() frame]; gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame)); bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame)); @@ -687,7 +687,7 @@ // Flip the coordinates based on the main screen. NSInteger screen_height = - NSHeight([[[NSScreen screens] objectAtIndex:0] frame]); + NSHeight([[[NSScreen screens] firstObject] frame]); NSRect frame_nsrect = [window() frame]; gfx::Rect frame_rect(NSRectToCGRect(frame_nsrect));
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_popup_base_view_cocoa.mm b/chrome/browser/ui/cocoa/autofill/autofill_popup_base_view_cocoa.mm index 8d54aac9..73e2f32a 100644 --- a/chrome/browser/ui/cocoa/autofill/autofill_popup_base_view_cocoa.mm +++ b/chrome/browser/ui/cocoa/autofill/autofill_popup_base_view_cocoa.mm
@@ -139,7 +139,7 @@ // coordinate space places the origin at the top-left of the first screen, // whereas Cocoa's coordinate space expects the origin to be at the // bottom-left of this same screen. - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* screen = [[NSScreen screens] firstObject]; frame.origin.y = NSMaxY([screen frame]) - NSMaxY(frame); // TODO(isherman): The view should support scrolling if the popup gets too
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm b/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm index c4945fd..40584c3 100644 --- a/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm +++ b/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm
@@ -406,7 +406,7 @@ [[field window] convertBaseToScreen:textFrameInScreen.origin]; // And adjust for gfx::Rect being flipped compared to OSX coordinates. - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* screen = [[NSScreen screens] firstObject]; textFrameInScreen.origin.y = NSMaxY([screen frame]) - NSMaxY(textFrameInScreen); gfx::Rect textFrameRect(NSRectToCGRect(textFrameInScreen));
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm index 028c744..a3716da4 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -210,7 +210,7 @@ real_bounds.width(), real_bounds.height()); // Flip coordinates based on the primary screen. - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* screen = [[NSScreen screens] firstObject]; cocoa_bounds.origin.y = NSHeight([screen frame]) - real_bounds.height() - real_bounds.y(); @@ -348,7 +348,7 @@ gfx::Rect BrowserWindowCocoa::GetRestoredBounds() const { // Flip coordinates based on the primary screen. - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* screen = [[NSScreen screens] firstObject]; NSRect frame = [controller_ regularWindowFrame]; gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame)); bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame));
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.mm b/chrome/browser/ui/cocoa/browser_window_controller_private.mm index 99ef304..876f3dc 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_private.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
@@ -122,7 +122,7 @@ [self isInAnyFullscreenMode] ? savedRegularWindow_ : [self window]; // Window positions are stored relative to the origin of the primary monitor. - NSRect monitorFrame = [[[NSScreen screens] objectAtIndex:0] frame]; + NSRect monitorFrame = [[[NSScreen screens] firstObject] frame]; NSScreen* windowScreen = [window screen]; // Start with the window's frame, which is in virtual coordinates. @@ -682,7 +682,7 @@ enteringAppKitFullscreen_ = YES; enteringAppKitFullscreenOnPrimaryScreen_ = - [[[self window] screen] isEqual:[[NSScreen screens] objectAtIndex:0]]; + [[[self window] screen] isEqual:[[NSScreen screens] firstObject]]; fullscreen_mac::SlidingStyle style; if (browser_->exclusive_access_manager() @@ -1098,7 +1098,7 @@ // transition from working well. See http://crbug.com/396980 for more // details. if ([[self class] systemSettingsRequireMavericksAppKitFullscreenHack] && - ![[[self window] screen] isEqual:[[NSScreen screens] objectAtIndex:0]]) { + ![[[self window] screen] isEqual:[[NSScreen screens] firstObject]]) { return NO; }
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm index 9786b9b..0620ce5a 100644 --- a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm +++ b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm
@@ -114,7 +114,7 @@ gfx::Rect OmniboxPopupViewMac::GetTargetBounds() { // Flip the coordinate system before returning. - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* screen = [[NSScreen screens] firstObject]; NSRect monitor_frame = [screen frame]; gfx::Rect bounds(NSRectToCGRect(target_popup_frame_)); bounds.set_y(monitor_frame.size.height - bounds.y() - bounds.height());
diff --git a/chrome/browser/ui/cocoa/panels/panel_utils_cocoa.mm b/chrome/browser/ui/cocoa/panels/panel_utils_cocoa.mm index a5f1739..2fe8a56 100644 --- a/chrome/browser/ui/cocoa/panels/panel_utils_cocoa.mm +++ b/chrome/browser/ui/cocoa/panels/panel_utils_cocoa.mm
@@ -8,7 +8,7 @@ NSRect ConvertRectToCocoaCoordinates(const gfx::Rect& bounds) { // Flip coordinates based on the primary screen. - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* screen = [[NSScreen screens] firstObject]; return NSMakeRect( bounds.x(), NSHeight([screen frame]) - bounds.height() - bounds.y(), @@ -17,7 +17,7 @@ gfx::Rect ConvertRectFromCocoaCoordinates(NSRect bounds) { // Flip coordinates based on the primary screen. - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* screen = [[NSScreen screens] firstObject]; return gfx::Rect( NSMinX(bounds), NSHeight([screen frame]) - NSMaxY(bounds), @@ -26,14 +26,14 @@ NSPoint ConvertPointToCocoaCoordinates(const gfx::Point& point) { // Flip coordinates based on the primary screen. - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* screen = [[NSScreen screens] firstObject]; return NSMakePoint(point.x(), NSHeight([screen frame]) - point.y()); } gfx::Point ConvertPointFromCocoaCoordinates(NSPoint point) { // Flip coordinates based on the primary screen. - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* screen = [[NSScreen screens] firstObject]; return gfx::Point(point.x, NSHeight([screen frame]) - point.y); }
diff --git a/chrome/browser/ui/cocoa/presentation_mode_controller.mm b/chrome/browser/ui/cocoa/presentation_mode_controller.mm index 8f7c688..0998ad7 100644 --- a/chrome/browser/ui/cocoa/presentation_mode_controller.mm +++ b/chrome/browser/ui/cocoa/presentation_mode_controller.mm
@@ -535,7 +535,7 @@ - (BOOL)isWindowOnPrimaryScreen { NSScreen* screen = [[browserController_ window] screen]; - NSScreen* primaryScreen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* primaryScreen = [[NSScreen screens] firstObject]; return (screen == primaryScreen); }
diff --git a/chrome/browser/ui/extensions/extension_message_bubble_factory.cc b/chrome/browser/ui/extensions/extension_message_bubble_factory.cc index 6bda1e5..d898377 100644 --- a/chrome/browser/ui/extensions/extension_message_bubble_factory.cc +++ b/chrome/browser/ui/extensions/extension_message_bubble_factory.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/extensions/extension_message_bubble_factory.h" +#include "base/base_switches.h" #include "base/command_line.h" #include "base/lazy_instance.h" #include "base/metrics/field_trial.h" @@ -17,7 +18,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/channel_info.h" -#include "chrome/common/chrome_switches.h" #include "components/version_info/version_info.h" #include "extensions/common/feature_switch.h"
diff --git a/chrome/browser/ui/search/instant_extended_interactive_uitest.cc b/chrome/browser/ui/search/instant_extended_interactive_uitest.cc index 150d5b3..aae0adf 100644 --- a/chrome/browser/ui/search/instant_extended_interactive_uitest.cc +++ b/chrome/browser/ui/search/instant_extended_interactive_uitest.cc
@@ -4,6 +4,7 @@ #include <sstream> +#include "base/base_switches.h" #include "base/command_line.h" #include "base/metrics/histogram_base.h" #include "base/metrics/histogram_samples.h" @@ -36,7 +37,6 @@ #include "chrome/browser/ui/search/search_tab_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/webui/theme_source.h" -#include "chrome/common/chrome_switches.h" #include "chrome/common/instant_types.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/search_engines/search_engine_tab_helper.cc b/chrome/browser/ui/search_engines/search_engine_tab_helper.cc index 085afa1..4d3b560 100644 --- a/chrome/browser/ui/search_engines/search_engine_tab_helper.cc +++ b/chrome/browser/ui/search_engines/search_engine_tab_helper.cc
@@ -55,14 +55,17 @@ return base::string16(); } - // Don't autogenerate keywords for referrers that are anything other than HTTP - // or have a path. + // Don't autogenerate keywords for referrers that + // a) are anything other than HTTP/HTTPS or + // b) have a path. // // If we relax the path constraint, we need to be sure to sanitize the path // elements and update AutocompletePopup to look for keywords using the path. // See http://b/issue?id=863583. - if (!url.SchemeIs(url::kHttpScheme) || (url.path().length() > 1)) + if (!(url.SchemeIs(url::kHttpScheme) || url.SchemeIs(url::kHttpsScheme)) || + (url.path().length() > 1)) { return base::string16(); + } return TemplateURL::GenerateKeyword(url, accept_languages); } @@ -87,7 +90,9 @@ GenerateKeywordIfNecessary(params); } -bool SearchEngineTabHelper::OnMessageReceived(const IPC::Message& message) { +bool SearchEngineTabHelper::OnMessageReceived( + const IPC::Message& message, + content::RenderFrameHost* render_frame_host) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(SearchEngineTabHelper, message) IPC_MESSAGE_HANDLER(ChromeViewHostMsg_PageHasOSDD, OnPageHasOSDD)
diff --git a/chrome/browser/ui/search_engines/search_engine_tab_helper.h b/chrome/browser/ui/search_engines/search_engine_tab_helper.h index 4ccc1d6d..cab3cb8 100644 --- a/chrome/browser/ui/search_engines/search_engine_tab_helper.h +++ b/chrome/browser/ui/search_engines/search_engine_tab_helper.h
@@ -30,7 +30,8 @@ void DidNavigateMainFrame( const content::LoadCommittedDetails& details, const content::FrameNavigateParams& params) override; - bool OnMessageReceived(const IPC::Message& message) override; + bool OnMessageReceived(const IPC::Message& message, + content::RenderFrameHost* rfh) override; private: explicit SearchEngineTabHelper(content::WebContents* web_contents);
diff --git a/chrome/browser/ui/startup/bad_flags_prompt.cc b/chrome/browser/ui/startup/bad_flags_prompt.cc index 82d9317..88b827a 100644 --- a/chrome/browser/ui/startup/bad_flags_prompt.cc +++ b/chrome/browser/ui/startup/bad_flags_prompt.cc
@@ -16,6 +16,7 @@ #include "chrome/common/switch_utils.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" +#include "components/autofill/core/common/autofill_switches.h" #include "components/infobars/core/simple_alert_infobar_delegate.h" #include "components/invalidation/impl/invalidation_switches.h" #include "components/nacl/common/nacl_switches.h"
diff --git a/chrome/browser/ui/toolbar/media_router_action.cc b/chrome/browser/ui/toolbar/media_router_action.cc index 72a06cef4..34877266f4 100644 --- a/chrome/browser/ui/toolbar/media_router_action.cc +++ b/chrome/browser/ui/toolbar/media_router_action.cc
@@ -57,10 +57,13 @@ weak_ptr_factory_(this) { DCHECK(browser_); tab_strip_model_observer_.Add(browser_->tab_strip_model()); + + RegisterObserver(); OnHasLocalRouteUpdated(GetMediaRouter(browser)->HasLocalRoute()); } MediaRouterAction::~MediaRouterAction() { + UnregisterObserver(); } std::string MediaRouterAction::GetId() const {
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc index 29c1272..39b360a 100644 --- a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc +++ b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
@@ -48,7 +48,7 @@ const int kNonClientRestoredExtraThickness = 9; // In the window corners, the resize areas don't actually expand bigger, but the // 16 px at the end of the top and bottom edges triggers diagonal resizing. -const int kResizeAreaCornerSize = 16; +const int kResizeCornerWidth = 16; // The avatar ends 2 px above the bottom of the tabstrip (which, given the // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the // user). @@ -243,7 +243,7 @@ // first so that clicks in a tab don't get treated as sysmenu clicks. int nonclient_border_thickness = NonClientBorderThickness(); if (gfx::Rect(nonclient_border_thickness, - gfx::win::GetSystemMetricsInDIP(SM_CXSIZEFRAME), + gfx::win::GetSystemMetricsInDIP(SM_CYSIZEFRAME), gfx::win::GetSystemMetricsInDIP(SM_CXSMICON), gfx::win::GetSystemMetricsInDIP(SM_CYSMICON)).Contains(point)) return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; @@ -251,11 +251,17 @@ if (frame_component != HTNOWHERE) return frame_component; - int frame_border_thickness = FrameBorderThickness(); - int window_component = GetHTComponentForFrame(point, frame_border_thickness, - nonclient_border_thickness, frame_border_thickness, - kResizeAreaCornerSize - frame_border_thickness, - frame()->widget_delegate()->CanResize()); + int frame_top_border_height = FrameTopBorderHeight(); + // We want the resize corner behavior to apply to the kResizeCornerWidth + // pixels at each end of the top and bottom edges. Because |point|'s x + // coordinate is based on the DWM-inset portion of the window (so, it's 0 at + // the first pixel inside the left DWM margin), we need to subtract the DWM + // margin thickness, which we calculate as the total frame border thickness + // minus the nonclient border thickness. + const int dwm_margin = FrameBorderThickness() - nonclient_border_thickness; + int window_component = GetHTComponentForFrame(point, frame_top_border_height, + nonclient_border_thickness, frame_top_border_height, + kResizeCornerWidth - dwm_margin, frame()->widget_delegate()->CanResize()); // Fall back to the caption if no other component matches. return (window_component == HTNOWHERE) ? HTCAPTION : window_component; } @@ -325,6 +331,14 @@ 0 : gfx::win::GetSystemMetricsInDIP(SM_CXSIZEFRAME); } +int GlassBrowserFrameView::FrameTopBorderHeight() const { + // We'd like to use FrameBorderThickness() here, but the maximized Aero glass + // frame has a 0 frame border around most edges and a CYSIZEFRAME-thick border + // at the top (see AeroGlassFrame::OnGetMinMaxInfo()). + return frame()->IsFullscreen() ? + 0 : gfx::win::GetSystemMetricsInDIP(SM_CYSIZEFRAME); +} + int GlassBrowserFrameView::NonClientBorderThickness() const { if (frame()->IsMaximized() || frame()->IsFullscreen()) return 0; @@ -338,13 +352,13 @@ if (frame()->IsFullscreen()) return 0; - // We'd like to use FrameBorderThickness() here, but the maximized Aero glass - // frame has a 0 frame border around most edges and a CYSIZEFRAME-thick border - // at the top (see AeroGlassFrame::OnGetMinMaxInfo()). - return gfx::win::GetSystemMetricsInDIP(SM_CYSIZEFRAME) + + // The tab top inset is equal to the height of any shadow region above the + // tabs, plus a 1 px top stroke. In maximized mode, we want to push the + // shadow region off the top of the screen. + const int tab_shadow_height = GetLayoutInsets(TAB).top() - 1; + return FrameTopBorderHeight() + (frame()->IsMaximized() ? - -GetLayoutConstant(TABSTRIP_TOP_SHADOW_HEIGHT) : - kNonClientRestoredExtraThickness); + -tab_shadow_height : kNonClientRestoredExtraThickness); } void GlassBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) { @@ -497,13 +511,19 @@ button_x = width() - frame()->GetMinimizeButtonOffset() + kNewAvatarButtonOffset; - // We need to offset the button correctly in maximized mode, so that the - // custom glass style aligns with the native control glass style. The - // glass shadow is off by 1px, which was determined by visual inspection. - const int shadow_height = GetLayoutConstant(TABSTRIP_TOP_SHADOW_HEIGHT); - int button_y = frame()->IsMaximized() ? - (NonClientTopBorderHeight() + shadow_height - 1) : 1; - + // The caption button position and size is confusing. In maximized mode, the + // caption buttons are SM_CYMENUSIZE pixels high and are placed + // FrameTopBorderHeight() pixels from the top of the window; all those top + // border pixels are offscreen, so this result in caption buttons flush with + // the top of the screen. In restored mode, the caption buttons are first + // placed just below a 2 px border at the top of the window (which is the + // first two pixels' worth of FrameTopBorderHeight()), then extended upwards + // one extra pixel to overlap part of this border. + // + // To match both of these, we size the button as if it's always the extra one + // pixel in height, then we place it at the correct position in restored mode, + // or one pixel above the top of the screen in maximized mode. + int button_y = frame()->IsMaximized() ? (FrameTopBorderHeight() - 1) : 1; new_avatar_button()->SetBounds( button_x, button_y, @@ -524,10 +544,8 @@ int avatar_bottom = GetTopInset() + browser_view()->GetTabStripHeight() - kAvatarBottomSpacing; - int avatar_restored_y = avatar_bottom - incognito_icon.height(); - const int shadow_height = GetLayoutConstant(TABSTRIP_TOP_SHADOW_HEIGHT); int avatar_y = frame()->IsMaximized() ? - (NonClientTopBorderHeight() + shadow_height) : avatar_restored_y; + FrameTopBorderHeight() : (avatar_bottom - incognito_icon.height()); avatar_bounds_.SetRect(avatar_x, avatar_y, incognito_icon.width(), browser_view()->ShouldShowAvatar() ? (avatar_bottom - avatar_y) : 0); if (avatar_button())
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view.h b/chrome/browser/ui/views/frame/glass_browser_frame_view.h index 292d56e1..748ef25 100644 --- a/chrome/browser/ui/views/frame/glass_browser_frame_view.h +++ b/chrome/browser/ui/views/frame/glass_browser_frame_view.h
@@ -53,10 +53,13 @@ bool DoesIntersectRect(const views::View* target, const gfx::Rect& rect) const override; - // Returns the thickness of the border that makes up the window frame edges. - // This does not include any client edge. + // Returns the thickness of the border that makes up the window left, right, + // and bottom frame edges. This does not include any client edge. int FrameBorderThickness() const; + // Returns the height of the window top frame edge. + int FrameTopBorderHeight() const; + // Returns the thickness of the entire nonclient left, right, and bottom // borders, including both the window frame and any client edge. int NonClientBorderThickness() const;
diff --git a/chrome/browser/ui/views/layout_constants.cc b/chrome/browser/ui/views/layout_constants.cc index 2414aba..66ee3fc 100644 --- a/chrome/browser/ui/views/layout_constants.cc +++ b/chrome/browser/ui/views/layout_constants.cc
@@ -27,7 +27,6 @@ const int kTabstripTabOverlap[] = {26, 26, 26}; #endif const int kTabstripToolbarOverlap[] = {3, 3, 3}; - const int kTabstripTopShadowHeight[] = {3, 3, 3}; const int kToolbarContentShadowHeight[] = {0, 0, 0}; const int kToolbarContentShadowHeightAsh[] = {2, 0, 0}; const int kToolbarElementPadding[] = {0, 0, 8}; @@ -58,8 +57,6 @@ return kTabstripTabOverlap[mode]; case TABSTRIP_TOOLBAR_OVERLAP: return kTabstripToolbarOverlap[mode]; - case TABSTRIP_TOP_SHADOW_HEIGHT: - return kTabstripTopShadowHeight[mode]; case TAB_CLOSE_BUTTON_TRAILING_PADDING_OVERLAP: return kTabCloseButtonTrailingPaddingOverlap[mode]; case TAB_FAVICON_TITLE_SPACING:
diff --git a/chrome/browser/ui/views/layout_constants.h b/chrome/browser/ui/views/layout_constants.h index 3c14b98..0125719 100644 --- a/chrome/browser/ui/views/layout_constants.h +++ b/chrome/browser/ui/views/layout_constants.h
@@ -46,9 +46,6 @@ // The vertical overlap of the tabstrip atop the toolbar. TABSTRIP_TOOLBAR_OVERLAP, - // The height of the shadow region above the top of the tabs. - TABSTRIP_TOP_SHADOW_HEIGHT, - // The amount by which the tab close button should overlap the trailing // padding region after the tab's contents region. TAB_CLOSE_BUTTON_TRAILING_PADDING_OVERLAP,
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui.cc b/chrome/browser/ui/webui/media_router/media_router_ui.cc index ebaf89c..30b7602 100644 --- a/chrome/browser/ui/webui/media_router/media_router_ui.cc +++ b/chrome/browser/ui/webui/media_router/media_router_ui.cc
@@ -157,6 +157,9 @@ } MediaRouterUI::~MediaRouterUI() { + if (issues_observer_) + issues_observer_->UnregisterObserver(); + if (query_result_manager_.get()) query_result_manager_->RemoveObserver(this); if (presentation_service_delegate_.get()) @@ -204,8 +207,7 @@ DCHECK(initiator); DCHECK(router_); - // Register for Issue and MediaRoute updates. - issues_observer_.reset(new UIIssuesObserver(router_, this)); + // Register for MediaRoute updates. routes_observer_.reset(new UIMediaRoutesObserver( router_, base::Bind(&MediaRouterUI::OnRoutesUpdated, base::Unretained(this)))); @@ -253,88 +255,15 @@ void MediaRouterUI::UIInitialized() { ui_initialized_ = true; + + // Register for Issue updates. + if (!issues_observer_) + issues_observer_.reset(new UIIssuesObserver(router_, this)); + issues_observer_->RegisterObserver(); } -bool MediaRouterUI::CreateRoute(const MediaSink::Id& sink_id) { - return DoCreateRoute(sink_id, GetPreferredCastMode(cast_modes_)); -} - -bool MediaRouterUI::CreateRouteWithCastModeOverride( - const MediaSink::Id& sink_id, - MediaCastMode cast_mode_override) { - // NOTE: It's actually not an override if - // |cast_mode_override| == |GetPreferredCastMode(cast_modes_)|. - return DoCreateRoute(sink_id, cast_mode_override); -} - -void MediaRouterUI::CloseRoute(const MediaRoute::Id& route_id) { - router_->CloseRoute(route_id); -} - -void MediaRouterUI::AddIssue(const Issue& issue) { - router_->AddIssue(issue); -} - -void MediaRouterUI::ClearIssue(const std::string& issue_id) { - router_->ClearIssue(issue_id); -} - -std::string MediaRouterUI::GetInitialHeaderText() const { - if (cast_modes_.empty()) - return std::string(); - - return MediaCastModeToDescription(GetPreferredCastMode(cast_modes_), - GetTruncatedHostFromURL(frame_url_)); -} - -std::string MediaRouterUI::GetInitialHeaderTextTooltip() const { - if (cast_modes_.empty()) - return std::string(); - - return GetHostFromURL(frame_url_); -} - -void MediaRouterUI::OnResultsUpdated( - const std::vector<MediaSinkWithCastModes>& sinks) { - sinks_ = sinks; - if (ui_initialized_) - handler_->UpdateSinks(sinks_); -} - -void MediaRouterUI::SetIssue(const Issue* issue) { - if (ui_initialized_) - handler_->UpdateIssue(issue); -} - -void MediaRouterUI::OnRoutesUpdated(const std::vector<MediaRoute>& routes) { - routes_ = routes; - if (ui_initialized_) - handler_->UpdateRoutes(routes_); -} - -void MediaRouterUI::OnRouteResponseReceived(const int route_request_id, - const MediaSink::Id& sink_id, - const MediaRoute* route, - const std::string& presentation_id, - const std::string& error) { - DVLOG(1) << "OnRouteResponseReceived"; - // If we receive a new route that we aren't expecting, do nothing. - if (route_request_id != current_route_request_id_) - return; - - if (!route) { - // The provider will handle sending an issue for a failed route request. - DVLOG(0) << "MediaRouteResponse returned error: " << error; - } - - handler_->OnCreateRouteResponseReceived(sink_id, route); - requesting_route_for_default_source_ = false; - current_route_request_id_ = -1; - route_creation_timer_.Stop(); -} - -bool MediaRouterUI::DoCreateRoute(const MediaSink::Id& sink_id, - MediaCastMode cast_mode) { +bool MediaRouterUI::CreateRoute(const MediaSink::Id& sink_id, + MediaCastMode cast_mode) { DCHECK(query_result_manager_.get()); DCHECK(initiator_); @@ -405,6 +334,57 @@ return true; } +void MediaRouterUI::CloseRoute(const MediaRoute::Id& route_id) { + router_->CloseRoute(route_id); +} + +void MediaRouterUI::AddIssue(const Issue& issue) { + router_->AddIssue(issue); +} + +void MediaRouterUI::ClearIssue(const std::string& issue_id) { + router_->ClearIssue(issue_id); +} + +void MediaRouterUI::OnResultsUpdated( + const std::vector<MediaSinkWithCastModes>& sinks) { + sinks_ = sinks; + if (ui_initialized_) + handler_->UpdateSinks(sinks_); +} + +void MediaRouterUI::SetIssue(const Issue* issue) { + if (ui_initialized_) + handler_->UpdateIssue(issue); +} + +void MediaRouterUI::OnRoutesUpdated(const std::vector<MediaRoute>& routes) { + routes_ = routes; + if (ui_initialized_) + handler_->UpdateRoutes(routes_); +} + +void MediaRouterUI::OnRouteResponseReceived(const int route_request_id, + const MediaSink::Id& sink_id, + const MediaRoute* route, + const std::string& presentation_id, + const std::string& error) { + DVLOG(1) << "OnRouteResponseReceived"; + // If we receive a new route that we aren't expecting, do nothing. + if (route_request_id != current_route_request_id_) + return; + + if (!route) { + // The provider will handle sending an issue for a failed route request. + DVLOG(0) << "MediaRouteResponse returned error: " << error; + } + + handler_->OnCreateRouteResponseReceived(sink_id, route); + requesting_route_for_default_source_ = false; + current_route_request_id_ = -1; + route_creation_timer_.Stop(); +} + void MediaRouterUI::RouteCreationTimeout() { requesting_route_for_default_source_ = false; current_route_request_id_ = -1;
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui.h b/chrome/browser/ui/webui/media_router/media_router_ui.h index 7ef49b7e..3d7859f4 100644 --- a/chrome/browser/ui/webui/media_router/media_router_ui.h +++ b/chrome/browser/ui/webui/media_router/media_router_ui.h
@@ -87,20 +87,12 @@ // Notifies this instance that the UI has been initialized. void UIInitialized(); - // Requests a route be created from the source determined by the preferred - // MediaCastMode, to the sink given by |sink_id|. - // The preferred cast mode is determined from the set of currently supported - // cast modes in |cast_modes_|. - // Returns false if unable to request the route. + // Requests a route be created from the source mapped to + // |cast_mode|, to the sink given by |sink_id|. + // Returns true if a route request is successfully submitted. // |OnRouteResponseReceived()| will be invoked when the route request // completes. - bool CreateRoute(const MediaSink::Id& sink_id); - - // Requests a route be created from the source mapped to - // |cast_mode_override|, to the sink given by |sink_id|. - // Returns true if a route request is successfully submitted. - bool CreateRouteWithCastModeOverride(const MediaSink::Id& sink_id, - MediaCastMode cast_mode_override); + bool CreateRoute(const MediaSink::Id& sink_id, MediaCastMode cast_mode); // Calls MediaRouter to close the given route. void CloseRoute(const MediaRoute::Id& route_id); @@ -111,15 +103,6 @@ // Calls MediaRouter to clear the given issue. void ClearIssue(const Issue::Id& issue_id); - // Returns the header text that should be displayed in the UI when it is - // initially loaded. The header text is determined by the preferred cast mode. - std::string GetInitialHeaderText() const; - - // Returns the tooltip text for the header that should be displayed - // in the UI when it is initially loaded. At present, this text is - // just the full hostname of the current site. - std::string GetInitialHeaderTextTooltip() const; - // Returns the hostname of the default source's parent frame URL. std::string GetFrameURLHost() const; bool HasPendingRouteRequest() const { @@ -177,8 +160,6 @@ const std::string& presentation_id, const std::string& error); - bool DoCreateRoute(const MediaSink::Id& sink_id, MediaCastMode cast_mode); - // Creates and sends an issue if route creation times out. void RouteCreationTimeout();
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc index 452de54..3c44c1c3c 100644 --- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc +++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
@@ -253,11 +253,6 @@ DVLOG(1) << "OnRequestInitialData"; base::DictionaryValue initial_data; - initial_data.SetString("headerText", - media_router_ui_->GetInitialHeaderText()); - initial_data.SetString("headerTextTooltip", - media_router_ui_->GetInitialHeaderTextTooltip()); - // "No Cast devices found?" Chromecast help center page. initial_data.SetString("deviceMissingUrl", base::StringPrintf(kHelpPageUrlPrefix, 3249268)); @@ -269,10 +264,14 @@ media_router_ui_->GetRouteProviderExtensionId())); initial_data.Set("routes", routes.release()); - scoped_ptr<base::ListValue> cast_modes(CastModesToValue( - media_router_ui_->cast_modes(), - media_router_ui_->GetFrameURLHost())); - initial_data.Set("castModes", cast_modes.release()); + const std::set<MediaCastMode> cast_modes = media_router_ui_->cast_modes(); + scoped_ptr<base::ListValue> cast_modes_list( + CastModesToValue(cast_modes, media_router_ui_->GetFrameURLHost())); + initial_data.Set("castModes", cast_modes_list.release()); + if (!cast_modes.empty()) { + initial_data.SetInteger("initialCastModeType", + GetPreferredCastMode(cast_modes)); + } web_ui()->CallJavascriptFunction(kSetInitialData, initial_data); media_router_ui_->UIInitialized(); @@ -297,6 +296,11 @@ return; } + if (!IsValidCastModeNum(cast_mode_num)) { + DVLOG(1) << "Invalid cast mode: " << cast_mode_num << ". Aborting."; + return; + } + MediaRouterUI* media_router_ui = static_cast<MediaRouterUI*>(web_ui()->GetController()); if (media_router_ui->HasPendingRouteRequest()) { @@ -310,22 +314,15 @@ return; } - DVLOG(2) << "sink id: " << sink_id << ", cast mode: " << cast_mode_num; + DVLOG(2) << __FUNCTION__ << ": sink id: " << sink_id + << ", cast mode: " << cast_mode_num; // TODO(haibinlu): Pass additional parameters into the CreateRoute request, // e.g. low-fps-mirror, user-override. (crbug.com/490364) - bool success = false; - if (IsValidCastModeNum(cast_mode_num)) { - // User explicitly selected cast mode. - DVLOG(2) << "Cast mode override: " << cast_mode_num; - success = media_router_ui->CreateRouteWithCastModeOverride( - sink_id, static_cast<MediaCastMode>(cast_mode_num)); - } else { - success = media_router_ui->CreateRoute(sink_id); - } - - if (!success) { - // The provider will handle sending an issue for a failed route request. + if (!media_router_ui->CreateRoute( + sink_id, static_cast<MediaCastMode>(cast_mode_num))) { + // TODO(imcheng): Need to add an issue if failed to initiate a CreateRoute + // request. DVLOG(1) << "Error initiating route request."; } }
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 ecc1cf6..0eb06442 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
@@ -12,6 +12,8 @@ #include "chrome/grit/generated_resources.h" #include "chrome/grit/google_chrome_strings.h" #include "chrome/grit/locale_settings.h" +#include "chrome/grit/settings_chromium_strings.h" +#include "chrome/grit/settings_google_chrome_strings.h" #include "chrome/grit/settings_strings.h" #include "content/public/browser/web_ui_data_source.h" #include "grit/components_strings.h" @@ -190,6 +192,23 @@ IDS_SETTINGS_CLEAR_DATA_EVERYTHING); } +#if !defined(OS_CHROMEOS) +void AddDefaultBrowserStrings(content::WebUIDataSource* html_source) { + html_source->AddLocalizedString( + "defaultBrowser", IDS_SETTINGS_DEFAULT_BROWSER); + html_source->AddLocalizedString( + "defaultBroswerDefault", IDS_SETTINGS_DEFAULT_BROWSER_DEFAULT); + html_source->AddLocalizedString( + "defaultBroswerNotDefault", IDS_SETTINGS_DEFAULT_BROWSER_NOT_DEFAULT); + html_source->AddLocalizedString( + "defaultBroswerMakeDefault", IDS_SETTINGS_DEFAULT_BROWSER_MAKE_DEFAULT); + html_source->AddLocalizedString( + "defaultBroswerUnknown", IDS_SETTINGS_DEFAULT_BROWSER_UNKNOWN); + html_source->AddLocalizedString( + "defaultBroswerSecondary", IDS_SETTINGS_DEFAULT_BROWSER_SECONDARY); +} +#endif + void AddDownloadsStrings(content::WebUIDataSource* html_source) { html_source->AddLocalizedString( "downloadsPageTitle", IDS_SETTINGS_DOWNLOADS); @@ -547,6 +566,9 @@ AddAppearanceStrings(html_source); AddCertificateManagerStrings(html_source); AddClearBrowsingDataStrings(html_source); +#if !defined(OS_CHROMEOS) + AddDefaultBrowserStrings(html_source); +#endif AddDateTimeStrings(html_source); AddDownloadsStrings(html_source); #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc index 3f01c4b..cfacee5 100644 --- a/chrome/browser/ui/webui/settings/md_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc
@@ -7,11 +7,13 @@ #include <string> #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/options/sync_setup_handler.h" #include "chrome/browser/ui/webui/settings/appearance_handler.h" #include "chrome/browser/ui/webui/settings/downloads_handler.h" #include "chrome/browser/ui/webui/settings/languages_handler.h" #include "chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.h" #include "chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h" +#include "chrome/browser/ui/webui/settings/settings_default_browser_handler.h" #include "chrome/browser/ui/webui/settings/settings_startup_pages_handler.h" #include "chrome/common/url_constants.h" #include "content/public/browser/web_contents.h" @@ -32,9 +34,11 @@ : content::WebUIController(web_ui) { AddSettingsPageUIHandler(new AppearanceHandler(web_ui)); AddSettingsPageUIHandler(new ClearBrowsingDataHandler(web_ui)); + AddSettingsPageUIHandler(new DefaultBrowserHandler(web_ui)); AddSettingsPageUIHandler(new DownloadsHandler()); AddSettingsPageUIHandler(new LanguagesHandler(web_ui)); AddSettingsPageUIHandler(new StartupPagesHandler(web_ui)); + AddSettingsPageUIHandler(new SyncSetupHandler()); content::WebUIDataSource* html_source = content::WebUIDataSource::Create(chrome::kChromeUIMdSettingsHost); @@ -56,8 +60,8 @@ } void MdSettingsUI::AddSettingsPageUIHandler( - settings::SettingsPageUIHandler* handler_raw) { - scoped_ptr<settings::SettingsPageUIHandler> handler(handler_raw); + content::WebUIMessageHandler* handler_raw) { + scoped_ptr<content::WebUIMessageHandler> handler(handler_raw); DCHECK(handler.get()); web_ui()->AddMessageHandler(handler.release());
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.h b/chrome/browser/ui/webui/settings/md_settings_ui.h index cfab2b4b..5623dc3 100644 --- a/chrome/browser/ui/webui/settings/md_settings_ui.h +++ b/chrome/browser/ui/webui/settings/md_settings_ui.h
@@ -35,8 +35,7 @@ ~MdSettingsUI() override; private: - // Adds SettingsPageUiHandler to the handlers list if handler is enabled. - void AddSettingsPageUIHandler(SettingsPageUIHandler* handler); + void AddSettingsPageUIHandler(content::WebUIMessageHandler* handler); DISALLOW_COPY_AND_ASSIGN(MdSettingsUI); };
diff --git a/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc b/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc new file mode 100644 index 0000000..75fc76f --- /dev/null +++ b/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc
@@ -0,0 +1,88 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/settings/settings_default_browser_handler.h" + +#include "base/bind.h" +#include "base/prefs/pref_service.h" +#include "chrome/browser/browser_process.h" +#include "chrome/common/pref_names.h" +#include "content/public/browser/web_ui.h" + +namespace settings { + +DefaultBrowserHandler::DefaultBrowserHandler(content::WebUI* webui) + : default_browser_worker_( + new ShellIntegration::DefaultBrowserWorker(this)) { + default_browser_policy_.Init( + prefs::kDefaultBrowserSettingEnabled, g_browser_process->local_state(), + base::Bind(&DefaultBrowserHandler::RequestDefaultBrowserState, + base::Unretained(this), nullptr)); +} + +DefaultBrowserHandler::~DefaultBrowserHandler() { + default_browser_worker_->ObserverDestroyed(); +} + +void DefaultBrowserHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "SettingsDefaultBrowser.requestDefaultBrowserState", + base::Bind(&DefaultBrowserHandler::RequestDefaultBrowserState, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "SettingsDefaultBrowser.setAsDefaultBrowser", + base::Bind(&DefaultBrowserHandler::SetAsDefaultBrowser, + base::Unretained(this))); +} + +void DefaultBrowserHandler::SetDefaultWebClientUIState( + ShellIntegration::DefaultWebClientUIState state) { + if (state == ShellIntegration::STATE_PROCESSING) + return; + + if (state == ShellIntegration::STATE_IS_DEFAULT) { + // Notify the user in the future if Chrome ceases to be the user's chosen + // default browser. + Profile::FromWebUI(web_ui())->GetPrefs()->SetBoolean( + prefs::kCheckDefaultBrowser, true); + } + + base::FundamentalValue is_default( + state == ShellIntegration::STATE_IS_DEFAULT); + base::FundamentalValue can_be_default( + state != ShellIntegration::STATE_UNKNOWN && + !default_browser_policy_.IsManaged() && + ShellIntegration::CanSetAsDefaultBrowser() != + ShellIntegration::SET_DEFAULT_NOT_ALLOWED); + + web_ui()->CallJavascriptFunction("Settings.updateDefaultBrowserState", + is_default, can_be_default); +} + +bool DefaultBrowserHandler::IsInteractiveSetDefaultPermitted() { + return true; +} + +void DefaultBrowserHandler::OnSetAsDefaultConcluded(bool succeeded) { + base::FundamentalValue success(succeeded); + web_ui()->CallJavascriptFunction("Settings.setAsDefaultConcluded", success); +} + +void DefaultBrowserHandler::RequestDefaultBrowserState( + const base::ListValue* /*args*/) { + default_browser_worker_->StartCheckIsDefault(); +} + +void DefaultBrowserHandler::SetAsDefaultBrowser(const base::ListValue* args) { + CHECK(!default_browser_policy_.IsManaged()); + + default_browser_worker_->StartSetAsDefault(); + + // If the user attempted to make Chrome the default browser, notify + // them when this changes. + Profile::FromWebUI(web_ui())->GetPrefs()->SetBoolean( + prefs::kCheckDefaultBrowser, true); +} + +} // namespace settings
diff --git a/chrome/browser/ui/webui/settings/settings_default_browser_handler.h b/chrome/browser/ui/webui/settings/settings_default_browser_handler.h new file mode 100644 index 0000000..fad3006 --- /dev/null +++ b/chrome/browser/ui/webui/settings/settings_default_browser_handler.h
@@ -0,0 +1,61 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_SETTINGS_DEFAULT_BROWSER_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_SETTINGS_DEFAULT_BROWSER_HANDLER_H_ + +#include "base/macros.h" +#include "base/prefs/pref_member.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/shell_integration.h" +#include "chrome/browser/ui/webui/settings/md_settings_ui.h" + +namespace base { +class ListValue; +} + +namespace content { +class WebUI; +} + +namespace settings { + +// The application used by the OS to open web documents (e.g. *.html) +// is the "default browser". This class is an API for the JavaScript +// settings code to change the default browser settings. +class DefaultBrowserHandler + : public SettingsPageUIHandler, + public ShellIntegration::DefaultWebClientObserver { + public: + explicit DefaultBrowserHandler(content::WebUI* webui); + ~DefaultBrowserHandler() override; + + // SettingsPageUIHandler implementation. + void RegisterMessages() override; + + // ShellIntegration::DefaultWebClientObserver implementation. + void SetDefaultWebClientUIState( + ShellIntegration::DefaultWebClientUIState state) override; + bool IsInteractiveSetDefaultPermitted() override; + void OnSetAsDefaultConcluded(bool succeeded) override; + + private: + // Called from WebUI to request the current state. + void RequestDefaultBrowserState(const base::ListValue* args); + + // Makes this the default browser. Called from WebUI. + void SetAsDefaultBrowser(const base::ListValue* args); + + // Reference to a background worker that handles default browser settings. + scoped_refptr<ShellIntegration::DefaultBrowserWorker> default_browser_worker_; + + // Policy setting to determine if default browser setting is managed. + BooleanPrefMember default_browser_policy_; + + DISALLOW_COPY_AND_ASSIGN(DefaultBrowserHandler); +}; + +} // namespace settings + +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_SETTINGS_DEFAULT_BROWSER_HANDLER_H_
diff --git a/chrome/browser/ui/window_sizer/window_sizer_mac.mm b/chrome/browser/ui/window_sizer/window_sizer_mac.mm index b73c2db..64d049f 100644 --- a/chrome/browser/ui/window_sizer/window_sizer_mac.mm +++ b/chrome/browser/ui/window_sizer/window_sizer_mac.mm
@@ -19,7 +19,7 @@ gfx::Point WindowSizer::GetDefaultPopupOrigin(const gfx::Size& size, chrome::HostDesktopType type) { NSRect work_area = [[NSScreen mainScreen] visibleFrame]; - NSRect main_area = [[[NSScreen screens] objectAtIndex:0] frame]; + NSRect main_area = [[[NSScreen screens] firstObject] frame]; NSPoint corner = NSMakePoint(NSMinX(work_area), NSMaxY(work_area)); if (Browser* browser = chrome::FindLastActiveWithHostDesktopType(type)) {
diff --git a/chrome/chrome_android_paks.gypi b/chrome/chrome_android_paks.gypi index d3a105c..1ebd363 100644 --- a/chrome/chrome_android_paks.gypi +++ b/chrome/chrome_android_paks.gypi
@@ -87,14 +87,14 @@ '<(DEPTH)/chrome/chrome_resources.gyp:packed_resources', '<(DEPTH)/chrome/chrome_resources.gyp:packed_extra_resources', ], - 'copies': [ - { - 'destination': '<(chrome_android_pak_output_folder)', - 'files': [ - '<@(chrome_android_pak_input_resources)', - ], - } - ], + 'variables': { + 'dest_path': '<(chrome_android_pak_output_folder)', + 'src_files': [ + '<@(chrome_android_pak_input_resources)', + ], + 'clear': 1, + }, + 'includes': ['../build/android/copy_ex.gypi'], }, ], }
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 471be68..c16a2917 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi
@@ -30,6 +30,7 @@ 'browser/android/accessibility_util.h', 'browser/android/activity_type_ids.cc', 'browser/android/activity_type_ids.h', + 'browser/android/android_theme_resources.h', 'browser/android/appmenu/app_menu_drag_helper.cc', 'browser/android/appmenu/app_menu_drag_helper.h', 'browser/android/banners/app_banner_data_fetcher_android.cc',
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 0f46be5..ce1ee3ab0 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi
@@ -1935,6 +1935,8 @@ 'browser/ui/webui/settings/md_settings_ui.h', 'browser/ui/webui/settings/settings_clear_browsing_data_handler.cc', 'browser/ui/webui/settings/settings_clear_browsing_data_handler.h', + 'browser/ui/webui/settings/settings_default_browser_handler.cc', + 'browser/ui/webui/settings/settings_default_browser_handler.h', 'browser/ui/webui/settings/settings_startup_pages_handler.cc', 'browser/ui/webui/settings/settings_startup_pages_handler.h', 'browser/ui/webui/signin/inline_login_handler.cc',
diff --git a/chrome/chrome_repack_resources.gypi b/chrome/chrome_repack_resources.gypi index cea4203..8b5b3df 100644 --- a/chrome/chrome_repack_resources.gypi +++ b/chrome/chrome_repack_resources.gypi
@@ -21,6 +21,15 @@ ], 'pak_output': '<(SHARED_INTERMEDIATE_DIR)/repack/resources.pak', 'conditions': [ + ['branding=="Chrome"', { + 'pak_inputs': [ + '<(grit_out_dir)/settings_google_chrome_strings.pak', + ], + }, { + 'pak_inputs': [ + '<(grit_out_dir)/settings_chromium_strings.pak', + ], + }], ['chromeos==1', { 'pak_inputs': [ '<(SHARED_INTERMEDIATE_DIR)/ui/file_manager/file_manager_resources.pak',
diff --git a/chrome/chrome_resources.gyp b/chrome/chrome_resources.gyp index 041e51d..492536ca 100644 --- a/chrome/chrome_resources.gyp +++ b/chrome/chrome_resources.gyp
@@ -278,6 +278,22 @@ }, 'includes': [ '../build/grit_action.gypi' ], }, + { + # GN version: //chrome/app:settings_chromium_strings + 'action_name': 'generate_settings_chromium_strings', + 'variables': { + 'grit_grd_file': 'app/settings_chromium_strings.grd', + }, + 'includes': [ '../build/grit_action.gypi' ], + }, + { + # GN version: //chrome/app:settings_google_chrome_strings + 'action_name': 'generate_settings_google_chrome_strings', + 'variables': { + 'grit_grd_file': 'app/settings_google_chrome_strings.grd', + }, + 'includes': [ '../build/grit_action.gypi' ], + }, ], }, {
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 3a27481..672373dc 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi
@@ -328,7 +328,7 @@ 'browser/media/chrome_webrtc_webcam_browsertest.cc', 'browser/media/defer_background_media_browsertest.cc', 'browser/media/encrypted_media_browsertest.cc', - 'browser/media/encrypted_media_istypesupported_browsertest.cc', + 'browser/media/encrypted_media_supported_types_browsertest.cc', 'browser/media/media_browsertest.cc', 'browser/media/media_browsertest.h', 'browser/media/media_stream_devices_controller_browsertest.cc',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 27fec64..59b77d7 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi
@@ -194,8 +194,6 @@ 'browser/profiles/profile_shortcut_manager_unittest_win.cc', 'browser/push_messaging/push_messaging_app_identifier_unittest.cc', 'browser/push_messaging/push_messaging_permission_context_unittest.cc', - 'browser/renderer_context_menu/render_view_context_menu_test_util.cc', - 'browser/renderer_context_menu/render_view_context_menu_test_util.h', 'browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_unit_test.mm', 'browser/resources_util_unittest.cc', 'browser/search/contextual_search_policy_handler_android_unittest.cc', @@ -554,6 +552,8 @@ 'browser/permissions/permission_queue_controller_unittest.cc', ], 'chrome_unit_tests_non_mobile_sources': [ + 'browser/renderer_context_menu/render_view_context_menu_test_util.cc', + 'browser/renderer_context_menu/render_view_context_menu_test_util.h', 'browser/ui/website_settings/mock_permission_bubble_view.cc', 'browser/ui/website_settings/mock_permission_bubble_view.h', ], @@ -1898,7 +1898,16 @@ ] }], ['OS=="android"', { + 'dependencies!': [ + '../ui/message_center/message_center.gyp:message_center_test_support', + ], 'sources!': [ + 'browser/download/test_download_shelf.cc', + 'browser/download/test_download_shelf.h', + 'browser/profile_resetter/profile_resetter_test_base.cc', + 'browser/profile_resetter/profile_resetter_test_base.h', + 'browser/sessions/session_restore_test_helper.cc', + 'browser/sessions/session_restore_test_helper.h', 'browser/sessions/session_service_test_helper.cc', 'browser/sessions/session_service_test_helper.h', 'browser/ui/exclusive_access/fullscreen_controller_state_test.cc', @@ -1906,6 +1915,10 @@ 'browser/ui/exclusive_access/fullscreen_controller_state_tests.h', 'browser/ui/exclusive_access/fullscreen_controller_test.cc', 'browser/ui/exclusive_access/fullscreen_controller_test.h', + 'browser/ui/test/test_confirm_bubble_model.cc', + 'browser/ui/test/test_confirm_bubble_model.h', + 'renderer/safe_browsing/mock_feature_extractor_clock.cc', + 'renderer/safe_browsing/mock_feature_extractor_clock.h', 'test/base/dialog_test_browser_window.cc', 'test/base/dialog_test_browser_window.h', 'test/base/test_browser_window.cc', @@ -2916,15 +2929,15 @@ 'dependencies': [ '../v8/tools/gyp/v8.gyp:v8_external_snapshot', ], - 'copies': [ - { - 'destination': '<(asset_location)', - 'files': [ - '<(PRODUCT_DIR)/natives_blob.bin', - '<(PRODUCT_DIR)/snapshot_blob.bin', - ], - }, - ], + 'variables': { + 'dest_path': '<(asset_location)', + 'src_files': [ + '<(PRODUCT_DIR)/natives_blob.bin', + '<(PRODUCT_DIR)/snapshot_blob.bin', + ], + 'clear': 1, + }, + 'includes': ['../build/android/copy_ex.gypi'], }], ], 'includes': [ '../build/apk_test.gypi' ],
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index f44c566..f66b3d3f 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -2,18 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Defines all the command-line switches used by Chrome. +// Defines the shared command-line switches used by code in the Chrome +// directory that don't have anywhere more specific to go. #ifndef CHROME_COMMON_CHROME_SWITCHES_H_ #define CHROME_COMMON_CHROME_SWITCHES_H_ #include "build/build_config.h" -#include "base/base_switches.h" -#include "components/autofill/core/common/autofill_switches.h" -#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h" -#include "components/password_manager/core/common/password_manager_switches.h" -#include "components/signin/core/common/signin_switches.h" +// Don't add more switch files here. This is linked into some places like the +// installer where dependencies should be limited. Instead, have files +// directly include your switch file. +// +// TODO(brettw) delete content_switches.h include and make callers include that +// file manually if they need a content switch. #include "content/public/common/content_switches.h" namespace switches {
diff --git a/chrome/common/crash_keys.cc b/chrome/common/crash_keys.cc index d172c464..3cd3cd4 100644 --- a/chrome/common/crash_keys.cc +++ b/chrome/common/crash_keys.cc
@@ -4,6 +4,7 @@ #include "chrome/common/crash_keys.h" +#include "base/base_switches.h" #include "base/command_line.h" #include "base/format_macros.h" #include "base/logging.h"
diff --git a/chrome/common/logging_chrome.cc b/chrome/common/logging_chrome.cc index c8458ef9..0710441b 100644 --- a/chrome/common/logging_chrome.cc +++ b/chrome/common/logging_chrome.cc
@@ -31,6 +31,7 @@ #include <fstream> // NOLINT #include <string> // NOLINT +#include "base/base_switches.h" #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/debug/debugger.h"
diff --git a/chrome/common/service_process_util.cc b/chrome/common/service_process_util.cc index 9bb3464c..2974185 100644 --- a/chrome/common/service_process_util.cc +++ b/chrome/common/service_process_util.cc
@@ -6,6 +6,7 @@ #include <algorithm> +#include "base/base_switches.h" #include "base/command_line.h" #include "base/logging.h" #include "base/memory/singleton.h"
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn index 3d2c2f5..dc76f432 100644 --- a/chrome/renderer/BUILD.gn +++ b/chrome/renderer/BUILD.gn
@@ -215,4 +215,11 @@ "media/mock_webrtc_logging_message_filter.h", ] } + + if (is_android) { + sources -= [ + "safe_browsing/mock_feature_extractor_clock.cc", + "safe_browsing/mock_feature_extractor_clock.h", + ] + } }
diff --git a/chrome/service/service_process.cc b/chrome/service/service_process.cc index 6b126c5a6..0725a54 100644 --- a/chrome/service/service_process.cc +++ b/chrome/service/service_process.cc
@@ -6,6 +6,7 @@ #include <algorithm> +#include "base/base_switches.h" #include "base/basictypes.h" #include "base/callback.h" #include "base/command_line.h"
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 3e159608..9d36c566 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -161,6 +161,7 @@ } if (is_android) { + deps -= [ "//ui/message_center:test_support" ] sources -= [ "base/dialog_test_browser_window.cc", "base/dialog_test_browser_window.h",
diff --git a/chrome/test/chromedriver/capabilities_unittest.cc b/chrome/test/chromedriver/capabilities_unittest.cc index 9b8a4e0ef8..a1a3e7f 100644 --- a/chrome/test/chromedriver/capabilities_unittest.cc +++ b/chrome/test/chromedriver/capabilities_unittest.cc
@@ -510,9 +510,9 @@ ASSERT_EQ(1u, capabilities.switches.GetSize()); ASSERT_TRUE(capabilities.switches.HasSwitch("user-agent")); ASSERT_EQ( - "Mozilla/5.0 (Linux; Android 4.4.4; en-us; Nexus 5 Build/JOP40D) " - "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2307.2 " - "Mobile Safari/537.36", + "Mozilla/5.0 (Linux; Android 4.4.4; Nexus 5 Build/KTU84P) " + "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.114 Mobile " + "Safari/537.36", capabilities.switches.GetSwitchValue("user-agent")); ASSERT_EQ(360, capabilities.device_metrics->width);
diff --git a/chrome/test/chromedriver/chrome/mobile_device.cc b/chrome/test/chromedriver/chrome/mobile_device.cc index 26a8e75..faad5518 100644 --- a/chrome/test/chromedriver/chrome/mobile_device.cc +++ b/chrome/test/chromedriver/chrome/mobile_device.cc
@@ -23,66 +23,49 @@ "could not parse mobile device list because " + json_reader.GetErrorMessage()); - base::ListValue* mobile_devices; - if (!devices_value->GetAsList(&mobile_devices)) - return Status(kUnknownError, "malformed device metrics list"); + base::DictionaryValue* mobile_devices; + if (!devices_value->GetAsDictionary(&mobile_devices)) + return Status(kUnknownError, "malformed device metrics dictionary"); - for (base::ListValue::iterator it = mobile_devices->begin(); - it != mobile_devices->end(); - ++it) { - base::DictionaryValue* device = NULL; - if (!(*it)->GetAsDictionary(&device)) { - return Status(kUnknownError, - "malformed device in list: should be a dictionary"); - } + base::DictionaryValue* device = NULL; + if (!mobile_devices->GetDictionary(device_name, &device)) + return Status(kUnknownError, "must be a valid device"); - if (device != NULL) { - std::string name; - if (!device->GetString("title", &name)) { - return Status(kUnknownError, - "malformed device name: should be a string"); - } - if (name != device_name) - continue; - - scoped_ptr<MobileDevice> tmp_mobile_device(new MobileDevice()); - std::string device_metrics_string; - if (!device->GetString("userAgent", &tmp_mobile_device->user_agent)) { - return Status(kUnknownError, - "malformed device user agent: should be a string"); - } - int width = 0; - int height = 0; - double device_scale_factor = 0.0; - bool touch = true; - bool mobile = true; - if (!device->GetInteger("width", &width)) { - return Status(kUnknownError, - "malformed device width: should be an integer"); - } - if (!device->GetInteger("height", &height)) { - return Status(kUnknownError, - "malformed device height: should be an integer"); - } - if (!device->GetDouble("deviceScaleFactor", &device_scale_factor)) { - return Status(kUnknownError, - "malformed device scale factor: should be a double"); - } - if (!device->GetBoolean("touch", &touch)) { - return Status(kUnknownError, - "malformed touch: should be a bool"); - } - if (!device->GetBoolean("mobile", &mobile)) { - return Status(kUnknownError, - "malformed mobile: should be a bool"); - } - tmp_mobile_device->device_metrics.reset( - new DeviceMetrics(width, height, device_scale_factor, touch, mobile)); - - *mobile_device = tmp_mobile_device.Pass(); - return Status(kOk); - } + scoped_ptr<MobileDevice> tmp_mobile_device(new MobileDevice()); + std::string device_metrics_string; + if (!device->GetString("userAgent", &tmp_mobile_device->user_agent)) { + return Status(kUnknownError, + "malformed device user agent: should be a string"); } + int width = 0; + int height = 0; + double device_scale_factor = 0.0; + bool touch = true; + bool mobile = true; + if (!device->GetInteger("width", &width)) { + return Status(kUnknownError, + "malformed device width: should be an integer"); + } + if (!device->GetInteger("height", &height)) { + return Status(kUnknownError, + "malformed device height: should be an integer"); + } + if (!device->GetDouble("deviceScaleFactor", &device_scale_factor)) { + return Status(kUnknownError, + "malformed device scale factor: should be a double"); + } + if (!device->GetBoolean("touch", &touch)) { + return Status(kUnknownError, + "malformed touch: should be a bool"); + } + if (!device->GetBoolean("mobile", &mobile)) { + return Status(kUnknownError, + "malformed mobile: should be a bool"); + } + tmp_mobile_device->device_metrics.reset( + new DeviceMetrics(width, height, device_scale_factor, touch, mobile)); - return Status(kUnknownError, "must be a valid device"); + *mobile_device = tmp_mobile_device.Pass(); + return Status(kOk); + }
diff --git a/chrome/test/chromedriver/chrome/mobile_device_list.cc b/chrome/test/chromedriver/chrome/mobile_device_list.cc index aa4704b..13cd982 100644 --- a/chrome/test/chromedriver/chrome/mobile_device_list.cc +++ b/chrome/test/chromedriver/chrome/mobile_device_list.cc
@@ -2,101 +2,102 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file was generated at (2015-03-30 16:08:35.102812) by running: +// This file was generated at (2015-10-05 13:42:15.387188) by running: // chrome/test/chromedriver/embed_mobile_devices_in_cpp.py --directory // chrome/test/chromedriver/chrome/ -// third_party/WebKit/Source/devtools/front_end/toolbox/OverridesUI.js +// third_party/WebKit/Source/devtools/front_end/emulated_devices/module.json #include "chrome/test/chromedriver/chrome/mobile_device_list.h" const char kMobileDevices[] = - "[{\"title\": \"Apple iPhone 4\", \"width\": 320, \"height\": 480, " - "\"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 (iPhone; U; CPU " - "iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like " - "Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5\", \"touch\": true, " - "\"mobile\": true},{\"title\": \"Apple iPhone 5\", \"width\": 320, " - "\"height\": 568, \"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 " - "(iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 " - "(KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53\", " - "\"touch\": true, \"mobile\": true},{\"title\": \"Apple iPhone 6\", " - "\"width\": 375, \"height\": 667, \"deviceScaleFactor\": 2, \"userAgent\": " - "\"Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) " - "AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d " - "Safari/600.1.4\", \"touch\": true, \"mobile\": true},{\"title\": \"Apple " - "iPhone 6 Plus\", \"width\": 414, \"height\": 736, \"deviceScaleFactor\": " - "3, \"userAgent\": \"Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) " - "AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d " - "Safari/600.1.4\", \"touch\": true, \"mobile\": true},{\"title\": " - "\"BlackBerry Z30\", \"width\": 360, \"height\": 640, " - "\"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 (BB10; Touch) " - "AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile " - "Safari/537.10+\", \"touch\": true, \"mobile\": true},{\"title\": \"Google " - "Nexus 4\", \"width\": 384, \"height\": 640, \"deviceScaleFactor\": 2, " - "\"userAgent\": \"Mozilla/5.0 (Linux; Android 4.4.4; en-us; Nexus 4 " - "Build/JOP40D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2307.2 " - "Mobile Safari/537.36\", \"touch\": true, \"mobile\": true},{\"title\": " - "\"Google Nexus 5\", \"width\": 360, \"height\": 640, " - "\"deviceScaleFactor\": 3, \"userAgent\": \"Mozilla/5.0 (Linux; Android " - "4.4.4; en-us; Nexus 5 Build/JOP40D) AppleWebKit/537.36 (KHTML, like " - "Gecko) Chrome/42.0.2307.2 Mobile Safari/537.36\", \"touch\": true, " - "\"mobile\": true},{\"title\": \"LG Optimus L70\", \"width\": 384, " - "\"height\": 640, \"deviceScaleFactor\": 1.25, \"userAgent\": " - "\"Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 " - "Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 " - "Chrome/30.0.1599.103 Mobile Safari/537.36\", \"touch\": true, \"mobile\": " - "true},{\"title\": \"Nokia N9\", \"width\": 360, \"height\": 640, " - "\"deviceScaleFactor\": 1, \"userAgent\": \"Mozilla/5.0 (MeeGo; NokiaN9) " + "{\"Laptop with touch\": {\"deviceScaleFactor\": 1, \"mobile\": false, " + "\"height\": 1280, \"width\": 950, \"touch\": true, \"userAgent\": \"\"}, " + "\"BlackBerry Z30\": {\"deviceScaleFactor\": 2, \"mobile\": true, " + "\"height\": 640, \"width\": 360, \"touch\": true, \"userAgent\": " + "\"Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) " + "Version/10.0.9.2372 Mobile Safari/537.10+\"}, \"Google Nexus 6\": " + "{\"deviceScaleFactor\": 3.5, \"mobile\": true, \"height\": 732, " + "\"width\": 412, \"touch\": true, \"userAgent\": \"Mozilla/5.0 (Linux; " + "Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like " + "Gecko) Chrome/44.0.2403.20 Mobile Safari/537.36\"}, \"Google Nexus 7\": " + "{\"deviceScaleFactor\": 2, \"mobile\": true, \"height\": 960, \"width\": " + "600, \"touch\": true, \"userAgent\": \"Mozilla/5.0 (Linux; Android 4.3; " + "Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/42.0.2307.2 Safari/537.36\"}, \"Google Nexus 4\": " + "{\"deviceScaleFactor\": 2, \"mobile\": true, \"height\": 640, \"width\": " + "384, \"touch\": true, \"userAgent\": \"Mozilla/5.0 (Linux; Android 4.4.2; " + "Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/35.0.1916.122 Mobile Safari/537.36\"}, \"Google Nexus 5\": " + "{\"deviceScaleFactor\": 3, \"mobile\": true, \"height\": 640, \"width\": " + "360, \"touch\": true, \"userAgent\": \"Mozilla/5.0 (Linux; Android 4.4.4; " + "Nexus 5 Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/38.0.2125.114 Mobile Safari/537.36\"}, \"Apple iPad\": " + "{\"deviceScaleFactor\": 2, \"mobile\": true, \"height\": 1024, \"width\": " + "768, \"touch\": true, \"userAgent\": \"Mozilla/5.0 (iPad; CPU OS 7_0 like " + "Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 " + "Mobile/11A465 Safari/9537.53\"}, \"Laptop with HiDPI screen\": " + "{\"deviceScaleFactor\": 2, \"mobile\": false, \"height\": 1440, " + "\"width\": 900, \"touch\": false, \"userAgent\": \"\"}, \"Samsung Galaxy " + "Note II\": {\"deviceScaleFactor\": 2, \"mobile\": true, \"height\": 640, " + "\"width\": 360, \"touch\": true, \"userAgent\": \"Mozilla/5.0 (Linux; U; " + "Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, " + "like Gecko) Version/4.0 Mobile Safari/534.30\"}, \"Nokia N9\": " + "{\"deviceScaleFactor\": 1, \"mobile\": true, \"height\": 640, \"width\": " + "360, \"touch\": true, \"userAgent\": \"Mozilla/5.0 (MeeGo; NokiaN9) " "AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile " - "Safari/534.13\", \"touch\": true, \"mobile\": true},{\"title\": \"Nokia " - "Lumia 520\", \"width\": 320, \"height\": 533, \"deviceScaleFactor\": 1.4, " + "Safari/534.13\"}, \"Samsung Galaxy S4\": {\"deviceScaleFactor\": 3, " + "\"mobile\": true, \"height\": 640, \"width\": 360, \"touch\": true, " + "\"userAgent\": \"Mozilla/5.0 (Linux; Android 4.2.2; GT-I9505 Build/JDQ39) " + "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.59 Mobile " + "Safari/537.36\"}, \"Nokia Lumia 520\": {\"deviceScaleFactor\": 1.4, " + "\"mobile\": true, \"height\": 533, \"width\": 320, \"touch\": true, " "\"userAgent\": \"Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; " - "Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)\", \"touch\": " - "true, \"mobile\": true},{\"title\": \"Samsung Galaxy S III\", \"width\": " - "360, \"height\": 640, \"deviceScaleFactor\": 2, \"userAgent\": " - "\"Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) " - "AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile " - "Safari/534.30\", \"touch\": true, \"mobile\": true},{\"title\": \"Samsung " - "Galaxy S4\", \"width\": 360, \"height\": 640, \"deviceScaleFactor\": 3, " - "\"userAgent\": \"Mozilla/5.0 (Linux; Android 4.4.2; GT-I9505 Build/JDQ39) " - "AppleWebKit/537.36 (KHTML, like Gecko) Version/1.5 Chrome/28.0.1500.94 " - "Mobile Safari/537.36\", \"touch\": true, \"mobile\": true},{\"title\": " - "\"Amazon Kindle Fire HDX\", \"width\": 2560, \"height\": 1600, " - "\"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 (Linux; U; en-us; " - "KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 " - "Safari/535.19 Silk-Accelerated=true\", \"touch\": true, \"mobile\": " - "true},{\"title\": \"Apple iPad Mini\", \"width\": 1024, \"height\": 768, " - "\"deviceScaleFactor\": 1, \"userAgent\": \"Mozilla/5.0 (iPad; CPU OS " - "4_3_5 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) " - "Version/5.0.2 Mobile/8L1 Safari/6533.18.5\", \"touch\": true, \"mobile\": " - "true},{\"title\": \"Apple iPad\", \"width\": 1024, \"height\": 768, " - "\"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 (iPad; CPU OS 7_0 " - "like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 " - "Mobile/11A465 Safari/9537.53\", \"touch\": true, \"mobile\": " - "true},{\"title\": \"BlackBerry PlayBook\", \"width\": 1024, \"height\": " - "600, \"deviceScaleFactor\": 1, \"userAgent\": \"Mozilla/5.0 (PlayBook; U; " - "RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) " - "Version/7.2.1.0 Safari/536.2+\", \"touch\": true, \"mobile\": " - "true},{\"title\": \"Google Nexus 10\", \"width\": 1280, \"height\": 800, " - "\"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 (Linux; Android " - "4.3; Nexus 10 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) " - "Chrome/42.0.2307.2 Mobile Safari/537.36\", \"touch\": true, \"mobile\": " - "true},{\"title\": \"Google Nexus 7\", \"width\": 960, \"height\": 600, " - "\"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 (Linux; Android " - "4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) " - "Chrome/42.0.2307.2 Mobile Safari/537.36\", \"touch\": true, \"mobile\": " - "true},{\"title\": \"Samsung Galaxy Note 3\", \"width\": 360, \"height\": " - "640, \"deviceScaleFactor\": 3, \"userAgent\": \"Mozilla/5.0 (Linux; U; " + "Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)\"}, " + "\"BlackBerry PlayBook\": {\"deviceScaleFactor\": 1, \"mobile\": true, " + "\"height\": 1024, \"width\": 600, \"touch\": true, \"userAgent\": " + "\"Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) " + "AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+\"}, " + "\"Apple iPhone 5\": {\"deviceScaleFactor\": 2, \"mobile\": true, " + "\"height\": 568, \"width\": 320, \"touch\": true, \"userAgent\": " + "\"Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) " + "AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 " + "Safari/9537.53\"}, \"Apple iPhone 4\": {\"deviceScaleFactor\": 2, " + "\"mobile\": true, \"height\": 480, \"width\": 320, \"touch\": true, " + "\"userAgent\": \"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS " + "X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 " + "Mobile/8C148 Safari/6533.18.5\"}, \"Apple iPhone 6\": " + "{\"deviceScaleFactor\": 2, \"mobile\": true, \"height\": 667, \"width\": " + "375, \"touch\": true, \"userAgent\": \"Mozilla/5.0 (iPhone; CPU iPhone OS " + "8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 " + "Mobile/12A4345d Safari/600.1.4\"}, \"LG Optimus L70\": " + "{\"deviceScaleFactor\": 1.25, \"mobile\": true, \"height\": 640, " + "\"width\": 384, \"touch\": true, \"userAgent\": \"Mozilla/5.0 (Linux; U; " + "Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 " + "(KHTML, like Gecko) Version/4.0 Chrome/30.0.1599.103 Mobile " + "Safari/537.36\"}, \"Apple iPhone 6 Plus\": {\"deviceScaleFactor\": 3, " + "\"mobile\": true, \"height\": 736, \"width\": 414, \"touch\": true, " + "\"userAgent\": \"Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) " + "AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d " + "Safari/600.1.4\"}, \"Apple iPad Mini\": {\"deviceScaleFactor\": 2, " + "\"mobile\": true, \"height\": 1024, \"width\": 768, \"touch\": true, " + "\"userAgent\": \"Mozilla/5.0 (iPad; CPU OS 7_0_4 like Mac OS X) " + "AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B554a " + "Safari/9537.53\"}, \"Amazon Kindle Fire HDX\": {\"deviceScaleFactor\": 2, " + "\"mobile\": true, \"height\": 2560, \"width\": 1600, \"touch\": true, " + "\"userAgent\": \"Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) " + "AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 " + "Silk-Accelerated=true\"}, \"Samsung Galaxy S III\": " + "{\"deviceScaleFactor\": 2, \"mobile\": true, \"height\": 640, \"width\": " + "360, \"touch\": true, \"userAgent\": \"Mozilla/5.0 (Linux; U; Android " + "4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) " + "Version/4.0 Mobile Safari/534.30\"}, \"Laptop with MDPI screen\": " + "{\"deviceScaleFactor\": 1, \"mobile\": false, \"height\": 1280, " + "\"width\": 800, \"touch\": false, \"userAgent\": \"\"}, \"Samsung Galaxy " + "Note 3\": {\"deviceScaleFactor\": 3, \"mobile\": true, \"height\": 640, " + "\"width\": 360, \"touch\": true, \"userAgent\": \"Mozilla/5.0 (Linux; U; " "Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, " - "like Gecko) Version/4.0 Mobile Safari/534.30\", \"touch\": true, " - "\"mobile\": true},{\"title\": \"Samsung Galaxy Note II\", \"width\": 360, " - "\"height\": 640, \"deviceScaleFactor\": 2, \"userAgent\": \"Mozilla/5.0 " - "(Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 " - "(KHTML, like Gecko) Version/4.0 Mobile Safari/534.30\", \"touch\": true, " - "\"mobile\": true},{\"title\": \"Laptop with touch\", \"width\": 1280, " - "\"height\": 950, \"deviceScaleFactor\": 1, \"userAgent\": \"\", " - "\"touch\": true, \"mobile\": false},{\"title\": \"Laptop with HiDPI " - "screen\", \"width\": 1440, \"height\": 900, \"deviceScaleFactor\": 2, " - "\"userAgent\": \"\", \"touch\": false, \"mobile\": false},{\"title\": " - "\"Laptop with MDPI screen\", \"width\": 1280, \"height\": 800, " - "\"deviceScaleFactor\": 1, \"userAgent\": \"\", \"touch\": false, " - "\"mobile\": false}]"; + "like Gecko) Version/4.0 Mobile Safari/534.30\"}, \"Google Nexus 10\": " + "{\"deviceScaleFactor\": 2, \"mobile\": true, \"height\": 1280, \"width\": " + "800, \"touch\": true, \"userAgent\": \"Mozilla/5.0 (Linux; Android 4.3; " + "Nexus 10 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/42.0.2307.2 Safari/537.36\"}}";
diff --git a/chrome/test/chromedriver/chrome/mobile_device_list.h b/chrome/test/chromedriver/chrome/mobile_device_list.h index e85e3a4..d11484f 100644 --- a/chrome/test/chromedriver/chrome/mobile_device_list.h +++ b/chrome/test/chromedriver/chrome/mobile_device_list.h
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file was generated at (2015-03-30 16:08:35.102812) by running: +// This file was generated at (2015-10-05 13:42:15.387188) by running: // chrome/test/chromedriver/embed_mobile_devices_in_cpp.py --directory // chrome/test/chromedriver/chrome/ -// third_party/WebKit/Source/devtools/front_end/toolbox/OverridesUI.js +// third_party/WebKit/Source/devtools/front_end/emulated_devices/module.json #ifndef CHROME_TEST_CHROMEDRIVER_CHROME_MOBILE_DEVICE_LIST_H_ #define CHROME_TEST_CHROMEDRIVER_CHROME_MOBILE_DEVICE_LIST_H_
diff --git a/chrome/test/chromedriver/embed_mobile_devices_in_cpp.py b/chrome/test/chromedriver/embed_mobile_devices_in_cpp.py index 9fe2ad41..58665fe 100755 --- a/chrome/test/chromedriver/embed_mobile_devices_in_cpp.py +++ b/chrome/test/chromedriver/embed_mobile_devices_in_cpp.py
@@ -5,12 +5,13 @@ """Embeds standalone JavaScript snippets in C++ code. -The script requires the devtools/front_end/toolbox/OverridesUI.js file from -WebKit that lists the known mobile devices to be passed in as the only argument. -The list of known devices will be written to a C-style string to be parsed with -JSONReader. +The script requires the Source/devtools/front_end/emulated_devices/module.json +file from Blink that lists the known mobile devices to be passed in as the only +argument. The list of known devices will be written to a C-style string to be +parsed with JSONReader. """ +import json import optparse import re import subprocess @@ -19,18 +20,6 @@ import cpp_source -def quotizeKeys(s, keys): - """Returns the string |s| with each instance of each key wrapped in quotes. - - Args: - s: a string containing keys that need to be wrapped in quotes. - keys: an iterable of keys to be wrapped in quotes in the string. - """ - for key in keys: - s = re.sub('%s: ' % key, '"%s": ' % key, s) - return s - - def main(): parser = optparse.OptionParser() parser.add_option( @@ -38,34 +27,29 @@ help='Path to directory where the cc/h files should be created') options, args = parser.parse_args() - devices = '[' + devices = {} file_name = args[0] inside_list = False with open(file_name, 'r') as f: - for line in f: - if not inside_list: - if 'WebInspector.OverridesUI._phones = [' in line: - inside_list = True - if 'WebInspector.OverridesUI._tablets = [' in line: - devices += ',' - inside_list = True - if 'WebInspector.OverridesUI._notebooks = [' in line: - devices += ',' - inside_list = True - else: - if line.strip() == '];': - inside_list = False - continue - devices += line.strip() + emulated_devices = json.load(f) + extensions = emulated_devices['extensions'] + for extension in extensions: + if extension['type'] == 'emulated-device': + device = extension['device'] + devices[device['title']] = { + 'userAgent': device['user-agent'], + 'width': device['screen']['vertical']['width'], + 'height': device['screen']['vertical']['height'], + 'deviceScaleFactor': device['screen']['device-pixel-ratio'], + 'touch': 'touch' in device['capabilities'], + 'mobile': 'mobile' in device['capabilities'], + } output_dir = 'chrome/test/chromedriver/chrome' - devices += ']' - devices = quotizeKeys(devices, - ['title', 'width', 'height', 'deviceScaleFactor', - 'userAgent', 'touch', 'mobile']) cpp_source.WriteSource('mobile_device_list', output_dir, - options.directory, {'kMobileDevices': devices}) + options.directory, + {'kMobileDevices': json.dumps(devices)}) clang_format = ['clang-format', '-i'] subprocess.Popen(clang_format + ['%s/mobile_device_list.cc' % output_dir])
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index d84d3ed..fbbc3f7 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -1447,8 +1447,8 @@ self.assertEqual(640, driver.ExecuteScript('return window.screen.height')) body_tag = driver.FindElement('tag name', 'body') self.assertEqual( - 'Mozilla/5.0 (Linux; Android 4.4.4; en-us; Nexus 5 Build/JOP40D) ' - 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2307.2 Mobile ' + 'Mozilla/5.0 (Linux; Android 4.4.4; Nexus 5 Build/KTU84P) ' + 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.114 Mobile ' 'Safari/537.36', body_tag.GetText())
diff --git a/chrome/test/data/webui/media_router/media_router_container_tests.js b/chrome/test/data/webui/media_router/media_router_container_tests.js index c337d1ba..20b8a46 100644 --- a/chrome/test/data/webui/media_router/media_router_container_tests.js +++ b/chrome/test/data/webui/media_router/media_router_container_tests.js
@@ -160,6 +160,9 @@ 'issue id 2', 'Issue Title 2', 'Issue Message 2', 0, 1, 'route id 2', false, 1234); + container.initializeCastModes( + fakeCastModeList, fakeCastModeList[1].type); + // Allow for the media router container to be created and attached. setTimeout(done); }); @@ -176,21 +179,20 @@ // Tests for 'create-route' event firing when a sink with no associated // route is clicked. test('select sink without a route', function(done) { - container.sinkList = fakeSinkList; + container.allSinks = fakeSinkList; setTimeout(function() { var sinkList = container.$['sink-list'].querySelectorAll('paper-item'); - container.addEventListener('create-route', function(data) { assertEquals(fakeSinkList[2].id, data.detail.sinkId); assertEquals(container.selectedCastModeValue_, data.detail.selectedCastModeValue); done(); }); - // Tap on a sink without a route, which should fire a 'create-route' // event. + assertEquals(fakeSinkList.length, sinkList.length); MockInteractions.tap(sinkList[2]); }); }); @@ -198,7 +200,7 @@ // Tests that selecting a sink with an associated route will make the // |container| switch to ROUTE_DETAILS view. test('select sink with a route', function(done) { - container.sinkList = fakeSinkList; + container.allSinks = fakeSinkList; container.routeList = fakeRouteList; setTimeout(function() { @@ -217,7 +219,7 @@ // Tests that |container| returns to SINK_LIST view and arrow drop icon // toggles after a cast mode is selected. test('select cast mode', function(done) { - container.castModeList = fakeCastModeListWithNonDefaultModesOnly; + container.castModeList_ = fakeCastModeListWithNonDefaultModesOnly; MockInteractions.tap(container.$['arrow-drop-icon']); checkArrowDropIcon(container.CONTAINER_VIEW_.CAST_MODE_LIST); @@ -265,21 +267,16 @@ test('header text with no default cast modes', function(done) { checkElementTextWithId(loadTimeData.getString('selectCastModeHeader'), 'cast-mode-header-text'); + checkElementTextWithId(fakeCastModeList[1].description, + 'sink-list-header-text'); - var fakeHeaderText = 'fake header text'; - container.headerText = fakeHeaderText; - checkElementTextWithId(fakeHeaderText, 'sink-list-header-text'); - - // Set the cast mode list to update the header text when one is - // selected. - container.castModeList = fakeCastModeListWithNonDefaultModesOnly; - + container.castModeList_ = fakeCastModeListWithNonDefaultModesOnly; setTimeout(function() { var castModeList = container.$['cast-mode-list'].querySelectorAll('paper-item'); - - for (var i = 0; i < fakeCastModeListWithNonDefaultModesOnly.length; - i++) { + assertEquals(fakeCastModeListWithNonDefaultModesOnly.length, + castModeList.length); + for (var i = 0; i < castModeList.length; i++) { MockInteractions.tap(castModeList[i]); checkElementTextWithId( fakeCastModeListWithNonDefaultModesOnly[i].description, @@ -296,7 +293,7 @@ // Tests the header text when updated with a cast mode list with a mix of // default and non-default cast modes. test('cast modes with one default mode', function(done) { - container.castModeList = fakeCastModeList; + container.castModeList_ = fakeCastModeList; setTimeout(function() { var castModeList = @@ -323,12 +320,12 @@ // Tests that text shown for each sink matches their names. test('sink list text', function(done) { - container.sinkList = fakeSinkList; + container.allSinks = fakeSinkList; setTimeout(function() { var sinkList = container.$['sink-list'].querySelectorAll('paper-item'); - + assertEquals(fakeSinkList.length, sinkList.length); for (var i = 0; i < fakeSinkList.length; i++) { checkElementText(fakeSinkList[i].name, sinkList[i]); } @@ -338,13 +335,13 @@ // Tests the text shown for the sink list. test('initial sink list route text', function(done) { - container.sinkList = fakeSinkList; + container.allSinks = fakeSinkList; container.routeList = fakeRouteList; setTimeout(function() { var routeList = container.$['sink-list'].querySelectorAll('.route'); - + assertEquals(fakeSinkList.length, routeList.length); checkElementText(fakeRouteList[0].description, routeList[0]); checkElementText(fakeRouteList[1].description, routeList[1]); checkElementText('', routeList[2]); @@ -354,7 +351,7 @@ // Tests the visibility of routes in the sink list. test('initial route visibility', function(done) { - container.sinkList = fakeSinkList; + container.allSinks = fakeSinkList; container.routeList = fakeRouteList; setTimeout(function() { @@ -371,7 +368,7 @@ // Tests the expected view when there is only one local active route and // media_router_container is created for the first time. test('initial view with one local route', function() { - container.sinkList = fakeSinkList; + container.allSinks = fakeSinkList; container.routeList = fakeRouteList; checkCurrentView(container.CONTAINER_VIEW_.ROUTE_DETAILS); @@ -380,7 +377,7 @@ // Tests the expected view when there are multiple local active routes // and media_router_container is created for the first time. test('initial view with multiple local routes', function() { - container.sinkList = fakeSinkList; + container.allSinks = fakeSinkList; container.routeList = fakeRouteListWithLocalRoutesOnly; checkCurrentView(container.CONTAINER_VIEW_.SINK_LIST); @@ -389,7 +386,7 @@ // Tests the expected view when there are no local active routes and // media_router_container is created for the first time. test('initial view with no local route', function() { - container.sinkList = fakeSinkList; + container.allSinks = fakeSinkList; container.routeList = []; checkCurrentView(container.CONTAINER_VIEW_.SINK_LIST); @@ -398,7 +395,7 @@ // Tests the expected view when there are no local active routes and // media_router_container is created for the first time. test('view after route is closed remotely', function() { - container.sinkList = fakeSinkList; + container.allSinks = fakeSinkList; container.routeList = fakeRouteList; checkCurrentView(container.CONTAINER_VIEW_.ROUTE_DETAILS); @@ -414,7 +411,6 @@ 'container-header', 'device-missing', 'sink-list']); - // Set a non-blocking issue. The issue should stay hidden. container.issue = fakeNonBlockingIssue; checkElementsVisibleWithId(['cast-mode-header-text', @@ -464,7 +460,7 @@ 'sink-list-view']); // Set an non-empty sink list. - container.sinkList = fakeSinkList; + container.allSinks = fakeSinkList; checkElementsVisibleWithId(['container-header', 'sink-list', 'sink-list-header-text', @@ -483,6 +479,81 @@ container.issue = fakeBlockingIssue; checkElementsVisibleWithId(['issue-banner', 'sink-list']); }); + + // Tests that the sink list does not contain any sinks that are not + // compatible with the current cast mode and are not associated with a + // route. + test('sink list filtering based on initial cast mode', function(done) { + var newSinks = [ + new media_router.Sink('sink id 10', 'Sink 10', + media_router.SinkIconType.CAST, + media_router.SinkStatus.ACTIVE, [2, 3]), + new media_router.Sink('sink id 20', 'Sink 20', + media_router.SinkIconType.CAST, + media_router.SinkStatus.ACTIVE, [1, 2, 3]), + new media_router.Sink('sink id 30', 'Sink 30', + media_router.SinkIconType.CAST, + media_router.SinkStatus.PENDING, [2, 3]), + ]; + + container.allSinks = newSinks; + container.routeList = [ + new media_router.Route('id 1', 'sink id 30', 'Title 1', 1, false), + ]; + + setTimeout(function() { + var sinkList = + container.$['sink-list'].querySelectorAll('paper-item'); + + // newSinks[0] got filtered out since it is not compatible with cast + // mode 1. + // 'Sink 20' should be on the list because it contains the selected + // cast mode. (sinkList[0] = newSinks[1]) + // 'Sink 30' should be on the list because it has a route + // (sinkList[1] = newSinks[2]) + assertEquals(2, sinkList.length); + + checkElementText(newSinks[1].name, sinkList[0]); + + // |sinkList[1]| contains route title in addition to sink name. + assertTrue(sinkList[1].textContent.trim().startsWith( + newSinks[2].name.trim())); + + done(); + }); + }); + + // Tests that after a different cast mode is selected, the sink list will + // change based on the sinks compatibility with the new cast mode. + test('changing cast mode changes sink list', function(done) { + container.allSinks = fakeSinkList; + + var castModeList = + container.$['cast-mode-list'].querySelectorAll('paper-item'); + MockInteractions.tap(castModeList[0]); + checkElementTextWithId( + fakeCastModeList[0].description, 'sink-list-header-text'); + + setTimeout(function() { + var sinkList = + container.$['sink-list'].querySelectorAll('paper-item'); + + // The sink list is empty because none of the sinks in fakeSinkList + // is compatible with cast mode 0. + assertEquals(0, sinkList.length); + MockInteractions.tap(castModeList[2]); + checkElementTextWithId( + fakeCastModeList[2].description, 'sink-list-header-text'); + + setTimeout(function() { + var sinkList = + container.$['sink-list'].querySelectorAll('paper-item'); + + assertEquals(3, sinkList.length); + done(); + }); + }); + }); }); }
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index e2ac5c5..a1976a2 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -38,7 +38,7 @@ TEST_F('CrSettingsBrowserTest', 'DISABLED_CrSettingsTest', function() { // Register mocha tests for each element. settings_checkbox.registerTests(); - cr_settings_prefs.registerTests(); + settings_prefs.registerTests(); // Run all registered tests. mocha.run();
diff --git a/chrome/test/data/webui/settings/prefs_tests.js b/chrome/test/data/webui/settings/prefs_tests.js index b5a3d92..99eeaf6 100644 --- a/chrome/test/data/webui/settings/prefs_tests.js +++ b/chrome/test/data/webui/settings/prefs_tests.js
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/** @fileoverview Suite of tests for cr-settings-prefs. */ -cr.define('cr_settings_prefs', function() { +/** @fileoverview Suite of tests for settings-prefs. */ +cr.define('settings_prefs', function() { /** * Creates a deep copy of the object. * @param {!Object} obj @@ -144,7 +144,7 @@ var mockApi = null; /** - * @param {!Object} prefStore Pref store from <cr-settings-prefs>. + * @param {!Object} prefStore Pref store from <settings-prefs>. * @param {string} key Pref key of the pref to return. * @return {chrome.settingsPrivate.PrefObject|undefined} */ @@ -174,7 +174,7 @@ } /** - * Checks that the <cr-settings-prefs> contains the expected values. + * Checks that the <settings-prefs> contains the expected values. * @param {number} testCaseValueIndex The index of possible values from * the test case to check. */ @@ -194,17 +194,17 @@ */ var createdElements = []; - // Initialize <cr-settings-prefs> elements before each test. + // Initialize <settings-prefs> elements before each test. setup(function() { mockApi = new MockSettingsApi(); // TODO(michaelpg): don't use global variables to inject the API. window.mockApi = mockApi; - // Create and attach the <cr-settings-prefs> elements. Make several of + // Create and attach the <settings-prefs> elements. Make several of // them to test that the shared state model scales correctly. createdElements = []; for (var i = 0; i < 100; i++) { - var prefsInstance = document.createElement('cr-settings-prefs'); + var prefsInstance = document.createElement('settings-prefs'); document.body.appendChild(prefsInstance); createdElements.push(prefsInstance); } @@ -219,7 +219,7 @@ teardown(function() { CrSettingsPrefs.resetForTesting(); - // Reset each <cr-settings-prefs>. + // Reset each <settings-prefs>. for (var i = 0; i < createdElements.length; i++) createdElements[i].resetForTesting(); @@ -244,7 +244,7 @@ }); test('forwards pref changes to API', function() { - // Test that cr-settings-prefs uses the setPref API. + // Test that settings-prefs uses the setPref API. for (var testCase of prefsTestCases) { prefs.set('prefs.' + testCase.key + '.value', deepCopy(testCase.values[1]));
diff --git a/chrome/test/media_router/media_router_integration_ui_browsertest.cc b/chrome/test/media_router/media_router_integration_ui_browsertest.cc index d4f50ed..66025623 100644 --- a/chrome/test/media_router/media_router_integration_ui_browsertest.cc +++ b/chrome/test/media_router/media_router_integration_ui_browsertest.cc
@@ -27,7 +27,7 @@ std::string sink_length_script = base::StringPrintf( "domAutomationController.send(" "window.document.getElementById('media-router-container')." - "sinkList.length)"); + "sinksToShow_.length)"); ASSERT_EQ(2, ExecuteScriptAndExtractInt(dialog_contents, sink_length_script)); ChooseSink(web_contents, kTestSinkName);
diff --git a/cloud_print/service/win/service_controller.cc b/cloud_print/service/win/service_controller.cc index 102e998..def8f1a 100644 --- a/cloud_print/service/win/service_controller.cc +++ b/cloud_print/service/win/service_controller.cc
@@ -8,6 +8,7 @@ #include <atlcom.h> #include <atlctl.h> +#include "base/base_switches.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h"
diff --git a/cloud_print/service/win/service_utils.cc b/cloud_print/service/win/service_utils.cc index e64b5cb..279ff9e 100644 --- a/cloud_print/service/win/service_utils.cc +++ b/cloud_print/service/win/service_utils.cc
@@ -3,15 +3,16 @@ // found in the LICENSE file. #include "cloud_print/service/win/service_utils.h" -#include "google_apis/gaia/gaia_switches.h" #include <windows.h> #include <security.h> // NOLINT +#include "base/base_switches.h" #include "base/command_line.h" #include "base/strings/string_util.h" #include "chrome/common/chrome_switches.h" #include "components/cloud_devices/common/cloud_devices_switches.h" +#include "google_apis/gaia/gaia_switches.h" base::string16 GetLocalComputerName() { DWORD size = 0;
diff --git a/components/BUILD.gn b/components/BUILD.gn index 16f8006..f5d6c8b2 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -310,6 +310,7 @@ "//components/leveldb_proto:unit_tests", "//components/suggestions:unit_tests", "//components/omnibox/browser:unit_tests", + "//components/sessions:test_support", ] if (!is_ios) {
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc index 247b5f03..7e2f83ad 100644 --- a/components/autofill/content/renderer/autofill_agent.cc +++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -223,7 +223,8 @@ if (is_same_page_navigation) { OnSamePageNavigationCompleted(); - } else if (is_new_navigation) { + } else { + // Navigation to a new page or a page refresh. form_cache_.Reset(); submitted_forms_.clear(); last_interacted_form_.reset(); @@ -627,8 +628,8 @@ render_frame()->GetWebFrame()->document().forms(forms); for (size_t i = 0; i < forms.size(); ++i) { const blink::WebFormElement& form = forms[i]; - if (GetCanonicalActionForForm(last_interacted_form_) == - GetCanonicalActionForForm(form) && + if (form_util::GetCanonicalActionForForm(last_interacted_form_) == + form_util::GetCanonicalActionForForm(form) && IsWebNodeVisible(form)) { // Found our candidate form, and it is still visible. return;
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc index ea4fe67..9f1d765 100644 --- a/components/autofill/content/renderer/form_autofill_util.cc +++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -52,6 +52,9 @@ using blink::WebVector; namespace autofill { + +const size_t kMaxParseableFields = 200; + namespace { // A bit field mask for FillForm functions to not fill some fields. @@ -1075,9 +1078,99 @@ control_elements, extract_mask, form, field); } +GURL StripAuthAndParams(const GURL& gurl) { + // We want to keep the path but strip any authentication data, as well as + // query and ref portions of URL, for the form action and form origin. + GURL::Replacements rep; + rep.ClearUsername(); + rep.ClearPassword(); + rep.ClearQuery(); + rep.ClearRef(); + return gurl.ReplaceComponents(rep); +} + } // namespace -const size_t kMaxParseableFields = 200; +namespace form_util { + +bool IsNamedElementVisible( + const std::vector<blink::WebFormControlElement>& control_elements, + const base::string16& name) { + for (size_t i = 0; i < control_elements.size(); ++i) { + if (control_elements[i].nameForAutofill() == name) { + return IsWebNodeVisible(control_elements[i]); + } + } + return false; +} + +bool IsFormVisible(blink::WebFrame* frame, + const GURL& action, + const GURL& origin, + const FormData& form_data, + const FormsPredictionsMap& form_predictions) { + const GURL frame_url = GURL(frame->document().url().string().utf8()); + blink::WebVector<blink::WebFormElement> forms; + frame->document().forms(forms); + +#if !defined(OS_MACOSX) && !defined(OS_ANDROID) + const bool action_is_empty = action == origin; +#endif + + // Since empty or unspecified action fields are automatically set to page URL, + // action field for forms cannot be used for comparing (all forms with + // empty/unspecified actions have the same value). If an action field is set + // to the page URL, this method checks ALL fields of the form instead (using + // FormData.SameFormAs). This is also true if the action was set to the page + // URL on purpose. + for (size_t i = 0; i < forms.size(); ++i) { + const blink::WebFormElement& form = forms[i]; + if (!IsWebNodeVisible(form)) + continue; + + GURL canonical_action = GetCanonicalActionForForm(form); +#if !defined(OS_MACOSX) && !defined(OS_ANDROID) + bool form_action_is_empty = canonical_action == frame_url; + + if (action_is_empty != form_action_is_empty) + continue; + + if (action_is_empty) { // Both actions are empty, compare all fields. + FormData extracted_form_data; + WebFormElementToFormData(form, blink::WebFormControlElement(), + EXTRACT_NONE, &extracted_form_data, nullptr); + if (form_data.SameFormAs(extracted_form_data)) { + return true; // Form still exists. + } + } else { // Both actions are non-empty, compare actions only. + if (action == canonical_action) { + return true; // Form still exists. + } + } +#else // OS_MACOSX or OS_ANDROID + if (action == canonical_action) { + return true; // Form still exists. + } +#endif + } + + return false; +} + +GURL GetCanonicalActionForForm(const WebFormElement& form) { + WebString action = form.action(); + if (action.isNull()) + action = WebString(""); // missing 'action' attribute implies current URL. + GURL full_action(form.document().completeURL(action)); + return StripAuthAndParams(full_action); +} + +GURL GetCanonicalOriginForDocument(const WebDocument& document) { + GURL full_origin(document.url()); + return StripAuthAndParams(full_origin); +} + +} // namespace form_util bool IsMonthInput(const WebInputElement* element) { CR_DEFINE_STATIC_LOCAL(WebString, kMonth, ("month"));
diff --git a/components/autofill/content/renderer/form_autofill_util.h b/components/autofill/content/renderer/form_autofill_util.h index 391551ea..9ba7efb 100644 --- a/components/autofill/content/renderer/form_autofill_util.h +++ b/components/autofill/content/renderer/form_autofill_util.h
@@ -9,6 +9,7 @@ #include "base/strings/string16.h" #include "components/autofill/core/common/autofill_constants.h" +#include "components/autofill/core/common/password_form_field_prediction_map.h" #include "third_party/WebKit/public/platform/WebVector.h" #include "third_party/WebKit/public/web/WebElementCollection.h" #include "ui/gfx/geometry/rect_f.h" @@ -53,6 +54,36 @@ // Copied to components/autofill/ios/browser/resources/autofill_controller.js. extern const size_t kMaxParseableFields; +namespace form_util { +// TODO(mathp): Move more functions in the form_util namespace. + +// Returns true if |control_elements| contains an element named |name| and is +// visible. +bool IsNamedElementVisible( + const std::vector<blink::WebFormControlElement>& control_elements, + const base::string16& name); + +// Helper function to check if there exist any form on |frame| where its action +// equals |action|. Returns true if so. For forms with empty or unspecified +// actions, all form data are used for comparison. Form data comparison is +// disabled on Mac and Android because the update prompt isn't implemented. +// It may cause many false password updates. +// TODO(kolos) Turn on all data comparing when the update prompt will be +// implemented on Mac and Android. +bool IsFormVisible(blink::WebFrame* frame, + const GURL& action, + const GURL& origin, + const FormData& form_data, + const FormsPredictionsMap& form_predictions); + +// Helper functions to assist in getting the canonical form of the action and +// origin. The action will proplerly take into account <BASE>, and both will +// strip unnecessary data (e.g. query params and HTTP credentials). +GURL GetCanonicalActionForForm(const blink::WebFormElement& form); +GURL GetCanonicalOriginForDocument(const blink::WebDocument& document); + +} // namespace form_util + // Returns true if |element| is a month input element. bool IsMonthInput(const blink::WebInputElement* element);
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index 9e6df579..d515592 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -73,19 +73,6 @@ !fill_data.username_field.value.empty()); } -// Returns true if |control_elements| contains an element named |name| and is -// visible. -bool IsNamedElementVisible( - const std::vector<blink::WebFormControlElement>& control_elements, - const base::string16& name) { - for (const blink::WebFormControlElement& control_element : control_elements) { - if (control_element.nameForAutofill() == name) { - return IsWebNodeVisible(control_element); - } - } - return false; -} - // Returns true if password form has username and password fields with either // same or no name and id attributes supplied. bool DoesFormContainAmbiguousOrEmptyNames( @@ -132,6 +119,37 @@ : field.name; } +bool IsUnownedPasswordFormVisible(blink::WebFrame* frame, + const GURL& action, + const GURL& origin, + const FormData& form_data, + const FormsPredictionsMap& form_predictions) { + scoped_ptr<PasswordForm> unowned_password_form( + CreatePasswordFormFromUnownedInputElements(*frame, nullptr, + &form_predictions)); + std::vector<blink::WebFormControlElement> control_elements = + GetUnownedAutofillableFormFieldElements(frame->document().all(), nullptr); + if (unowned_password_form && + form_util::IsNamedElementVisible( + control_elements, unowned_password_form->username_element) && + form_util::IsNamedElementVisible( + control_elements, unowned_password_form->password_element)) { +#if !defined(OS_MACOSX) && !defined(OS_ANDROID) + const bool action_is_empty = action == origin; + bool forms_are_same = + action_is_empty ? form_data.SameFormAs(unowned_password_form->form_data) + : action == unowned_password_form->action; + if (forms_are_same) + return true; // Form still exists. +#else // OS_MACOSX or OS_ANDROID + if (action == unowned_password_form->action) + return true; // Form still exists. +#endif + } + + return false; +} + // Utility function to find the unique entry of |control_elements| for the // specified input |field|. On successful find, adds it to |result| and returns // |true|. Otherwise clears the references from each |HTMLInputElement| from @@ -267,7 +285,7 @@ if (!doc.isHTMLDocument()) return; - if (data.origin != GetCanonicalOriginForDocument(doc)) + if (data.origin != form_util::GetCanonicalOriginForDocument(doc)) return; blink::WebVector<blink::WebFormElement> forms; @@ -277,7 +295,7 @@ blink::WebFormElement fe = forms[i]; // Action URL must match. - if (data.action != GetCanonicalActionForForm(fe)) + if (data.action != form_util::GetCanonicalActionForForm(fe)) continue; std::vector<blink::WebFormControlElement> control_elements = @@ -596,91 +614,6 @@ return it != map.end() && it->second.get(); } - -// Helper function to check if there exist any form on |frame| where its action -// equals |saved form|'s action or input elements outside a <form> tag if the -// action equals the current url. Return true if so. -// For forms with empty or unspecified actions, all form data are used for -// comparing. All data comparing is disabled on Mac and Android because the -// update prompt isn't implemented. It may cause many false password updates. -// TODO(kolos) Turn on all data comparing when the update prompt will be -// implemented on Mac and Android. -bool IsFormVisible(blink::WebFrame* frame, - const PasswordForm& saved_form, - const FormsPredictionsMap& form_predictions) { - const GURL frame_url = GURL(frame->document().url().string().utf8()); - blink::WebVector<blink::WebFormElement> forms; - frame->document().forms(forms); - -#if !defined(OS_MACOSX) && !defined(OS_ANDROID) - const bool saved_form_action_is_empty = - saved_form.action == saved_form.origin; -#endif - - // Since empty or unspecified action fields are automatically set to page URL, - // action field for forms cannot be used for comparing (all forms with - // empty/unspecified actions have the same value). If an action field is set - // to the page URL, this method checks ALL fields of the form instead (using - // FormData.SameFormAs). This is also true if the action was set to the page - // URL on purpose. - for (size_t i = 0; i < forms.size(); ++i) { - const blink::WebFormElement& form = forms[i]; - if (!IsWebNodeVisible(form)) - continue; - - GURL canonical_action = GetCanonicalActionForForm(form); - -#if !defined(OS_MACOSX) && !defined(OS_ANDROID) - bool action_is_empty = canonical_action == frame_url; - - if (saved_form_action_is_empty != action_is_empty) - continue; - - if (action_is_empty) { // Both actions are empty, compare all fields. - FormData form_data; - WebFormElementToFormData(form, blink::WebFormControlElement(), - EXTRACT_NONE, &form_data, nullptr); - if (saved_form.form_data.SameFormAs(form_data)) { - return true; // Form still exists. - } - } else { // Both actions are non-empty, compare actions only. - if (saved_form.action == canonical_action) { - return true; // Form still exists. - } - } -#else // OS_MACOSX or OS_ANDROID - if (saved_form.action == canonical_action) { - return true; // Form still exists. - } -#endif - } - - scoped_ptr<PasswordForm> unowned_password_form( - CreatePasswordFormFromUnownedInputElements(*frame, nullptr, - &form_predictions)); - std::vector<blink::WebFormControlElement> control_elements = - GetUnownedAutofillableFormFieldElements(frame->document().all(), nullptr); - if (unowned_password_form && - IsNamedElementVisible(control_elements, - unowned_password_form->username_element) && - IsNamedElementVisible(control_elements, - unowned_password_form->password_element)) { -#if !defined(OS_MACOSX) && !defined(OS_ANDROID) - bool forms_are_same = - saved_form_action_is_empty - ? saved_form.form_data.SameFormAs(unowned_password_form->form_data) - : saved_form.action == unowned_password_form->action; - if (forms_are_same) - return true; // Form still exists. -#else // OS_MACOSX or OS_ANDROID - if (saved_form.action == unowned_password_form->action) - return true; // Form still exists. -#endif - } - - return false; -} - } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -1001,8 +934,16 @@ // Prompt to save only if the form is now gone, either invisible or // removed from the DOM. blink::WebFrame* frame = render_frame()->GetWebFrame(); - if (IsFormVisible(frame, *provisionally_saved_form_, form_predictions_)) + if (form_util::IsFormVisible(frame, provisionally_saved_form_->action, + provisionally_saved_form_->origin, + provisionally_saved_form_->form_data, + form_predictions_) || + IsUnownedPasswordFormVisible(frame, provisionally_saved_form_->action, + provisionally_saved_form_->origin, + provisionally_saved_form_->form_data, + form_predictions_)) { return; + } Send(new AutofillHostMsg_InPageNavigation(routing_id(), *provisionally_saved_form_));
diff --git a/components/autofill/content/renderer/password_form_conversion_utils.cc b/components/autofill/content/renderer/password_form_conversion_utils.cc index 3a89823..62ade2b 100644 --- a/components/autofill/content/renderer/password_form_conversion_utils.cc +++ b/components/autofill/content/renderer/password_form_conversion_utils.cc
@@ -491,7 +491,8 @@ if (!LocateSpecificPasswords(passwords, &password, &new_password)) return false; - password_form->origin = GetCanonicalOriginForDocument(form.document); + password_form->origin = + form_util::GetCanonicalOriginForDocument(form.document); GURL::Replacements rep; rep.SetPathStr(""); password_form->signon_realm = @@ -539,32 +540,8 @@ return true; } -GURL StripAuthAndParams(const GURL& gurl) { - // We want to keep the path but strip any authentication data, as well as - // query and ref portions of URL, for the form action and form origin. - GURL::Replacements rep; - rep.ClearUsername(); - rep.ClearPassword(); - rep.ClearQuery(); - rep.ClearRef(); - return gurl.ReplaceComponents(rep); -} - } // namespace -GURL GetCanonicalActionForForm(const WebFormElement& form) { - WebString action = form.action(); - if (action.isNull()) - action = WebString(""); // missing 'action' attribute implies current URL - GURL full_action(form.document().completeURL(action)); - return StripAuthAndParams(full_action); -} - -GURL GetCanonicalOriginForDocument(const WebDocument& document) { - GURL full_origin(document.url()); - return StripAuthAndParams(full_origin); -} - bool IsGaiaReauthenticationForm( const GURL& origin, const WebVector<blink::WebFormControlElement>& control_elements) { @@ -605,7 +582,7 @@ return scoped_ptr<PasswordForm>(); scoped_ptr<PasswordForm> password_form(new PasswordForm()); - password_form->action = GetCanonicalActionForForm(web_form); + password_form->action = form_util::GetCanonicalActionForForm(web_form); if (!password_form->action.is_valid()) return scoped_ptr<PasswordForm>();
diff --git a/components/autofill/content/renderer/password_form_conversion_utils.h b/components/autofill/content/renderer/password_form_conversion_utils.h index d931e2a0..257e202 100644 --- a/components/autofill/content/renderer/password_form_conversion_utils.h +++ b/components/autofill/content/renderer/password_form_conversion_utils.h
@@ -27,12 +27,6 @@ struct FormFieldData; struct PasswordForm; -// Helper functions to assist in getting the canonical form of the action and -// origin. The action will proplerly take into account <BASE>, and both will -// strip unnecessary data (e.g. query params and HTTP credentials). -GURL GetCanonicalActionForForm(const blink::WebFormElement& form); -GURL GetCanonicalOriginForDocument(const blink::WebDocument& document); - // Tests whether the given form is a GAIA reauthentication form. The form is // not passed directly as WebFormElement, but by specifying its |url| and // |control_elements|. This is for better performance and easier testing.
diff --git a/components/components_tests.gyp b/components/components_tests.gyp index 4f43573b..d1d3843 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp
@@ -1459,9 +1459,7 @@ 'target_name': 'components_browsertests_apk', 'type': 'none', 'dependencies': [ - '../content/content.gyp:content_icudata', '../content/content.gyp:content_java', - '../content/content.gyp:content_v8_external_data', '../content/content_shell_and_tests.gyp:content_java_test_support', '../content/content_shell_and_tests.gyp:content_shell_browsertests_java', '../content/content_shell_and_tests.gyp:content_shell_java',
diff --git a/components/cronet.gypi b/components/cronet.gypi index 5a63b94..10a7fecd 100644 --- a/components/cronet.gypi +++ b/components/cronet.gypi
@@ -49,10 +49,10 @@ 'includes': [ '../build/android/java_cpp_enum.gypi' ], }, { - 'target_name': 'cronet_url_request_context_config_list', + 'target_name': 'cronet_engine_builder_list', 'type': 'none', 'sources': [ - 'cronet/android/java/src/org/chromium/net/UrlRequestContextConfigList.template', + 'cronet/android/java/src/org/chromium/net/CronetEngineBuilderList.template', ], 'variables': { 'package_name': 'org/chromium/cronet', @@ -214,7 +214,7 @@ 'target_name': 'cronet_api', 'type': 'none', 'dependencies': [ - 'cronet_url_request_context_config_list', + 'cronet_engine_builder_list', 'cronet_version', 'load_states_list', 'network_quality_observations_java', @@ -223,6 +223,8 @@ 'java_in_dir': 'cronet/android/java', 'javac_includes': [ '**/ChunkedWritableByteChannel.java', + '**/CronetEngine.java', + '**/CronetEngineBuilderList.java', '**/ExtendedResponseInfo.java', '**/HistogramManager.java', '**/HttpUrlConnection*.java', @@ -235,9 +237,7 @@ '**/UploadDataProvider.java', '**/UploadDataSink.java', '**/UrlRequest.java', - '**/UrlRequestContext.java', '**/UrlRequestContextConfig.java', - '**/UrlRequestContextConfigList.java', '**/UrlRequestException.java', '**/UrlRequestListener.java', '**/UserAgent.java',
diff --git a/components/cronet/README.md b/components/cronet/README.md index eb7d81a3..c917eb2d 100644 --- a/components/cronet/README.md +++ b/components/cronet/README.md
@@ -68,13 +68,13 @@ Make a request like this: - UrlRequestContextConfig myConfig = new UrlRequestContextConfig(); - CronetUrlRequestContext myRequestContext = - new CronetUrlRequestContext(getContext(), myConfig); + CronetEngine.Builder engineBuilder = new CronetEngine.Builder(getContext()); + CronetEngine engine = engineBuilder.build(); Executor executor = Executors.newSingleThreadExecutor(); MyListener listener = new MyListener(); - UrlRequest request = myRequestContext.createRequest( - "https://www.example.com", listener, executor); + UrlRequest.Builder requestBuilder = new UrlRequest.Builder( + "https://www.example.com", listener, executor, engine); + UrlRequest request = requestBuilder.build(); request.start(); In the above example, `MyListener` extends `UrlRequestListener`. The request @@ -97,9 +97,8 @@ ### Uploading Data MyUploadDataProvider myUploadDataProvider = new MyUploadDataProvider(); - request.setHttpMethod("POST"); - request.setUploadDataProvider(myUploadDataProvider, executor); - request.start(); + requestBuilder.setHttpMethod("POST"); + requestBuilder.setUploadDataProvider(myUploadDataProvider, executor); In the above example, `MyUploadDataProvider` extends `UploadDataProvider`. When Cronet is ready to send the request body, @@ -112,32 +111,32 @@ invoked again. For more details, please see the API reference. ### <a id=configuring-cronet></a> Configuring Cronet -Various configuration options are available via the `UrlRequestContextConfig` +Various configuration options are available via the `CronetEngine.Builder` object. Enabling HTTP/2, QUIC, or SDCH: - For Example: - myConfig.enableSPDY(true).enableQUIC(true).enableSDCH(true); + engineBuilder.enableSPDY(true).enableQUIC(true).enableSDCH(true); Controlling the cache: - Use a 100KiB in-memory cache: - myConfig.enableHttpCache( - UrlRequestContextConfig.HttpCache.IN_MEMORY, 100 * 1024); + engineBuilder.enableHttpCache( + CronetEngine.Builder.HttpCache.IN_MEMORY, 100 * 1024); - or use a 1MiB disk cache: - myConfig.setStoragePath(storagePathString); - myConfig.enableHttpCache(UrlRequestContextConfig.HttpCache.DISK, + engineBuilder.setStoragePath(storagePathString); + engineBuilder.enableHttpCache(CronetEngine.Builder.HttpCache.DISK, 1024 * 1024); ### Debugging To get more information about how Cronet is processing network requests, you can start and stop **NetLog** logging by calling -`UrlRequestContext.startNetLogToFile` and `UrlRequestContext.stopNetLog`. +`CronetEngine.startNetLogToFile` and `CronetEngine.stopNetLog`. Bear in mind that logs may contain sensitive data. You may analyze the generated log by navigating to [chrome://net-internals#import] using a Chrome browser. @@ -149,7 +148,7 @@ simply do the following: CronetURLStreamHandlerFactory streamHandlerFactory = - new CronetURLStreamHandlerFactory(getContext(), myConfig); + new CronetURLStreamHandlerFactory(engine); URL.setURLStreamHandlerFactory(streamHandlerFactory); Cronet's @@ -158,7 +157,7 @@ see {@link org.chromium.net.urlconnection.CronetURLStreamHandlerFactory} for more information). You can configure Cronet and control caching through the -`UrlRequestContextConfig` instance, `myConfig` +`CronetEngine.Builder` instance, `engineBuilder` (See [Configuring Cronet](#configuring-cronet) section), before you pass it into the `CronetURLStreamHandlerFactory` constructor.
diff --git a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java index 2901071a..6c875e1 100644 --- a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java +++ b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestContext.java
@@ -15,7 +15,7 @@ /** * Provides context for the native HTTP operations. - * @deprecated Use {@link CronetUrlRequestContext} instead. + * @deprecated Use {@link CronetEngine} instead. */ @JNINamespace("cronet") @Deprecated @@ -34,7 +34,7 @@ * Constructor. */ protected ChromiumUrlRequestContext( - final Context context, String userAgent, UrlRequestContextConfig config) { + final Context context, String userAgent, CronetEngine.Builder config) { CronetLibraryLoader.ensureInitialized(context, config); mChromiumUrlRequestContextAdapter = nativeCreateRequestContextAdapter(userAgent, getLoggingLevel(), config.toString());
diff --git a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestFactory.java b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestFactory.java index 95200820..1fc9393 100644 --- a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestFactory.java +++ b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestFactory.java
@@ -14,7 +14,7 @@ /** * Network request factory using the native http stack implementation. - * @deprecated Use {@link CronetUrlRequestContext} instead. + * @deprecated Use {@link CronetEngine} instead. */ @UsedByReflection("HttpUrlRequestFactory.java") @Deprecated @@ -22,8 +22,7 @@ private ChromiumUrlRequestContext mRequestContext; @UsedByReflection("HttpUrlRequestFactory.java") - public ChromiumUrlRequestFactory( - Context context, UrlRequestContextConfig config) { + public ChromiumUrlRequestFactory(Context context, CronetEngine.Builder config) { if (isEnabled()) { String userAgent = config.userAgent(); if (userAgent.isEmpty()) {
diff --git a/components/cronet/android/java/src/org/chromium/net/CronetEngine.java b/components/cronet/android/java/src/org/chromium/net/CronetEngine.java new file mode 100644 index 0000000..2de7e8d0 --- /dev/null +++ b/components/cronet/android/java/src/org/chromium/net/CronetEngine.java
@@ -0,0 +1,563 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.net; + +import android.content.Context; +import android.util.Log; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; +import java.lang.reflect.Constructor; +import java.util.concurrent.Executor; + +/** + * An engine to process {@link UrlRequest}s, which uses the best HTTP stack + * available on the current platform. + */ +public abstract class CronetEngine { + /** + * A builder for {@link CronetEngine}s, which allows runtime configuration of + * {@code CronetEngine}. Configuration options are set on the builder and + * then {@link #build} is called to create the {@code CronetEngine}. + */ + public static class Builder { + private final JSONObject mConfig; + private final Context mContext; + + /** + * Default config enables SPDY, disables QUIC, SDCH and HTTP cache. + * @param context Android {@link Context} for engine to use. + */ + public Builder(Context context) { + mConfig = new JSONObject(); + mContext = context; + enableLegacyMode(false); + enableQUIC(false); + enableHTTP2(true); + enableSDCH(false); + enableHttpCache(HTTP_CACHE_DISABLED, 0); + } + + /** + * Creates a config from a JSON string, which was serialized using + * {@link #toString}. + * + * @param context Android {@link Context} for engine to use. + * @param json JSON string of configuration parameters, which was + * serialized using {@link #toString}. + */ + public Builder(Context context, String json) throws JSONException { + mConfig = new JSONObject(json); + mContext = context; + } + + /** + * Overrides the user-agent header for all requests. + * @return the builder to facilitate chaining. + */ + public Builder setUserAgent(String userAgent) { + return putString(CronetEngineBuilderList.USER_AGENT, userAgent); + } + + String userAgent() { + return mConfig.optString(CronetEngineBuilderList.USER_AGENT); + } + + /** + * Sets directory for HTTP Cache and Cookie Storage. The directory must + * exist. + * @param value path to existing directory. + * @return the builder to facilitate chaining. + */ + public Builder setStoragePath(String value) { + if (!new File(value).isDirectory()) { + throw new IllegalArgumentException( + "Storage path must be set to existing directory"); + } + + return putString(CronetEngineBuilderList.STORAGE_PATH, value); + } + + String storagePath() { + return mConfig.optString(CronetEngineBuilderList.STORAGE_PATH); + } + + /** + * Sets whether falling back to implementation based on system's + * {@link java.net.HttpURLConnection} implementation is enabled. + * Defaults to disabled. + * @return the builder to facilitate chaining. + * @deprecated Not supported by the new API. + */ + @Deprecated + public Builder enableLegacyMode(boolean value) { + return putBoolean(CronetEngineBuilderList.ENABLE_LEGACY_MODE, value); + } + + boolean legacyMode() { + return mConfig.optBoolean(CronetEngineBuilderList.ENABLE_LEGACY_MODE); + } + + /** + * Overrides the name of the native library backing Cronet. + * @return the builder to facilitate chaining. + */ + Builder setLibraryName(String libName) { + return putString(CronetEngineBuilderList.NATIVE_LIBRARY_NAME, libName); + } + + String libraryName() { + return mConfig.optString(CronetEngineBuilderList.NATIVE_LIBRARY_NAME, "cronet"); + } + + /** + * Sets whether <a href="https://www.chromium.org/quic">QUIC</a> protocol + * is enabled. Defaults to disabled. + * @return the builder to facilitate chaining. + */ + public Builder enableQUIC(boolean value) { + return putBoolean(CronetEngineBuilderList.ENABLE_QUIC, value); + } + + /** + * Sets whether <a href="https://tools.ietf.org/html/rfc7540">HTTP/2</a> + * protocol is enabled. Defaults to enabled. + * @return the builder to facilitate chaining. + */ + public Builder enableHTTP2(boolean value) { + return putBoolean(CronetEngineBuilderList.ENABLE_SPDY, value); + } + + /** + * Sets whether + * <a + * href="https://lists.w3.org/Archives/Public/ietf-http-wg/2008JulSep/att-0441/Shared_Dictionary_Compression_over_HTTP.pdf"> + * SDCH</a> compression is enabled. Defaults to disabled. + * @return the builder to facilitate chaining. + */ + public Builder enableSDCH(boolean value) { + return putBoolean(CronetEngineBuilderList.ENABLE_SDCH, value); + } + + /** + * Enables + * <a href="https://developer.chrome.com/multidevice/data-compression">Data + * Reduction Proxy</a>. Defaults to disabled. + * @param key key to use when authenticating with the proxy. + * @return the builder to facilitate chaining. + */ + public Builder enableDataReductionProxy(String key) { + return (putString(CronetEngineBuilderList.DATA_REDUCTION_PROXY_KEY, key)); + } + + /** + * Overrides + * <a href="https://developer.chrome.com/multidevice/data-compression"> + * Data Reduction Proxy</a> configuration parameters with a primary + * proxy name, fallback proxy name, and a secure proxy check URL. Proxies + * are specified as [scheme://]host[:port]. Used for testing. + * @param primaryProxy the primary data reduction proxy to use. + * @param fallbackProxy a fallback data reduction proxy to use. + * @param secureProxyCheckUrl a URL to fetch to determine if using a secure + * proxy is allowed. + * @return the builder to facilitate chaining. + * @hide + */ + public Builder setDataReductionProxyOptions( + String primaryProxy, String fallbackProxy, String secureProxyCheckUrl) { + if (primaryProxy.isEmpty() || fallbackProxy.isEmpty() + || secureProxyCheckUrl.isEmpty()) { + throw new IllegalArgumentException( + "Primary and fallback proxies and check url must be set"); + } + putString(CronetEngineBuilderList.DATA_REDUCTION_PRIMARY_PROXY, primaryProxy); + putString(CronetEngineBuilderList.DATA_REDUCTION_FALLBACK_PROXY, fallbackProxy); + putString(CronetEngineBuilderList.DATA_REDUCTION_SECURE_PROXY_CHECK_URL, + secureProxyCheckUrl); + return this; + } + + /** + * Setting to disable HTTP cache. Some data may still be temporarily stored in memory. + * Passed to {@link #enableHttpCache}. + */ + public static final int HTTP_CACHE_DISABLED = 0; + + /** + * Setting to enable in-memory HTTP cache, including HTTP data. + * Passed to {@link #enableHttpCache}. + */ + public static final int HTTP_CACHE_IN_MEMORY = 1; + + /** + * Setting to enable on-disk cache, excluding HTTP data. + * {@link #setStoragePath} must be called prior to passing this constant to + * {@link #enableHttpCache}. + */ + public static final int HTTP_CACHE_DISK_NO_HTTP = 2; + + /** + * Setting to enable on-disk cache, including HTTP data. + * {@link #setStoragePath} must be called prior to passing this constant to + * {@link #enableHttpCache}. + */ + public static final int HTTP_CACHE_DISK = 3; + + /** + * Enables or disables caching of HTTP data and other information like QUIC + * server information. + * @param cacheMode control location and type of cached data. + * @param maxSize maximum size in bytes used to cache data (advisory and maybe + * exceeded at times). + * @return the builder to facilitate chaining. + */ + public Builder enableHttpCache(int cacheMode, long maxSize) { + if (cacheMode == HTTP_CACHE_DISK || cacheMode == HTTP_CACHE_DISK_NO_HTTP) { + if (storagePath().isEmpty()) { + throw new IllegalArgumentException("Storage path must be set"); + } + } else { + if (!storagePath().isEmpty()) { + throw new IllegalArgumentException("Storage path must be empty"); + } + } + putBoolean(CronetEngineBuilderList.LOAD_DISABLE_CACHE, + cacheMode == HTTP_CACHE_DISABLED || cacheMode == HTTP_CACHE_DISK_NO_HTTP); + putLong(CronetEngineBuilderList.HTTP_CACHE_MAX_SIZE, maxSize); + + switch (cacheMode) { + case HTTP_CACHE_DISABLED: + return putString(CronetEngineBuilderList.HTTP_CACHE, + CronetEngineBuilderList.HTTP_CACHE_DISABLED); + case HTTP_CACHE_DISK_NO_HTTP: + case HTTP_CACHE_DISK: + return putString(CronetEngineBuilderList.HTTP_CACHE, + CronetEngineBuilderList.HTTP_CACHE_DISK); + + case HTTP_CACHE_IN_MEMORY: + return putString(CronetEngineBuilderList.HTTP_CACHE, + CronetEngineBuilderList.HTTP_CACHE_MEMORY); + } + return this; + } + + /** + * Adds hint that {@code host} supports QUIC. + * Note that {@link #enableHttpCache enableHttpCache} + * ({@link HttpCache#DISK DISK}) is needed to take advantage of 0-RTT + * connection establishment between sessions. + * + * @param host hostname of the server that supports QUIC. + * @param port host of the server that supports QUIC. + * @param alternatePort alternate port to use for QUIC. + * @return the builder to facilitate chaining. + */ + public Builder addQuicHint(String host, int port, int alternatePort) { + if (host.contains("/")) { + throw new IllegalArgumentException("Illegal QUIC Hint Host: " + host); + } + try { + JSONArray quicHints = mConfig.optJSONArray(CronetEngineBuilderList.QUIC_HINTS); + if (quicHints == null) { + quicHints = new JSONArray(); + mConfig.put(CronetEngineBuilderList.QUIC_HINTS, quicHints); + } + + JSONObject hint = new JSONObject(); + hint.put(CronetEngineBuilderList.QUIC_HINT_HOST, host); + hint.put(CronetEngineBuilderList.QUIC_HINT_PORT, port); + hint.put(CronetEngineBuilderList.QUIC_HINT_ALT_PORT, alternatePort); + quicHints.put(hint); + } catch (JSONException e) { + // Intentionally do nothing. + } + return this; + } + + /** + * Sets experimental QUIC connection options, overwriting any pre-existing + * options. List of options is subject to change. + * + * @param quicConnectionOptions comma-separated QUIC options (for example + * "PACE,IW10") to use if QUIC is enabled. + * @return the builder to facilitate chaining. + */ + public Builder setExperimentalQuicConnectionOptions(String quicConnectionOptions) { + return putString(CronetEngineBuilderList.QUIC_OPTIONS, quicConnectionOptions); + } + + /** + * Get JSON string representation of the builder. + */ + @Override + public String toString() { + return mConfig.toString(); + } + + /** + * Returns {@link Context} for builder. + * + * @return {@link Context} for builder. + */ + Context getContext() { + return mContext; + } + + /** + * Sets a boolean value in the config. Returns a reference to the same + * config object, so you can chain put calls together. + * @return the builder to facilitate chaining. + */ + private Builder putBoolean(String key, boolean value) { + try { + mConfig.put(key, value); + } catch (JSONException e) { + // Intentionally do nothing. + } + return this; + } + + /** + * Sets a long value in the config. Returns a reference to the same + * config object, so you can chain put calls together. + * @return the builder to facilitate chaining. + */ + private Builder putLong(String key, long value) { + try { + mConfig.put(key, value); + } catch (JSONException e) { + // Intentionally do nothing. + } + return this; + } + + /** + * Sets a string value in the config. Returns a reference to the same + * config object, so you can chain put calls together. + * @return the builder to facilitate chaining. + */ + private Builder putString(String key, String value) { + try { + mConfig.put(key, value); + } catch (JSONException e) { + // Intentionally do nothing. + } + return this; + } + + /** + * Build a {@link CronetEngine} using this builder's configuration. + */ + public CronetEngine build() { + return createContext(this); + } + } + + private static final String TAG = "UrlRequestFactory"; + private static final String CRONET_URL_REQUEST_CONTEXT = + "org.chromium.net.CronetUrlRequestContext"; + + /** + * Creates a {@link UrlRequest} object. All callbacks will + * be called on {@code executor}'s thread. {@code executor} must not run + * tasks on the current thread to prevent blocking networking operations + * and causing exceptions during shutdown. Request is given medium priority, + * see {@link UrlRequest#REQUEST_PRIORITY_MEDIUM}. To specify other + * priorities see {@link #createRequest(String, UrlRequestListener, + * Executor, int priority)}. + * + * @param url {@link java.net.URL} for the request. + * @param listener callback class that gets called on different events. + * @param executor {@link Executor} on which all callbacks will be called. + * @return new request. + * @deprecated Use {@link Builder#build}. + */ + @Deprecated + public abstract UrlRequest createRequest( + String url, UrlRequestListener listener, Executor executor); + + /** + * Creates a {@link UrlRequest} object. All callbacks will + * be called on {@code executor}'s thread. {@code executor} must not run + * tasks on the current thread to prevent blocking networking operations + * and causing exceptions during shutdown. + * + * @param url {@link java.net.URL} for the request. + * @param listener callback class that gets called on different events. + * @param executor {@link Executor} on which all callbacks will be called. + * @param priority priority of the request which should be one of the + * {@link UrlRequest#REQUEST_PRIORITY_IDLE REQUEST_PRIORITY_*} + * values. + * @return new request. + * @deprecated Use {@link Builder#build}. + */ + @Deprecated + public abstract UrlRequest createRequest( + String url, UrlRequestListener listener, Executor executor, int priority); + + /** + * @return {@code true} if the engine is enabled. + */ + abstract boolean isEnabled(); + + /** + * @return a human-readable version string of the engine. + */ + public abstract String getVersionString(); + + /** + * Shuts down the {@link CronetEngine} if there are no active requests, + * otherwise throws an exception. + * + * Cannot be called on network thread - the thread Cronet calls into + * Executor on (which is different from the thread the Executor invokes + * callbacks on). May block until all the {@code CronetEngine}'s + * resources have been cleaned up. + */ + public abstract void shutdown(); + + /** + * Starts NetLog logging to a file. The NetLog is useful for debugging. + * The file can be viewed using a Chrome browser navigated to + * chrome://net-internals/#import + * @param fileName the complete file path. It must not be empty. If the file + * exists, it is truncated before starting. If actively logging, + * this method is ignored. + * @param logAll {@code true} to include basic events, user cookies, + * credentials and all transferred bytes in the log. + * {@code false} to just include basic events. + */ + public abstract void startNetLogToFile(String fileName, boolean logAll); + + /** + * Stops NetLog logging and flushes file to disk. If a logging session is + * not in progress, this call is ignored. + */ + public abstract void stopNetLog(); + + /** + * Enables the network quality estimator, which collects and reports + * measurements of round trip time (RTT) and downstream throughput at + * various layers of the network stack. After enabling the estimator, + * listeners of RTT and throughput can be added with + * {@link #addRttListener} and {@link #addThroughputListener} and + * removed with {@link #removeRttListener} and + * {@link #removeThroughputListener}. The estimator uses memory and CPU + * only when enabled. + * @param executor an executor that will be used to notified all + * added RTT and throughput listeners. + * @deprecated not really deprecated but hidden for now as it's a prototype. + */ + @Deprecated public abstract void enableNetworkQualityEstimator(Executor executor); + + /** + * Enables the network quality estimator for testing. This must be called + * before round trip time and throughput listeners are added. Set both + * boolean parameters to false for default behavior. + * @param useLocalHostRequests include requests to localhost in estimates. + * @param useSmallerResponses include small responses in throughput estimates. + * @param executor an {@link java.util.concurrent.Executor} on which all + * listeners will be called. + * @deprecated not really deprecated but hidden for now as it's a prototype. + */ + @Deprecated + abstract void enableNetworkQualityEstimatorForTesting( + boolean useLocalHostRequests, boolean useSmallerResponses, Executor executor); + + /** + * Registers a listener that gets called whenever the network quality + * estimator witnesses a sample round trip time. This must be called + * after {@link #enableNetworkQualityEstimator}, and with throw an + * exception otherwise. Round trip times may be recorded at various layers + * of the network stack, including TCP, QUIC, and at the URL request layer. + * The listener is called on the {@link java.util.concurrent.Executor} that + * is passed to {@link #enableNetworkQualityEstimator}. + * @param listener the listener of round trip times. + * @deprecated not really deprecated but hidden for now as it's a prototype. + */ + @Deprecated public abstract void addRttListener(NetworkQualityRttListener listener); + + /** + * Removes a listener of round trip times if previously registered with + * {@link #addRttListener}. This should be called after a + * {@link NetworkQualityRttListener} is added in order to stop receiving + * observations. + * @param listener the listener of round trip times. + * @deprecated not really deprecated but hidden for now as it's a prototype. + */ + @Deprecated public abstract void removeRttListener(NetworkQualityRttListener listener); + + /** + * Registers a listener that gets called whenever the network quality + * estimator witnesses a sample throughput measurement. This must be called + * after {@link #enableNetworkQualityEstimator}. Throughput observations + * are computed by measuring bytes read over the active network interface + * at times when at least one URL response is being received. The listener + * is called on the {@link java.util.concurrent.Executor} that is passed to + * {@link #enableNetworkQualityEstimator}. + * @param listener the listener of throughput. + * @deprecated not really deprecated but hidden for now as it's a prototype. + */ + @Deprecated + public abstract void addThroughputListener(NetworkQualityThroughputListener listener); + + /** + * Removes a listener of throughput. This should be called after a + * {@link NetworkQualityThroughputListener} is added with + * {@link #addThroughputListener} in order to stop receiving observations. + * @param listener the listener of throughput. + * @deprecated not really deprecated but hidden for now as it's a prototype. + */ + @Deprecated + public abstract void removeThroughputListener(NetworkQualityThroughputListener listener); + + /** + * Creates a {@link CronetEngine} with the given {@link Builder}. + * @param context Android {@link Context}. + * @param config engine configuration. + * @deprecated Use {@link CronetEngine.Builder}. + */ + @Deprecated + public static CronetEngine createContext(Builder config) { + CronetEngine cronetEngine = null; + if (config.userAgent().isEmpty()) { + config.setUserAgent(UserAgent.from(config.getContext())); + } + if (!config.legacyMode()) { + cronetEngine = createCronetEngine(config); + } + if (cronetEngine == null) { + // TODO(mef): Fallback to stub implementation. Once stub + // implementation is available merge with createCronetFactory. + cronetEngine = createCronetEngine(config); + } + Log.i(TAG, "Using network stack: " + cronetEngine.getVersionString()); + return cronetEngine; + } + + private static CronetEngine createCronetEngine(Builder config) { + CronetEngine cronetEngine = null; + try { + Class<? extends CronetEngine> engineClass = + CronetEngine.class.getClassLoader() + .loadClass(CRONET_URL_REQUEST_CONTEXT) + .asSubclass(CronetEngine.class); + Constructor<? extends CronetEngine> constructor = + engineClass.getConstructor(Builder.class); + CronetEngine possibleEngine = constructor.newInstance(config); + if (possibleEngine.isEnabled()) { + cronetEngine = possibleEngine; + } + } catch (ClassNotFoundException e) { + // Leave as null. + } catch (Exception e) { + throw new IllegalStateException("Cannot instantiate: " + CRONET_URL_REQUEST_CONTEXT, e); + } + return cronetEngine; + } +}
diff --git a/components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfigList.template b/components/cronet/android/java/src/org/chromium/net/CronetEngineBuilderList.template similarity index 72% rename from components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfigList.template rename to components/cronet/android/java/src/org/chromium/net/CronetEngineBuilderList.template index cbb9350..f30a09f 100644 --- a/components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfigList.template +++ b/components/cronet/android/java/src/org/chromium/net/CronetEngineBuilderList.template
@@ -5,9 +5,9 @@ package org.chromium.net; // A simple auto-generated interface used to list config params as used by -// both org.chromium.net.UrlRequestContextConfig and -// net/cronet/android/org_chromium_net_UrlRequestContext.h -public interface UrlRequestContextConfigList { +// both org.chromium.net.CronetEngine.Builder and +// components/cronet/url_request_context_config.h +public interface CronetEngineBuilderList { #define DEFINE_CONTEXT_CONFIG(x) public static final String x = #x; #include "components/cronet/url_request_context_config_list.h" #undef DEFINE_CONTEXT_CONFIG
diff --git a/components/cronet/android/java/src/org/chromium/net/CronetLibraryLoader.java b/components/cronet/android/java/src/org/chromium/net/CronetLibraryLoader.java index 9894ecd..60a7675 100644 --- a/components/cronet/android/java/src/org/chromium/net/CronetLibraryLoader.java +++ b/components/cronet/android/java/src/org/chromium/net/CronetLibraryLoader.java
@@ -26,12 +26,12 @@ * any thread, the load and initialization is performed on main thread. */ public static void ensureInitialized( - final Context context, final UrlRequestContextConfig config) { + final Context context, final CronetEngine.Builder builder) { synchronized (sLoadLock) { if (sInitTaskPosted) { return; } - System.loadLibrary(config.libraryName()); + System.loadLibrary(builder.libraryName()); if (!Version.CRONET_VERSION.equals(nativeGetCronetVersion())) { throw new RuntimeException(String.format( "Expected Cronet version number %s, " @@ -40,7 +40,7 @@ nativeGetCronetVersion())); } nativeCronetInitApplicationContext(context.getApplicationContext()); - // Init native Chromium URLRequestContext on Main UI thread. + // Init native Chromium CronetEngine on Main UI thread. Runnable task = new Runnable() { public void run() { initOnMainThread(context);
diff --git a/components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java b/components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java index 9381f0a..104b722 100644 --- a/components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java +++ b/components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java
@@ -466,15 +466,15 @@ private static int convertRequestPriority(int priority) { switch (priority) { - case REQUEST_PRIORITY_IDLE: + case Builder.REQUEST_PRIORITY_IDLE: return RequestPriority.IDLE; - case REQUEST_PRIORITY_LOWEST: + case Builder.REQUEST_PRIORITY_LOWEST: return RequestPriority.LOWEST; - case REQUEST_PRIORITY_LOW: + case Builder.REQUEST_PRIORITY_LOW: return RequestPriority.LOW; - case REQUEST_PRIORITY_MEDIUM: + case Builder.REQUEST_PRIORITY_MEDIUM: return RequestPriority.MEDIUM; - case REQUEST_PRIORITY_HIGHEST: + case Builder.REQUEST_PRIORITY_HIGHEST: return RequestPriority.HIGHEST; default: return RequestPriority.MEDIUM;
diff --git a/components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java index cd4b710..7cdabde2 100644 --- a/components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java +++ b/components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java
@@ -4,7 +4,6 @@ package org.chromium.net; -import android.content.Context; import android.os.Build; import android.os.ConditionVariable; import android.os.Handler; @@ -26,11 +25,11 @@ import javax.annotation.concurrent.GuardedBy; /** - * UrlRequestContext using Chromium HTTP stack implementation. + * CronetEngine using Chromium HTTP stack implementation. */ @JNINamespace("cronet") -@UsedByReflection("UrlRequestContext.java") -class CronetUrlRequestContext extends UrlRequestContext { +@UsedByReflection("CronetEngine.java") +class CronetUrlRequestContext extends CronetEngine { private static final int LOG_NONE = 3; // LOG(FATAL), no VLOG. private static final int LOG_DEBUG = -1; // LOG(FATAL...INFO), VLOG(1) private static final int LOG_VERBOSE = -2; // LOG(FATAL...INFO), VLOG(2) @@ -62,12 +61,11 @@ private final ObserverList<NetworkQualityThroughputListener> mThroughputListenerList = new ObserverList<NetworkQualityThroughputListener>(); - @UsedByReflection("UrlRequestContext.java") - public CronetUrlRequestContext(Context context, - UrlRequestContextConfig config) { - CronetLibraryLoader.ensureInitialized(context, config); + @UsedByReflection("CronetEngine.java") + public CronetUrlRequestContext(CronetEngine.Builder builder) { + CronetLibraryLoader.ensureInitialized(builder.getContext(), builder); nativeSetMinLogLevel(getLoggingLevel()); - mUrlRequestContextAdapter = nativeCreateRequestContextAdapter(config.toString()); + mUrlRequestContextAdapter = nativeCreateRequestContextAdapter(builder.toString()); if (mUrlRequestContextAdapter == 0) { throw new NullPointerException("Context Adapter creation failed."); } @@ -98,7 +96,7 @@ synchronized (mLock) { checkHaveAdapter(); return new CronetUrlRequest(this, mUrlRequestContextAdapter, url, - UrlRequest.REQUEST_PRIORITY_MEDIUM, listener, executor); + UrlRequest.Builder.REQUEST_PRIORITY_MEDIUM, listener, executor); } } @@ -282,7 +280,7 @@ private void checkHaveAdapter() throws IllegalStateException { if (!haveRequestContextAdapter()) { - throw new IllegalStateException("Context is shut down."); + throw new IllegalStateException("Engine is shut down."); } }
diff --git a/components/cronet/android/java/src/org/chromium/net/HttpUrlConnectionUrlRequestFactory.java b/components/cronet/android/java/src/org/chromium/net/HttpUrlConnectionUrlRequestFactory.java index ebefa6b..2bbcca1f 100644 --- a/components/cronet/android/java/src/org/chromium/net/HttpUrlConnectionUrlRequestFactory.java +++ b/components/cronet/android/java/src/org/chromium/net/HttpUrlConnectionUrlRequestFactory.java
@@ -13,7 +13,7 @@ /** * Network request using {@link java.net.HttpURLConnection}. - * @deprecated Use {@link UrlRequestContext} instead. + * @deprecated Use {@link CronetEngine} instead. */ @Deprecated class HttpUrlConnectionUrlRequestFactory extends HttpUrlRequestFactory { @@ -21,8 +21,7 @@ private final Context mContext; private final String mDefaultUserAgent; - public HttpUrlConnectionUrlRequestFactory( - Context context, UrlRequestContextConfig config) { + public HttpUrlConnectionUrlRequestFactory(Context context, CronetEngine.Builder config) { mContext = context; String userAgent = config.userAgent(); if (userAgent.isEmpty()) {
diff --git a/components/cronet/android/java/src/org/chromium/net/HttpUrlRequestFactory.java b/components/cronet/android/java/src/org/chromium/net/HttpUrlRequestFactory.java index fe84f5f..fd92f7e 100644 --- a/components/cronet/android/java/src/org/chromium/net/HttpUrlRequestFactory.java +++ b/components/cronet/android/java/src/org/chromium/net/HttpUrlRequestFactory.java
@@ -14,7 +14,7 @@ /** * A factory for {@link HttpUrlRequest}'s, which uses the best HTTP stack * available on the current platform. - * @deprecated Use {@link UrlRequestContext} instead. + * @deprecated Use {@link CronetEngine} instead. */ @Deprecated public abstract class HttpUrlRequestFactory { @@ -24,7 +24,7 @@ "org.chromium.net.ChromiumUrlRequestFactory"; public static HttpUrlRequestFactory createFactory( - Context context, UrlRequestContextConfig config) { + Context context, CronetEngine.Builder config) { HttpUrlRequestFactory factory = null; if (!config.legacyMode()) { factory = createChromiumFactory(context, config); @@ -80,7 +80,7 @@ public abstract void stopNetLog(); private static HttpUrlRequestFactory createChromiumFactory( - Context context, UrlRequestContextConfig config) { + Context context, CronetEngine.Builder config) { HttpUrlRequestFactory factory = null; try { Class<? extends HttpUrlRequestFactory> factoryClass = @@ -88,8 +88,7 @@ .loadClass(CHROMIUM_URL_REQUEST_FACTORY) .asSubclass(HttpUrlRequestFactory.class); Constructor<? extends HttpUrlRequestFactory> constructor = - factoryClass.getConstructor( - Context.class, UrlRequestContextConfig.class); + factoryClass.getConstructor(Context.class, CronetEngine.Builder.class); HttpUrlRequestFactory chromiumFactory = constructor.newInstance(context, config); if (chromiumFactory.isEnabled()) {
diff --git a/components/cronet/android/java/src/org/chromium/net/HttpUrlRequestFactoryConfig.java b/components/cronet/android/java/src/org/chromium/net/HttpUrlRequestFactoryConfig.java index 3da1c38..65434e4 100644 --- a/components/cronet/android/java/src/org/chromium/net/HttpUrlRequestFactoryConfig.java +++ b/components/cronet/android/java/src/org/chromium/net/HttpUrlRequestFactoryConfig.java
@@ -9,7 +9,7 @@ /** * A config for HttpUrlRequestFactory, which allows runtime configuration of * HttpUrlRequestFactory. - * @deprecated Use {@link UrlRequestContextConfig} instead. + * @deprecated Use {@link CronetEngine.Builder} instead. */ @Deprecated public class HttpUrlRequestFactoryConfig extends UrlRequestContextConfig {
diff --git a/components/cronet/android/java/src/org/chromium/net/UrlRequest.java b/components/cronet/android/java/src/org/chromium/net/UrlRequest.java index 6a784c30..714567b 100644 --- a/components/cronet/android/java/src/org/chromium/net/UrlRequest.java +++ b/components/cronet/android/java/src/org/chromium/net/UrlRequest.java
@@ -4,16 +4,215 @@ package org.chromium.net; +import android.util.Pair; + import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.concurrent.Executor; /** * Controls an HTTP request (GET, PUT, POST etc). - * Created using {@link UrlRequestContext#createRequest UrlRequestContext.createRequest()}. + * Created using {@link UrlRequest.Builder}. * Note: All methods must be called on the {@link Executor} passed in during creation. */ public interface UrlRequest { /** + * Builder for {@link UrlRequest}s. Allows configuring requests before constructing them + * with {@link Builder#build}. + */ + public static final class Builder { + // All fields are temporary storage of UrlRequest configuration to be + // copied to built UrlRequests. + + // CronetEngine to execute request. + final CronetEngine mCronetEngine; + // URL to request. + final String mUrl; + // Listener to receive progress callbacks. + final UrlRequestListener mListener; + // Executor to call listener on. + final Executor mExecutor; + // HTTP method (e.g. GET, POST etc). + String mMethod; + // List of request headers, stored as header field name and value pairs. + final ArrayList<Pair<String, String>> mRequestHeaders = + new ArrayList<Pair<String, String>>(); + // Disable the cache for just this request. + boolean mDisableCache; + // Priority of request. + int mPriority = REQUEST_PRIORITY_MEDIUM; + // If request is an upload, this provides the request body data. + UploadDataProvider mUploadDataProvider; + // Executor to call upload data provider back on. + Executor mUploadDataProviderExecutor; + + /** + * Creates a builder for {@link UrlRequest} objects. All callbacks for + * generated {@link UrlRequest} objects will be called on + * {@code executor}'s thread. {@code executor} must not run tasks on the + * current thread to prevent blocking networking operations and causing + * exceptions during shutdown. + * + * @param url {@link java.net.URL} for the generated requests. + * @param listener callback class that gets called on different events. + * @param executor {@link Executor} on which all callbacks will be called. + * @param cronetEngine {@link CronetEngine} used to execute this request. + */ + public Builder(String url, UrlRequestListener listener, Executor executor, + CronetEngine cronetEngine) { + if (url == null) { + throw new NullPointerException("URL is required."); + } + if (listener == null) { + throw new NullPointerException("Listener is required."); + } + if (executor == null) { + throw new NullPointerException("Executor is required."); + } + if (cronetEngine == null) { + throw new NullPointerException("CronetEngine is required."); + } + mUrl = url; + mListener = listener; + mExecutor = executor; + mCronetEngine = cronetEngine; + } + + /** + * Sets the HTTP method verb to use for this request. + * + * <p>The default when this method is not called is "GET" if the request has + * no body or "POST" if it does. + * + * @param method "GET", "HEAD", "DELETE", "POST" or "PUT". + * @return the builder to facilitate chaining. + */ + public Builder setHttpMethod(String method) { + if (method == null) { + throw new NullPointerException("Method is required."); + } + mMethod = method; + return this; + } + + /** + * Adds a request header. + * + * @param header header name. + * @param value header value. + * @return the builder to facilitate chaining. + */ + public Builder addHeader(String header, String value) { + if (header == null) { + throw new NullPointerException("Invalid header name."); + } + if (value == null) { + throw new NullPointerException("Invalid header value."); + } + mRequestHeaders.add(Pair.create(header, value)); + return this; + } + + /** + * Disables cache for the request. If context is not set up to use cache, + * this call has no effect. + * @return the builder to facilitate chaining. + */ + public Builder disableCache() { + mDisableCache = true; + return this; + } + + /** + * Lowest request priority. Passed to {@link #setPriority}. + */ + public static final int REQUEST_PRIORITY_IDLE = 0; + /** + * Very low request priority. Passed to {@link #setPriority}. + */ + public static final int REQUEST_PRIORITY_LOWEST = 1; + /** + * Low request priority. Passed to {@link #setPriority}. + */ + public static final int REQUEST_PRIORITY_LOW = 2; + /** + * Medium request priority. Passed to {@link #setPriority}. + */ + public static final int REQUEST_PRIORITY_MEDIUM = 3; + /** + * Highest request priority. Passed to {@link #setPriority}. + */ + public static final int REQUEST_PRIORITY_HIGHEST = 4; + + /** + * Sets priority of the request which should be one of the + * {@link #REQUEST_PRIORITY_IDLE REQUEST_PRIORITY_*} values. + * Defaults to {@link #REQUEST_PRIORITY_MEDIUM} + * + * @param priority priority of the request which should be one of the + * {@link #REQUEST_PRIORITY_IDLE REQUEST_PRIORITY_*} values. + * @return the builder to facilitate chaining. + */ + public Builder setPriority(int priority) { + mPriority = priority; + return this; + } + + /** + * Sets upload data provider. Switches method to "POST" if not + * explicitly set. Starting the request will throw an exception if a + * Content-Type header is not set. + * + * @param uploadDataProvider responsible for providing the upload data. + * @param executor All {@code uploadDataProvider} methods will be called + * using this {@code Executor}. May optionally be the same + * {@code Executor} the request itself is using. + * @return the builder to facilitate chaining. + */ + public Builder setUploadDataProvider( + UploadDataProvider uploadDataProvider, Executor executor) { + if (uploadDataProvider == null) { + throw new NullPointerException("Invalid UploadDataProvider."); + } + if (executor == null) { + throw new NullPointerException("Invalid UploadDataProvider Executor."); + } + if (mMethod == null) { + mMethod = "POST"; + } + mUploadDataProvider = uploadDataProvider; + mUploadDataProviderExecutor = executor; + return this; + } + + /** + * Creates a {@link UrlRequest} using configuration within this + * {@link Builder}. The returned {@code UrlRequest} can then be started + * by calling {@link UrlRequest#start}. + * + * @return constructed {@link UrlRequest} using configuration within + * this {@link Builder}. + */ + public UrlRequest build() { + final UrlRequest request = + mCronetEngine.createRequest(mUrl, mListener, mExecutor, mPriority); + if (mMethod != null) { + request.setHttpMethod(mMethod); + } + if (mDisableCache) { + request.disableCache(); + } + for (Pair<String, String> header : mRequestHeaders) { + request.addHeader(header.first, header.second); + } + if (mUploadDataProvider != null) { + request.setUploadDataProvider(mUploadDataProvider, mUploadDataProviderExecutor); + } + return request; + } + } + + /** * Request status values returned by {@link #getStatus}. */ public static class Status { @@ -196,36 +395,6 @@ } /** - * Lowest request priority. Passed to {@link UrlRequestContext#createRequest(String, - * UrlRequestListener, Executor, int) UrlRequestContext.createRequest()}. - */ - public static final int REQUEST_PRIORITY_IDLE = 0; - /** - * Very low request priority. Passed to {@link UrlRequestContext#createRequest(String, - * UrlRequestListener, Executor, int) UrlRequestContext.createRequest()}. - */ - public static final int REQUEST_PRIORITY_LOWEST = 1; - /** - * Low request priority. Passed to {@link UrlRequestContext#createRequest(String, - * UrlRequestListener, Executor, int) UrlRequestContext.createRequest()}. - */ - public static final int REQUEST_PRIORITY_LOW = 2; - /** - * Medium request priority. Passed to {@link UrlRequestContext#createRequest(String, - * UrlRequestListener, Executor, int) UrlRequestContext.createRequest()}. - */ - public static final int REQUEST_PRIORITY_MEDIUM = 3; - /** - * Highest request priority. Passed to {@link UrlRequestContext#createRequest(String, - * UrlRequestListener, Executor, int) UrlRequestContext.createRequest()}. - */ - public static final int REQUEST_PRIORITY_HIGHEST = 4; - - // More setters go here. They may only be called before start (Maybe - // also allow during redirects). Could optionally instead use arguments - // to URLRequestFactory when creating the request. - - /** * Sets the HTTP method verb to use for this request. Must be done before * request has started. * @@ -233,16 +402,18 @@ * no body or "POST" if it does. * * @param method "GET", "HEAD", "DELETE", "POST" or "PUT". + * @deprecated Use {@link Builder#setHttpMethod}. */ - public void setHttpMethod(String method); + @Deprecated public void setHttpMethod(String method); /** * Adds a request header. Must be done before request has started. * * @param header header name. * @param value header value. + * @deprecated Use {@link Builder#setPriority}. */ - public void addHeader(String header, String value); + @Deprecated public void addHeader(String header, String value); /** * Sets upload data provider. Must be done before request has started. May only be @@ -254,7 +425,9 @@ * @param executor All {@code uploadDataProvider} methods will be called * using this {@code Executor}. May optionally be the same * {@code Executor} the request itself is using. + * @deprecated Use {@link Builder#setUploadDataProvider}. */ + @Deprecated public void setUploadDataProvider(UploadDataProvider uploadDataProvider, Executor executor); /** @@ -346,8 +519,9 @@ /** * Disables cache for the request. If context is not set up to use cache, * this call has no effect. + * @deprecated Use {@link Builder#disableCache}. */ - public void disableCache(); + @Deprecated public void disableCache(); /** * Queries the status of the request.
diff --git a/components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java deleted file mode 100644 index 30ff080..0000000 --- a/components/cronet/android/java/src/org/chromium/net/UrlRequestContext.java +++ /dev/null
@@ -1,222 +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. - -package org.chromium.net; - -import android.content.Context; -import android.util.Log; - -import java.lang.reflect.Constructor; -import java.util.concurrent.Executor; - -/** - * A context for {@link UrlRequest}'s, which uses the best HTTP stack - * available on the current platform. - */ -public abstract class UrlRequestContext { - private static final String TAG = "UrlRequestFactory"; - private static final String CRONET_URL_REQUEST_CONTEXT = - "org.chromium.net.CronetUrlRequestContext"; - - /** - * Creates a {@link UrlRequest} object. All callbacks will - * be called on {@code executor}'s thread. {@code executor} must not run - * tasks on the current thread to prevent blocking networking operations - * and causing exceptions during shutdown. Request is given medium priority, - * see {@link UrlRequest#REQUEST_PRIORITY_MEDIUM}. To specify other - * priorities see {@link #createRequest(String, UrlRequestListener, - * Executor, int priority)}. - * - * @param url {@link java.net.URL} for the request. - * @param listener callback class that gets called on different events. - * @param executor {@link Executor} on which all callbacks will be called. - * @return new request. - */ - public abstract UrlRequest createRequest(String url, - UrlRequestListener listener, Executor executor); - - /** - * Creates a {@link UrlRequest} object. All callbacks will - * be called on {@code executor}'s thread. {@code executor} must not run - * tasks on the current thread to prevent blocking networking operations - * and causing exceptions during shutdown. - * - * @param url {@link java.net.URL} for the request. - * @param listener callback class that gets called on different events. - * @param executor {@link Executor} on which all callbacks will be called. - * @param priority priority of the request which should be one of the - * {@link UrlRequest#REQUEST_PRIORITY_IDLE REQUEST_PRIORITY_*} - * values. - * @return new request. - */ - public abstract UrlRequest createRequest(String url, - UrlRequestListener listener, Executor executor, int priority); - - /** - * @return {@code true} if the context is enabled. - */ - abstract boolean isEnabled(); - - /** - * @return a human-readable version string of the context. - */ - public abstract String getVersionString(); - - /** - * Shuts down the {@link UrlRequestContext} if there are no active requests, - * otherwise throws an exception. - * - * Cannot be called on network thread - the thread Cronet calls into - * Executor on (which is different from the thread the Executor invokes - * callbacks on). May block until all the {@code UrlRequestContext}'s - * resources have been cleaned up. - */ - public abstract void shutdown(); - - /** - * Starts NetLog logging to a file. The NetLog is useful for debugging. - * The file can be viewed using a Chrome browser navigated to - * chrome://net-internals/#import - * @param fileName the complete file path. It must not be empty. If the file - * exists, it is truncated before starting. If actively logging, - * this method is ignored. - * @param logAll {@code true} to include basic events, user cookies, - * credentials and all transferred bytes in the log. - * {@code false} to just include basic events. - */ - public abstract void startNetLogToFile(String fileName, boolean logAll); - - /** - * Stops NetLog logging and flushes file to disk. If a logging session is - * not in progress, this call is ignored. - */ - public abstract void stopNetLog(); - - /** - * Enables the network quality estimator, which collects and reports - * measurements of round trip time (RTT) and downstream throughput at - * various layers of the network stack. After enabling the estimator, - * listeners of RTT and throughput can be added with - * {@link #addRttListener} and {@link #addThroughputListener} and - * removed with {@link #removeRttListener} and - * {@link #removeThroughputListener}. The estimator uses memory and CPU - * only when enabled. - * @param executor an executor that will be used to notified all - * added RTT and throughput listeners. - * @deprecated not really deprecated but hidden for now as it's a prototype. - */ - @Deprecated public abstract void enableNetworkQualityEstimator(Executor executor); - - /** - * Enables the network quality estimator for testing. This must be called - * before round trip time and throughput listeners are added. Set both - * boolean parameters to false for default behavior. - * @param useLocalHostRequests include requests to localhost in estimates. - * @param useSmallerResponses include small responses in throughput estimates. - * @param executor an {@link java.util.concurrent.Executor} on which all - * listeners will be called. - * @deprecated not really deprecated but hidden for now as it's a prototype. - */ - @Deprecated - abstract void enableNetworkQualityEstimatorForTesting( - boolean useLocalHostRequests, boolean useSmallerResponses, Executor executor); - - /** - * Registers a listener that gets called whenever the network quality - * estimator witnesses a sample round trip time. This must be called - * after {@link #enableNetworkQualityEstimator}, and with throw an - * exception otherwise. Round trip times may be recorded at various layers - * of the network stack, including TCP, QUIC, and at the URL request layer. - * The listener is called on the {@link java.util.concurrent.Executor} that - * is passed to {@link #enableNetworkQualityEstimator}. - * @param listener the listener of round trip times. - * @deprecated not really deprecated but hidden for now as it's a prototype. - */ - @Deprecated public abstract void addRttListener(NetworkQualityRttListener listener); - - /** - * Removes a listener of round trip times if previously registered with - * {@link #addRttListener}. This should be called after a - * {@link NetworkQualityRttListener} is added in order to stop receiving - * observations. - * @param listener the listener of round trip times. - * @deprecated not really deprecated but hidden for now as it's a prototype. - */ - @Deprecated public abstract void removeRttListener(NetworkQualityRttListener listener); - - /** - * Registers a listener that gets called whenever the network quality - * estimator witnesses a sample throughput measurement. This must be called - * after {@link #enableNetworkQualityEstimator}. Throughput observations - * are computed by measuring bytes read over the active network interface - * at times when at least one URL response is being received. The listener - * is called on the {@link java.util.concurrent.Executor} that is passed to - * {@link #enableNetworkQualityEstimator}. - * @param listener the listener of throughput. - * @deprecated not really deprecated but hidden for now as it's a prototype. - */ - @Deprecated - public abstract void addThroughputListener(NetworkQualityThroughputListener listener); - - /** - * Removes a listener of throughput. This should be called after a - * {@link NetworkQualityThroughputListener} is added with - * {@link #addThroughputListener} in order to stop receiving observations. - * @param listener the listener of throughput. - * @deprecated not really deprecated but hidden for now as it's a prototype. - */ - @Deprecated - public abstract void removeThroughputListener(NetworkQualityThroughputListener listener); - - /** - * Creates a {@link UrlRequestContext} with the given - * {@link UrlRequestContextConfig}. - * @param context Android {@link Context}. - * @param config context configuration. - */ - public static UrlRequestContext createContext(Context context, - UrlRequestContextConfig config) { - UrlRequestContext urlRequestContext = null; - if (config.userAgent().isEmpty()) { - config.setUserAgent(UserAgent.from(context)); - } - if (!config.legacyMode()) { - urlRequestContext = createCronetContext(context, config); - } - if (urlRequestContext == null) { - // TODO(mef): Fallback to stub implementation. Once stub - // implementation is available merge with createCronetFactory. - urlRequestContext = createCronetContext(context, config); - } - Log.i(TAG, "Using network stack: " - + urlRequestContext.getVersionString()); - return urlRequestContext; - } - - private static UrlRequestContext createCronetContext(Context context, - UrlRequestContextConfig config) { - UrlRequestContext urlRequestContext = null; - try { - Class<? extends UrlRequestContext> contextClass = - UrlRequestContext.class.getClassLoader() - .loadClass(CRONET_URL_REQUEST_CONTEXT) - .asSubclass(UrlRequestContext.class); - Constructor<? extends UrlRequestContext> constructor = - contextClass.getConstructor( - Context.class, UrlRequestContextConfig.class); - UrlRequestContext cronetContext = - constructor.newInstance(context, config); - if (cronetContext.isEnabled()) { - urlRequestContext = cronetContext; - } - } catch (ClassNotFoundException e) { - // Leave as null. - } catch (Exception e) { - throw new IllegalStateException( - "Cannot instantiate: " + CRONET_URL_REQUEST_CONTEXT, - e); - } - return urlRequestContext; - } -}
diff --git a/components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java b/components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java index e240c5d..ff0c7779 100644 --- a/components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java +++ b/components/cronet/android/java/src/org/chromium/net/UrlRequestContextConfig.java
@@ -1,341 +1,26 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. +// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package org.chromium.net; -import org.json.JSONArray; import org.json.JSONException; -import org.json.JSONObject; - -import java.io.File; /** - * A config for UrlRequestContext, which allows runtime configuration of - * UrlRequestContext. + * A config for CronetEngine, which allows runtime configuration of + * CronetEngine. + * @deprecated use {@link CronetEngine.Builder} instead. */ -public class UrlRequestContextConfig { - private final JSONObject mConfig; - - /** - * Default config enables SPDY, disables QUIC, SDCH and http cache. - */ +public class UrlRequestContextConfig extends CronetEngine.Builder { public UrlRequestContextConfig() { - mConfig = new JSONObject(); - enableLegacyMode(false); - enableQUIC(false); - enableHTTP2(true); - enableSDCH(false); - enableHttpCache(HTTP_CACHE_DISABLED, 0); + // Context will be passed in later when the ChromiumUrlRequestFactory + // or ChromiumUrlRequestContext is created. + super(null); } - /** - * Creates a config from a JSON string, which was serialized using - * {@link #toString}. - */ public UrlRequestContextConfig(String json) throws JSONException { - mConfig = new JSONObject(json); - } - - /** - * Overrides the user-agent header for all requests. - * @return the config to facilitate chaining. - */ - public UrlRequestContextConfig setUserAgent(String userAgent) { - return putString(UrlRequestContextConfigList.USER_AGENT, userAgent); - } - - String userAgent() { - return mConfig.optString(UrlRequestContextConfigList.USER_AGENT); - } - - /** - * Sets directory for HTTP Cache and Cookie Storage. The directory must - * exist. - * @param value path to existing directory. - * @return the config to facilitate chaining. - */ - public UrlRequestContextConfig setStoragePath(String value) { - if (!new File(value).isDirectory()) { - throw new IllegalArgumentException( - "Storage path must be set to existing directory"); - } - - return putString(UrlRequestContextConfigList.STORAGE_PATH, value); - } - - String storagePath() { - return mConfig.optString(UrlRequestContextConfigList.STORAGE_PATH); - } - - /** - * Sets whether falling back to implementation based on system's - * {@link java.net.HttpURLConnection} implementation is enabled. - * Defaults to disabled. - * @return the config to facilitate chaining. - * @deprecated Not supported by the new API. - */ - @Deprecated - public UrlRequestContextConfig enableLegacyMode(boolean value) { - return putBoolean(UrlRequestContextConfigList.ENABLE_LEGACY_MODE, - value); - } - - boolean legacyMode() { - return mConfig.optBoolean( - UrlRequestContextConfigList.ENABLE_LEGACY_MODE); - } - - /** - * Overrides the name of the native library backing Cronet. - * @return the config to facilitate chaining. - */ - UrlRequestContextConfig setLibraryName(String libName) { - return putString(UrlRequestContextConfigList.NATIVE_LIBRARY_NAME, - libName); - } - - String libraryName() { - return mConfig.optString( - UrlRequestContextConfigList.NATIVE_LIBRARY_NAME, "cronet"); - } - - /** - * Sets whether <a href="https://www.chromium.org/quic">QUIC</a> protocol - * is enabled. Defaults to disabled. - * @return the config to facilitate chaining. - */ - public UrlRequestContextConfig enableQUIC(boolean value) { - return putBoolean(UrlRequestContextConfigList.ENABLE_QUIC, value); - } - - /** - * Sets whether <a href="https://tools.ietf.org/html/rfc7540">HTTP/2</a> - * protocol is enabled. Defaults to enabled. - * @return the config to facilitate chaining. - */ - public UrlRequestContextConfig enableHTTP2(boolean value) { - return putBoolean(UrlRequestContextConfigList.ENABLE_SPDY, value); - } - - /** - * Sets whether - * <a - * href="https://lists.w3.org/Archives/Public/ietf-http-wg/2008JulSep/att-0441/Shared_Dictionary_Compression_over_HTTP.pdf"> - * SDCH</a> compression is enabled. Defaults to disabled. - * @return the config to facilitate chaining. - */ - public UrlRequestContextConfig enableSDCH(boolean value) { - return putBoolean(UrlRequestContextConfigList.ENABLE_SDCH, value); - } - - /** - * Enables - * <a href="https://developer.chrome.com/multidevice/data-compression">Data - * Reduction Proxy</a>. Defaults to disabled. - * @param key key to use when authenticating with the proxy. - * @return the config to facilitate chaining. - */ - public UrlRequestContextConfig enableDataReductionProxy(String key) { - return (putString( - UrlRequestContextConfigList.DATA_REDUCTION_PROXY_KEY, key)); - } - - /** - * Overrides - * <a href="https://developer.chrome.com/multidevice/data-compression"> - * Data Reduction Proxy</a> configuration parameters with a primary - * proxy name, fallback proxy name, and a secure proxy check URL. Proxies - * are specified as [scheme://]host[:port]. Used for testing. - * @param primaryProxy the primary data reduction proxy to use. - * @param fallbackProxy a fallback data reduction proxy to use. - * @param secureProxyCheckUrl a URL to fetch to determine if using a secure - * proxy is allowed. - * @return the config to facilitate chaining. - * @hide - */ - public UrlRequestContextConfig setDataReductionProxyOptions( - String primaryProxy, - String fallbackProxy, - String secureProxyCheckUrl) { - if (primaryProxy.isEmpty() || fallbackProxy.isEmpty() - || secureProxyCheckUrl.isEmpty()) { - throw new IllegalArgumentException( - "Primary and fallback proxies and check url must be set"); - } - putString(UrlRequestContextConfigList.DATA_REDUCTION_PRIMARY_PROXY, - primaryProxy); - putString(UrlRequestContextConfigList.DATA_REDUCTION_FALLBACK_PROXY, - fallbackProxy); - putString(UrlRequestContextConfigList - .DATA_REDUCTION_SECURE_PROXY_CHECK_URL, secureProxyCheckUrl); - return this; - } - - /** - * Setting to disable HTTP cache. Some data may still be temporarily stored in memory. - * Passed to {@link #enableHttpCache}. - */ - public static final int HTTP_CACHE_DISABLED = 0; - - /** - * Setting to enable in-memory HTTP cache, including HTTP data. - * Passed to {@link #enableHttpCache}. - */ - public static final int HTTP_CACHE_IN_MEMORY = 1; - - /** - * Setting to enable on-disk cache, excluding HTTP data. - * {@link #setStoragePath} must be called prior to passing this constant to - * {@link #enableHttpCache}. - */ - public static final int HTTP_CACHE_DISK_NO_HTTP = 2; - - /** - * Setting to enable on-disk cache, including HTTP data. - * {@link #setStoragePath} must be called prior to passing this constant to - * {@link #enableHttpCache}. - */ - public static final int HTTP_CACHE_DISK = 3; - - /** - * Enables or disables caching of HTTP data and other information like QUIC - * server information. - * @param cacheMode control location and type of cached data. - * @param maxSize maximum size used to cache data (advisory and maybe - * exceeded at times). - * @return the config to facilitate chaining. - */ - public UrlRequestContextConfig enableHttpCache(int cacheMode, long maxSize) { - if (cacheMode == HTTP_CACHE_DISK || cacheMode == HTTP_CACHE_DISK_NO_HTTP) { - if (storagePath().isEmpty()) { - throw new IllegalArgumentException("Storage path must be set"); - } - } else { - if (!storagePath().isEmpty()) { - throw new IllegalArgumentException( - "Storage path must be empty"); - } - } - putBoolean(UrlRequestContextConfigList.LOAD_DISABLE_CACHE, - cacheMode == HTTP_CACHE_DISABLED || cacheMode == HTTP_CACHE_DISK_NO_HTTP); - putLong(UrlRequestContextConfigList.HTTP_CACHE_MAX_SIZE, maxSize); - - switch (cacheMode) { - case HTTP_CACHE_DISABLED: - return putString(UrlRequestContextConfigList.HTTP_CACHE, - UrlRequestContextConfigList.HTTP_CACHE_DISABLED); - case HTTP_CACHE_DISK_NO_HTTP: - case HTTP_CACHE_DISK: - return putString(UrlRequestContextConfigList.HTTP_CACHE, - UrlRequestContextConfigList.HTTP_CACHE_DISK); - - case HTTP_CACHE_IN_MEMORY: - return putString(UrlRequestContextConfigList.HTTP_CACHE, - UrlRequestContextConfigList.HTTP_CACHE_MEMORY); - } - return this; - } - - /** - * Adds hint that {@code host} supports QUIC. - * Note that {@link #enableHttpCache enableHttpCache} - * ({@link HttpCache#DISK DISK}) is needed to take advantage of 0-RTT - * connection establishment between sessions. - * - * @param host hostname of the server that supports QUIC. - * @param port host of the server that supports QUIC. - * @param alternatePort alternate port to use for QUIC. - * @return the config to facilitate chaining. - */ - public UrlRequestContextConfig addQuicHint(String host, - int port, - int alternatePort) { - if (host.contains("/")) { - throw new IllegalArgumentException("Illegal QUIC Hint Host: " - + host); - } - try { - JSONArray quicHints = mConfig.optJSONArray( - UrlRequestContextConfigList.QUIC_HINTS); - if (quicHints == null) { - quicHints = new JSONArray(); - mConfig.put(UrlRequestContextConfigList.QUIC_HINTS, quicHints); - } - - JSONObject hint = new JSONObject(); - hint.put(UrlRequestContextConfigList.QUIC_HINT_HOST, host); - hint.put(UrlRequestContextConfigList.QUIC_HINT_PORT, port); - hint.put(UrlRequestContextConfigList.QUIC_HINT_ALT_PORT, - alternatePort); - quicHints.put(hint); - } catch (JSONException e) { - // Intentionally do nothing. - } - return this; - } - - /** - * Sets experimental QUIC connection options, overwriting any pre-existing - * options. List of options is subject to change. - * - * @param quicConnectionOptions comma-separated QUIC options (for example - * "PACE,IW10") to use if QUIC is enabled. - * @return the config to facilitate chaining. - */ - public UrlRequestContextConfig setExperimentalQuicConnectionOptions( - String quicConnectionOptions) { - return putString(UrlRequestContextConfigList.QUIC_OPTIONS, - quicConnectionOptions); - } - - /** - * Get JSON string representation of the config. - */ - @Override - public String toString() { - return mConfig.toString(); - } - - /** - * Sets a boolean value in the config. Returns a reference to the same - * config object, so you can chain put calls together. - * @return the config to facilitate chaining. - */ - private UrlRequestContextConfig putBoolean(String key, boolean value) { - try { - mConfig.put(key, value); - } catch (JSONException e) { - // Intentionally do nothing. - } - return this; - } - - /** - * Sets a long value in the config. Returns a reference to the same - * config object, so you can chain put calls together. - * @return the config to facilitate chaining. - */ - private UrlRequestContextConfig putLong(String key, long value) { - try { - mConfig.put(key, value); - } catch (JSONException e) { - // Intentionally do nothing. - } - return this; - } - - /** - * Sets a string value in the config. Returns a reference to the same - * config object, so you can chain put calls together. - * @return the config to facilitate chaining. - */ - private UrlRequestContextConfig putString(String key, String value) { - try { - mConfig.put(key, value); - } catch (JSONException e) { - // Intentionally do nothing. - } - return this; + // Context will be passed in later when the ChromiumUrlRequestFactory + // or ChromiumUrlRequestContext is created. + super(null, json); } }
diff --git a/components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java b/components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java index 49d0a93a7..f3803f06 100644 --- a/components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java +++ b/components/cronet/android/java/src/org/chromium/net/UrlRequestListener.java
@@ -9,8 +9,8 @@ /** * Users of Cronet extend this class to receive callbacks indicating the * progress of a {@link UrlRequest} being processed. An instance of this class - * is passed in when the {@code UrlRequest} is created by - * {@link UrlRequestContext#createRequest} + * is passed in to {@link UrlRequest.Builder#UrlRequest.Builder UrlRequest.Builder()} + * when constructing the {@code UrlRequest}. * <p> * Note: All methods will be called on the thread of the * {@link java.util.concurrent.Executor} used during construction of the
diff --git a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetBufferedOutputStream.java b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetBufferedOutputStream.java index a7db527..e5a7090 100644 --- a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetBufferedOutputStream.java +++ b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetBufferedOutputStream.java
@@ -146,7 +146,8 @@ // TODO(xunjieli): Think of a less fragile way, since getLength() can be // potentially called in other places in the future. if (mInitialContentLength == -1) { - return mBuffer.position(); + // Account for the fact that setConnected() flip()s mBuffer. + return mConnected ? mBuffer.limit() : mBuffer.position(); } return mInitialContentLength; }
diff --git a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLConnection.java b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLConnection.java index 89bf7b690..8726e2a 100644 --- a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLConnection.java +++ b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLConnection.java
@@ -7,10 +7,10 @@ import android.util.Pair; import org.chromium.base.Log; +import org.chromium.net.CronetEngine; import org.chromium.net.ExtendedResponseInfo; import org.chromium.net.ResponseInfo; import org.chromium.net.UrlRequest; -import org.chromium.net.UrlRequestContext; import org.chromium.net.UrlRequestException; import org.chromium.net.UrlRequestListener; @@ -36,9 +36,9 @@ class CronetHttpURLConnection extends HttpURLConnection { private static final String TAG = "cr.CronetHttpURLConn"; private static final String CONTENT_LENGTH = "Content-Length"; - private final UrlRequestContext mUrlRequestContext; + private final CronetEngine mCronetEngine; private final MessageLoop mMessageLoop; - private final UrlRequest mRequest; + private UrlRequest mRequest; private final List<Pair<String, String>> mRequestHeaders; private CronetInputStream mInputStream; @@ -48,13 +48,10 @@ private boolean mOnRedirectCalled = false; private boolean mHasResponse = false; - public CronetHttpURLConnection(URL url, - UrlRequestContext urlRequestContext) { + public CronetHttpURLConnection(URL url, CronetEngine cronetEngine) { super(url); - mUrlRequestContext = urlRequestContext; + mCronetEngine = cronetEngine; mMessageLoop = new MessageLoop(); - mRequest = mUrlRequestContext.createRequest(url.toString(), - new CronetUrlRequestListener(), mMessageLoop); mInputStream = new CronetInputStream(this); mRequestHeaders = new ArrayList<Pair<String, String>>(); } @@ -255,9 +252,12 @@ if (connected) { return; } + final UrlRequest.Builder requestBuilder = new UrlRequest.Builder( + getURL().toString(), new CronetUrlRequestListener(), mMessageLoop, mCronetEngine); if (doOutput) { if (mOutputStream != null) { - mRequest.setUploadDataProvider(mOutputStream.getUploadDataProvider(), mMessageLoop); + requestBuilder.setUploadDataProvider( + mOutputStream.getUploadDataProvider(), mMessageLoop); if (getRequestProperty(CONTENT_LENGTH) == null && !isChunkedUpload()) { addRequestProperty(CONTENT_LENGTH, Long.toString(mOutputStream.getUploadDataProvider().getLength())); @@ -277,12 +277,13 @@ } } for (Pair<String, String> requestHeader : mRequestHeaders) { - mRequest.addHeader(requestHeader.first, requestHeader.second); + requestBuilder.addHeader(requestHeader.first, requestHeader.second); } if (!getUseCaches()) { - mRequest.disableCache(); + requestBuilder.disableCache(); } connected = true; + mRequest = requestBuilder.build(); // Start the request. mRequest.start(); }
diff --git a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLStreamHandler.java b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLStreamHandler.java index 952fc87a..c962e74 100644 --- a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLStreamHandler.java +++ b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLStreamHandler.java
@@ -4,7 +4,7 @@ package org.chromium.net.urlconnection; -import org.chromium.net.UrlRequestContext; +import org.chromium.net.CronetEngine; import java.io.IOException; import java.net.Proxy; @@ -23,10 +23,10 @@ * listed {@link CronetURLStreamHandlerFactory here}. */ public class CronetHttpURLStreamHandler extends URLStreamHandler { - private final UrlRequestContext mUrlRequestContext; + private final CronetEngine mCronetEngine; - public CronetHttpURLStreamHandler(UrlRequestContext urlRequestContext) { - mUrlRequestContext = urlRequestContext; + public CronetHttpURLStreamHandler(CronetEngine cronetEngine) { + mCronetEngine = cronetEngine; } /** @@ -37,7 +37,7 @@ public URLConnection openConnection(URL url) throws IOException { String protocol = url.getProtocol(); if ("http".equals(protocol) || "https".equals(protocol)) { - return new CronetHttpURLConnection(url, mUrlRequestContext); + return new CronetHttpURLConnection(url, mCronetEngine); } throw new UnsupportedOperationException( "Unexpected protocol:" + protocol);
diff --git a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetURLStreamHandlerFactory.java b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetURLStreamHandlerFactory.java index 2363a8f..aadcd7b 100644 --- a/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetURLStreamHandlerFactory.java +++ b/components/cronet/android/java/src/org/chromium/net/urlconnection/CronetURLStreamHandlerFactory.java
@@ -4,10 +4,7 @@ package org.chromium.net.urlconnection; -import android.content.Context; - -import org.chromium.net.UrlRequestContext; -import org.chromium.net.UrlRequestContextConfig; +import org.chromium.net.CronetEngine; import java.net.URLStreamHandler; import java.net.URLStreamHandlerFactory; @@ -42,21 +39,19 @@ */ public class CronetURLStreamHandlerFactory implements URLStreamHandlerFactory { - private final UrlRequestContext mRequestContext; + private final CronetEngine mCronetEngine; /** * Creates a {@link CronetURLStreamHandlerFactory} to handle HTTP and HTTPS * traffic. - * @param context application context. - * @param config the configuration to be used. + * @param cronetEngine the {@link CronetEngine} to be used. * @throws NullPointerException if config is null. */ - public CronetURLStreamHandlerFactory(Context context, - UrlRequestContextConfig config) { - if (config == null) { - throw new NullPointerException("UrlRequestContextConfig is null."); + public CronetURLStreamHandlerFactory(CronetEngine cronetEngine) { + if (cronetEngine == null) { + throw new NullPointerException("CronetEngine is null."); } - mRequestContext = UrlRequestContext.createContext(context, config); + mCronetEngine = cronetEngine; } /** @@ -66,7 +61,7 @@ @Override public URLStreamHandler createURLStreamHandler(String protocol) { if ("http".equals(protocol) || "https".equals(protocol)) { - return new CronetHttpURLStreamHandler(mRequestContext); + return new CronetHttpURLStreamHandler(mCronetEngine); } return null; }
diff --git a/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleActivity.java b/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleActivity.java index 6f450364c..2682771 100644 --- a/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleActivity.java +++ b/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleActivity.java
@@ -15,13 +15,12 @@ import android.widget.TextView; import org.chromium.base.Log; +import org.chromium.net.CronetEngine; import org.chromium.net.ExtendedResponseInfo; import org.chromium.net.ResponseInfo; import org.chromium.net.UploadDataProvider; import org.chromium.net.UploadDataSink; import org.chromium.net.UrlRequest; -import org.chromium.net.UrlRequestContext; -import org.chromium.net.UrlRequestContextConfig; import org.chromium.net.UrlRequestException; import org.chromium.net.UrlRequestListener; @@ -39,7 +38,7 @@ public class CronetSampleActivity extends Activity { private static final String TAG = "cr.CronetSample"; - private UrlRequestContext mRequestContext; + private CronetEngine mCronetEngine; private String mUrl; private boolean mLoading = false; @@ -157,12 +156,12 @@ mResultText = (TextView) findViewById(R.id.resultView); mReceiveDataText = (TextView) findViewById(R.id.dataView); - UrlRequestContextConfig myConfig = new UrlRequestContextConfig(); - myConfig.enableHttpCache(UrlRequestContextConfig.HTTP_CACHE_IN_MEMORY, 100 * 1024) + CronetEngine.Builder myBuilder = new CronetEngine.Builder(this); + myBuilder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024) .enableHTTP2(true) .enableQUIC(true); - mRequestContext = UrlRequestContext.createContext(this, myConfig); + mCronetEngine = myBuilder.build(); String appUrl = (getIntent() != null ? getIntent().getDataString() : null); if (appUrl == null) { @@ -193,13 +192,14 @@ alert.show(); } - private void applyPostDataToUrlRequest(UrlRequest request, Executor executor, String postData) { + private void applyPostDataToUrlRequestBuilder( + UrlRequest.Builder builder, Executor executor, String postData) { if (postData != null && postData.length() > 0) { UploadDataProvider uploadDataProvider = new SimpleUploadDataProvider(postData.getBytes()); - request.setHttpMethod("POST"); - request.addHeader("Content-Type", "application/x-www-form-urlencoded"); - request.setUploadDataProvider(uploadDataProvider, executor); + builder.setHttpMethod("POST"); + builder.addHeader("Content-Type", "application/x-www-form-urlencoded"); + builder.setUploadDataProvider(uploadDataProvider, executor); } } @@ -214,9 +214,9 @@ Executor executor = Executors.newSingleThreadExecutor(); UrlRequestListener listener = new SimpleUrlRequestListener(); - UrlRequest request = mRequestContext.createRequest(url, listener, executor); - applyPostDataToUrlRequest(request, executor, postData); - request.start(); + UrlRequest.Builder builder = new UrlRequest.Builder(url, listener, executor, mCronetEngine); + applyPostDataToUrlRequestBuilder(builder, executor, postData); + builder.build().start(); } /** @@ -241,12 +241,12 @@ } private void startNetLog() { - mRequestContext.startNetLogToFile( + mCronetEngine.startNetLogToFile( Environment.getExternalStorageDirectory().getPath() + "/cronet_sample_netlog.json", false); } private void stopNetLog() { - mRequestContext.stopNetLog(); + mCronetEngine.stopNetLog(); } }
diff --git a/components/cronet/android/test/javaperftests/src/org/chromium/net/CronetPerfTestActivity.java b/components/cronet/android/test/javaperftests/src/org/chromium/net/CronetPerfTestActivity.java index c9e1391..6d53f528 100644 --- a/components/cronet/android/test/javaperftests/src/org/chromium/net/CronetPerfTestActivity.java +++ b/components/cronet/android/test/javaperftests/src/org/chromium/net/CronetPerfTestActivity.java
@@ -111,7 +111,7 @@ private final Protocol mProtocol; private final URL mUrl; private final String mName; - private final UrlRequestContext mCronetContext; + private final CronetEngine mCronetEngine; // Size in bytes of content being uploaded or downloaded. private final int mLength; // How many requests to execute. @@ -178,13 +178,14 @@ throw new IllegalArgumentException("Bad URL: " + getConfigString("HOST") + ":" + port + "/" + resource); } - final UrlRequestContextConfig cronetConfig = new UrlRequestContextConfig(); + final CronetEngine.Builder cronetEngineBuilder = + new CronetEngine.Builder(CronetPerfTestActivity.this); if (mProtocol == Protocol.QUIC) { - cronetConfig.enableQUIC(true); - cronetConfig.addQuicHint(getConfigString("HOST"), getConfigInt("QUIC_PORT"), + cronetEngineBuilder.enableQUIC(true); + cronetEngineBuilder.addQuicHint(getConfigString("HOST"), getConfigInt("QUIC_PORT"), getConfigInt("QUIC_PORT")); } - mCronetContext = new CronetUrlRequestContext(CronetPerfTestActivity.this, cronetConfig); + mCronetEngine = cronetEngineBuilder.build(); mName = buildBenchmarkName(mode, direction, protocol, concurrency, mIterations); mConcurrency = concurrency; mResults = results; @@ -216,8 +217,8 @@ @SuppressLint("NewApi") private void startLogging() { if (getConfigBoolean("CAPTURE_NETLOG")) { - mCronetContext.startNetLogToFile(getFilesDir().getPath() + "/" + mName + ".json", - false); + mCronetEngine.startNetLogToFile( + getFilesDir().getPath() + "/" + mName + ".json", false); } if (getConfigBoolean("CAPTURE_TRACE")) { Debug.startMethodTracing(getFilesDir().getPath() + "/" + mName + ".trace"); @@ -229,7 +230,7 @@ private void stopLogging() { if (getConfigBoolean("CAPTURE_NETLOG")) { - mCronetContext.stopNetLog(); + mCronetEngine.stopNetLog(); } if (getConfigBoolean("CAPTURE_TRACE") || getConfigBoolean("CAPTURE_SAMPLED_TRACE")) { Debug.stopMethodTracing(); @@ -343,13 +344,14 @@ initiateRequest(buffer); } }; - final UrlRequest request = mCronetContext.createRequest(mUrl.toString(), - new Listener(buffer, completionCallback), mWorkQueueExecutor); + final UrlRequest.Builder builder = new UrlRequest.Builder(mUrl.toString(), + new Listener(buffer, completionCallback), mWorkQueueExecutor, + mCronetEngine); if (mDirection == Direction.UP) { - request.setUploadDataProvider(new Uploader(buffer), mWorkQueueExecutor); - request.addHeader("Content-Type", "application/octet-stream"); + builder.setUploadDataProvider(new Uploader(buffer), mWorkQueueExecutor); + builder.addHeader("Content-Type", "application/octet-stream"); } - request.start(); + builder.build().start(); } private class Uploader extends UploadDataProvider { @@ -479,7 +481,7 @@ break; case CRONET_HUC: { final CronetHttpURLStreamHandler cronetStreamHandler = - new CronetHttpURLStreamHandler(mCronetContext); + new CronetHttpURLStreamHandler(mCronetEngine); for (int i = 0; i < mIterations; i++) { tasks.add(new CronetHttpURLConnectionFetchTask(cronetStreamHandler)); }
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/ContextInitTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/ContextInitTest.java index 439ea512..c8e108f 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/ContextInitTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/ContextInitTest.java
@@ -138,11 +138,11 @@ // crashes like crbug.com/453845 final CronetTestActivity activity = launchCronetTestApp(); HttpUrlRequestFactory firstFactory = - HttpUrlRequestFactory.createFactory(activity, activity.getContextConfig()); + HttpUrlRequestFactory.createFactory(activity, activity.getCronetEngineBuilder()); HttpUrlRequestFactory secondFactory = HttpUrlRequestFactory.createFactory( - activity.getApplicationContext(), activity.getContextConfig()); + activity.getApplicationContext(), activity.getCronetEngineBuilder()); HttpUrlRequestFactory thirdFactory = HttpUrlRequestFactory.createFactory( - new ContextWrapper(activity), activity.getContextConfig()); + new ContextWrapper(activity), activity.getCronetEngineBuilder()); // Meager attempt to extend lifetimes to ensure they're concurrently // alive. firstFactory.getName();
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java index 395a8b1..f8c347ac 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
@@ -23,7 +23,7 @@ import java.util.concurrent.Executor; /** - * Test CronetUrlRequestContext. + * Test CronetEngine. */ public class CronetUrlRequestContextTest extends CronetTestBase { // URLs used for tests. @@ -53,11 +53,11 @@ @Override public void run() { mRunBlocker.block(); - UrlRequestContext requestContext = mActivity.initRequestContext(); + CronetEngine cronetEngine = mActivity.initCronetEngine(); mListener = new TestUrlRequestListener(); - UrlRequest urlRequest = - requestContext.createRequest(mUrl, mListener, mListener.getExecutor()); - urlRequest.start(); + UrlRequest.Builder urlRequestBuilder = + new UrlRequest.Builder(mUrl, mListener, mListener.getExecutor(), cronetEngine); + urlRequestBuilder.build().start(); mListener.blockForDone(); } } @@ -70,7 +70,7 @@ @Override public void onSucceeded(UrlRequest request, ExtendedResponseInfo info) { super.onSucceeded(request, info); - mActivity.mUrlRequestContext.shutdown(); + mActivity.mCronetEngine.shutdown(); } @Override @@ -78,7 +78,7 @@ ResponseInfo info, UrlRequestException error) { super.onFailed(request, info, error); - mActivity.mUrlRequestContext.shutdown(); + mActivity.mCronetEngine.shutdown(); } } @@ -127,21 +127,19 @@ public void testConfigUserAgent() throws Exception { String userAgentName = "User-Agent"; String userAgentValue = "User-Agent-Value"; - UrlRequestContextConfig config = new UrlRequestContextConfig(); - config.setUserAgent(userAgentValue); - config.setLibraryName("cronet_tests"); - String[] commandLineArgs = { - CronetTestActivity.CONFIG_KEY, config.toString() - }; + CronetEngine.Builder cronetEngineBuilder = new CronetEngine.Builder(mActivity); + cronetEngineBuilder.setUserAgent(userAgentValue); + cronetEngineBuilder.setLibraryName("cronet_tests"); + String[] commandLineArgs = {CronetTestActivity.CONFIG_KEY, cronetEngineBuilder.toString()}; mActivity = launchCronetTestAppWithUrlAndCommandLineArgs(TEST_URL, commandLineArgs); assertTrue(NativeTestServer.startNativeTestServer( getInstrumentation().getTargetContext())); TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoHeaderURL(userAgentName), listener, - listener.getExecutor()); - urlRequest.start(); + UrlRequest.Builder urlRequestBuilder = + new UrlRequest.Builder(NativeTestServer.getEchoHeaderURL(userAgentName), listener, + listener.getExecutor(), mActivity.mCronetEngine); + urlRequestBuilder.build().start(); listener.blockForDone(); assertEquals(userAgentValue, listener.mResponseAsString); } @@ -152,9 +150,9 @@ mActivity = launchCronetTestAppAndSkipFactoryInit(); // Ensure native code is loaded before trying to start test server. - UrlRequestContext.createContext( - getInstrumentation().getTargetContext(), - new UrlRequestContextConfig().setLibraryName("cronet_tests")) + new CronetEngine.Builder(getInstrumentation().getTargetContext()) + .setLibraryName("cronet_tests") + .build() .shutdown(); assertTrue(NativeTestServer.startNativeTestServer( @@ -167,23 +165,22 @@ // Enable the Data Reduction Proxy and configure it to use the test // server as its primary proxy, and to check successfully that this // proxy is OK to use. - UrlRequestContextConfig config = new UrlRequestContextConfig(); - config.enableDataReductionProxy("test-key"); - config.setDataReductionProxyOptions( - serverHostPort, "unused.net:9999", + CronetEngine.Builder cronetEngineBuilder = + new CronetEngine.Builder(getInstrumentation().getTargetContext()); + cronetEngineBuilder.enableDataReductionProxy("test-key"); + cronetEngineBuilder.setDataReductionProxyOptions(serverHostPort, "unused.net:9999", NativeTestServer.getFileURL("/secureproxychecksuccess.txt")); - config.setLibraryName("cronet_tests"); - mActivity.mUrlRequestContext = UrlRequestContext.createContext( - getInstrumentation().getTargetContext(), config); + cronetEngineBuilder.setLibraryName("cronet_tests"); + mActivity.mCronetEngine = cronetEngineBuilder.build(); TestUrlRequestListener listener = new TestUrlRequestListener(); // Construct and start a request that can only be returned by the test // server. This request will fail if the configuration logic for the // Data Reduction Proxy is not used. - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - "http://DomainThatDoesnt.Resolve/datareductionproxysuccess.txt", - listener, listener.getExecutor()); - urlRequest.start(); + UrlRequest.Builder urlRequestBuilder = new UrlRequest.Builder( + "http://DomainThatDoesnt.Resolve/datareductionproxysuccess.txt", listener, + listener.getExecutor(), mActivity.mCronetEngine); + urlRequestBuilder.build().start(); listener.blockForDone(); // Verify that the request is successful and that the Data Reduction @@ -201,23 +198,23 @@ mActivity = launchCronetTestApp(); TestNetworkQualityListener networkQualityListener = new TestNetworkQualityListener(); try { - mActivity.mUrlRequestContext.addRttListener(networkQualityListener); + mActivity.mCronetEngine.addRttListener(networkQualityListener); fail("Should throw an exception."); } catch (IllegalStateException e) { } try { - mActivity.mUrlRequestContext.addThroughputListener(networkQualityListener); + mActivity.mCronetEngine.addThroughputListener(networkQualityListener); fail("Should throw an exception."); } catch (IllegalStateException e) { } TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - TEST_URL, listener, listener.getExecutor()); + UrlRequest urlRequest = + mActivity.mCronetEngine.createRequest(TEST_URL, listener, listener.getExecutor()); urlRequest.start(); listener.blockForDone(); assertEquals(0, networkQualityListener.rttObservationCount()); assertEquals(0, networkQualityListener.throughputObservationCount()); - mActivity.mUrlRequestContext.shutdown(); + mActivity.mCronetEngine.shutdown(); } @SmallTest @@ -226,21 +223,20 @@ mActivity = launchCronetTestApp(); TestExecutor testExecutor = new TestExecutor(); TestNetworkQualityListener networkQualityListener = new TestNetworkQualityListener(); - mActivity.mUrlRequestContext.enableNetworkQualityEstimatorForTesting( - true, true, testExecutor); - mActivity.mUrlRequestContext.addRttListener(networkQualityListener); - mActivity.mUrlRequestContext.addThroughputListener(networkQualityListener); - mActivity.mUrlRequestContext.removeRttListener(networkQualityListener); - mActivity.mUrlRequestContext.removeThroughputListener(networkQualityListener); + mActivity.mCronetEngine.enableNetworkQualityEstimatorForTesting(true, true, testExecutor); + mActivity.mCronetEngine.addRttListener(networkQualityListener); + mActivity.mCronetEngine.addThroughputListener(networkQualityListener); + mActivity.mCronetEngine.removeRttListener(networkQualityListener); + mActivity.mCronetEngine.removeThroughputListener(networkQualityListener); TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - TEST_URL, listener, listener.getExecutor()); + UrlRequest urlRequest = + mActivity.mCronetEngine.createRequest(TEST_URL, listener, listener.getExecutor()); urlRequest.start(); listener.blockForDone(); testExecutor.runAllTasks(); assertEquals(0, networkQualityListener.rttObservationCount()); assertEquals(0, networkQualityListener.throughputObservationCount()); - mActivity.mUrlRequestContext.shutdown(); + mActivity.mCronetEngine.shutdown(); } @SmallTest @@ -249,19 +245,18 @@ mActivity = launchCronetTestApp(); TestExecutor testExecutor = new TestExecutor(); TestNetworkQualityListener networkQualityListener = new TestNetworkQualityListener(); - mActivity.mUrlRequestContext.enableNetworkQualityEstimatorForTesting( - true, true, testExecutor); - mActivity.mUrlRequestContext.addRttListener(networkQualityListener); - mActivity.mUrlRequestContext.addThroughputListener(networkQualityListener); + mActivity.mCronetEngine.enableNetworkQualityEstimatorForTesting(true, true, testExecutor); + mActivity.mCronetEngine.addRttListener(networkQualityListener); + mActivity.mCronetEngine.addThroughputListener(networkQualityListener); TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - TEST_URL, listener, listener.getExecutor()); + UrlRequest urlRequest = + mActivity.mCronetEngine.createRequest(TEST_URL, listener, listener.getExecutor()); urlRequest.start(); listener.blockForDone(); testExecutor.runAllTasks(); assertTrue(networkQualityListener.rttObservationCount() > 0); assertTrue(networkQualityListener.throughputObservationCount() > 0); - mActivity.mUrlRequestContext.shutdown(); + mActivity.mCronetEngine.shutdown(); } @SmallTest @@ -272,11 +267,12 @@ // Block listener when response starts to verify that shutdown fails // if there are active requests. listener.setAutoAdvance(false); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - TEST_URL, listener, listener.getExecutor()); + UrlRequest.Builder urlRequestBuilder = new UrlRequest.Builder( + TEST_URL, listener, listener.getExecutor(), mActivity.mCronetEngine); + UrlRequest urlRequest = urlRequestBuilder.build(); urlRequest.start(); try { - mActivity.mUrlRequestContext.shutdown(); + mActivity.mCronetEngine.shutdown(); fail("Should throw an exception"); } catch (Exception e) { assertEquals("Cannot shutdown with active requests.", @@ -286,7 +282,7 @@ listener.waitForNextStep(); assertEquals(ResponseStep.ON_RESPONSE_STARTED, listener.mResponseStep); try { - mActivity.mUrlRequestContext.shutdown(); + mActivity.mCronetEngine.shutdown(); fail("Should throw an exception"); } catch (Exception e) { assertEquals("Cannot shutdown with active requests.", @@ -297,7 +293,7 @@ listener.waitForNextStep(); assertEquals(ResponseStep.ON_READ_COMPLETED, listener.mResponseStep); try { - mActivity.mUrlRequestContext.shutdown(); + mActivity.mCronetEngine.shutdown(); fail("Should throw an exception"); } catch (Exception e) { assertEquals("Cannot shutdown with active requests.", @@ -335,18 +331,18 @@ // Create new request context, but its initialization on the main thread // will be stuck behind blockingTask. - final UrlRequestContext requestContext = activity.initRequestContext(); + final CronetEngine cronetEngine = activity.initCronetEngine(); // Unblock the main thread, so context gets initialized and shutdown on // it. block.open(); // Shutdown will wait for init to complete on main thread. - requestContext.shutdown(); + cronetEngine.shutdown(); // Verify that context is shutdown. try { - requestContext.stopNetLog(); + cronetEngine.stopNetLog(); fail("Should throw an exception."); } catch (Exception e) { - assertEquals("Context is shut down.", e.getMessage()); + assertEquals("Engine is shut down.", e.getMessage()); } } @@ -360,15 +356,15 @@ Runnable blockingTask = new Runnable() { public void run() { // Create new request context, loading the library. - final UrlRequestContext requestContext = activity.initRequestContext(); + final CronetEngine cronetEngine = activity.initCronetEngine(); // Shutdown right after init. - requestContext.shutdown(); + cronetEngine.shutdown(); // Verify that context is shutdown. try { - requestContext.stopNetLog(); + cronetEngine.stopNetLog(); fail("Should throw an exception."); } catch (Exception e) { - assertEquals("Context is shut down.", e.getMessage()); + assertEquals("Engine is shut down.", e.getMessage()); } block.open(); } @@ -383,12 +379,11 @@ public void testMultipleShutdown() throws Exception { mActivity = launchCronetTestApp(); try { - mActivity.mUrlRequestContext.shutdown(); - mActivity.mUrlRequestContext.shutdown(); + mActivity.mCronetEngine.shutdown(); + mActivity.mCronetEngine.shutdown(); fail("Should throw an exception"); } catch (Exception e) { - assertEquals("Context is shut down.", - e.getMessage()); + assertEquals("Engine is shut down.", e.getMessage()); } } @@ -397,9 +392,9 @@ public void testShutdownAfterError() throws Exception { mActivity = launchCronetTestApp(); TestUrlRequestListener listener = new ShutdownTestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - MOCK_CRONET_TEST_FAILED_URL, listener, listener.getExecutor()); - urlRequest.start(); + UrlRequest.Builder urlRequestBuilder = new UrlRequest.Builder(MOCK_CRONET_TEST_FAILED_URL, + listener, listener.getExecutor(), mActivity.mCronetEngine); + urlRequestBuilder.build().start(); listener.blockForDone(); assertTrue(listener.mOnErrorCalled); } @@ -412,11 +407,12 @@ // Block listener when response starts to verify that shutdown fails // if there are active requests. listener.setAutoAdvance(false); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - TEST_URL, listener, listener.getExecutor()); + UrlRequest.Builder urlRequestBuilder = new UrlRequest.Builder( + TEST_URL, listener, listener.getExecutor(), mActivity.mCronetEngine); + UrlRequest urlRequest = urlRequestBuilder.build(); urlRequest.start(); try { - mActivity.mUrlRequestContext.shutdown(); + mActivity.mCronetEngine.shutdown(); fail("Should throw an exception"); } catch (Exception e) { assertEquals("Cannot shutdown with active requests.", @@ -425,7 +421,7 @@ listener.waitForNextStep(); assertEquals(ResponseStep.ON_RESPONSE_STARTED, listener.mResponseStep); urlRequest.cancel(); - mActivity.mUrlRequestContext.shutdown(); + mActivity.mCronetEngine.shutdown(); } @SmallTest @@ -434,21 +430,20 @@ Context context = getInstrumentation().getTargetContext(); File directory = new File(PathUtils.getDataDirectory(context)); File file = File.createTempFile("cronet", "json", directory); - CronetUrlRequestContext requestContext = new CronetUrlRequestContext( - context, - new UrlRequestContextConfig().setLibraryName("cronet_tests")); + CronetEngine cronetEngine = new CronetUrlRequestContext( + new CronetEngine.Builder(context).setLibraryName("cronet_tests")); // Start NetLog immediately after the request context is created to make // sure that the call won't crash the app even when the native request // context is not fully initialized. See crbug.com/470196. - requestContext.startNetLogToFile(file.getPath(), false); + cronetEngine.startNetLogToFile(file.getPath(), false); // Start a request. TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest request = requestContext.createRequest( - TEST_URL, listener, listener.getExecutor()); - request.start(); + UrlRequest.Builder urlRequestBuilder = + new UrlRequest.Builder(TEST_URL, listener, listener.getExecutor(), cronetEngine); + urlRequestBuilder.build().start(); listener.blockForDone(); - requestContext.stopNetLog(); + cronetEngine.stopNetLog(); assertTrue(file.exists()); assertTrue(file.length() != 0); assertFalse(hasBytesInNetLog(file)); @@ -461,21 +456,20 @@ public void testNetLogAfterShutdown() throws Exception { mActivity = launchCronetTestApp(); TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - TEST_URL, listener, listener.getExecutor()); - urlRequest.start(); + UrlRequest.Builder urlRequestBuilder = new UrlRequest.Builder( + TEST_URL, listener, listener.getExecutor(), mActivity.mCronetEngine); + urlRequestBuilder.build().start(); listener.blockForDone(); - mActivity.mUrlRequestContext.shutdown(); + mActivity.mCronetEngine.shutdown(); File directory = new File(PathUtils.getDataDirectory( getInstrumentation().getTargetContext())); File file = File.createTempFile("cronet", "json", directory); try { - mActivity.mUrlRequestContext.startNetLogToFile(file.getPath(), - false); + mActivity.mCronetEngine.startNetLogToFile(file.getPath(), false); fail("Should throw an exception."); } catch (Exception e) { - assertEquals("Context is shut down.", e.getMessage()); + assertEquals("Engine is shut down.", e.getMessage()); } assertFalse(hasBytesInNetLog(file)); assertTrue(file.delete()); @@ -490,17 +484,17 @@ getInstrumentation().getTargetContext())); File file = File.createTempFile("cronet", "json", directory); // Start NetLog multiple times. - mActivity.mUrlRequestContext.startNetLogToFile(file.getPath(), false); - mActivity.mUrlRequestContext.startNetLogToFile(file.getPath(), false); - mActivity.mUrlRequestContext.startNetLogToFile(file.getPath(), false); - mActivity.mUrlRequestContext.startNetLogToFile(file.getPath(), false); + mActivity.mCronetEngine.startNetLogToFile(file.getPath(), false); + mActivity.mCronetEngine.startNetLogToFile(file.getPath(), false); + mActivity.mCronetEngine.startNetLogToFile(file.getPath(), false); + mActivity.mCronetEngine.startNetLogToFile(file.getPath(), false); // Start a request. TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - TEST_URL, listener, listener.getExecutor()); - urlRequest.start(); + UrlRequest.Builder urlRequestBuilder = new UrlRequest.Builder( + TEST_URL, listener, listener.getExecutor(), mActivity.mCronetEngine); + urlRequestBuilder.build().start(); listener.blockForDone(); - mActivity.mUrlRequestContext.stopNetLog(); + mActivity.mCronetEngine.stopNetLog(); assertTrue(file.exists()); assertTrue(file.length() != 0); assertFalse(hasBytesInNetLog(file)); @@ -515,19 +509,19 @@ File directory = new File(PathUtils.getDataDirectory( getInstrumentation().getTargetContext())); File file = File.createTempFile("cronet", "json", directory); - mActivity.mUrlRequestContext.startNetLogToFile(file.getPath(), false); + mActivity.mCronetEngine.startNetLogToFile(file.getPath(), false); // Start a request. TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - TEST_URL, listener, listener.getExecutor()); - urlRequest.start(); + UrlRequest.Builder urlRequestBuilder = new UrlRequest.Builder( + TEST_URL, listener, listener.getExecutor(), mActivity.mCronetEngine); + urlRequestBuilder.build().start(); listener.blockForDone(); // Stop NetLog multiple times. - mActivity.mUrlRequestContext.stopNetLog(); - mActivity.mUrlRequestContext.stopNetLog(); - mActivity.mUrlRequestContext.stopNetLog(); - mActivity.mUrlRequestContext.stopNetLog(); - mActivity.mUrlRequestContext.stopNetLog(); + mActivity.mCronetEngine.stopNetLog(); + mActivity.mCronetEngine.stopNetLog(); + mActivity.mCronetEngine.stopNetLog(); + mActivity.mCronetEngine.stopNetLog(); + mActivity.mCronetEngine.stopNetLog(); assertTrue(file.exists()); assertTrue(file.length() != 0); assertFalse(hasBytesInNetLog(file)); @@ -541,18 +535,17 @@ Context context = getInstrumentation().getTargetContext(); File directory = new File(PathUtils.getDataDirectory(context)); File file = File.createTempFile("cronet", "json", directory); - CronetUrlRequestContext requestContext = new CronetUrlRequestContext( - context, - new UrlRequestContextConfig().setLibraryName("cronet_tests")); + CronetEngine cronetEngine = new CronetUrlRequestContext( + new CronetEngine.Builder(context).setLibraryName("cronet_tests")); // Start NetLog with logAll as true. - requestContext.startNetLogToFile(file.getPath(), true); + cronetEngine.startNetLogToFile(file.getPath(), true); // Start a request. TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest request = requestContext.createRequest( - TEST_URL, listener, listener.getExecutor()); - request.start(); + UrlRequest.Builder urlRequestBuilder = + new UrlRequest.Builder(TEST_URL, listener, listener.getExecutor(), cronetEngine); + urlRequestBuilder.build().start(); listener.blockForDone(); - requestContext.stopNetLog(); + cronetEngine.stopNetLog(); assertTrue(file.exists()); assertTrue(file.length() != 0); assertTrue(hasBytesInNetLog(file)); @@ -577,11 +570,11 @@ private void enableCache(int cacheType) throws Exception { String cacheTypeString = ""; - if (cacheType == UrlRequestContextConfig.HTTP_CACHE_DISK) { + if (cacheType == CronetEngine.Builder.HTTP_CACHE_DISK) { cacheTypeString = CronetTestActivity.CACHE_DISK; - } else if (cacheType == UrlRequestContextConfig.HTTP_CACHE_DISK_NO_HTTP) { + } else if (cacheType == CronetEngine.Builder.HTTP_CACHE_DISK_NO_HTTP) { cacheTypeString = CronetTestActivity.CACHE_DISK_NO_HTTP; - } else if (cacheType == UrlRequestContextConfig.HTTP_CACHE_IN_MEMORY) { + } else if (cacheType == CronetEngine.Builder.HTTP_CACHE_IN_MEMORY) { cacheTypeString = CronetTestActivity.CACHE_IN_MEMORY; } String[] commandLineArgs = {CronetTestActivity.CACHE_KEY, cacheTypeString}; @@ -598,12 +591,12 @@ private void checkRequestCaching(String url, boolean expectCached, boolean disableCache) { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - url, listener, listener.getExecutor()); + UrlRequest.Builder urlRequestBuilder = new UrlRequest.Builder( + url, listener, listener.getExecutor(), mActivity.mCronetEngine); if (disableCache) { - urlRequest.disableCache(); + urlRequestBuilder.disableCache(); } - urlRequest.start(); + urlRequestBuilder.build().start(); listener.blockForDone(); assertEquals(expectCached, listener.mResponseInfo.wasCached()); } @@ -611,7 +604,7 @@ @SmallTest @Feature({"Cronet"}) public void testEnableHttpCacheDisabled() throws Exception { - enableCache(UrlRequestContextConfig.HTTP_CACHE_DISABLED); + enableCache(CronetEngine.Builder.HTTP_CACHE_DISABLED); String url = NativeTestServer.getFileURL("/cacheable.txt"); checkRequestCaching(url, false); checkRequestCaching(url, false); @@ -621,7 +614,7 @@ @SmallTest @Feature({"Cronet"}) public void testEnableHttpCacheInMemory() throws Exception { - enableCache(UrlRequestContextConfig.HTTP_CACHE_IN_MEMORY); + enableCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY); String url = NativeTestServer.getFileURL("/cacheable.txt"); checkRequestCaching(url, false); checkRequestCaching(url, true); @@ -632,7 +625,7 @@ @SmallTest @Feature({"Cronet"}) public void testEnableHttpCacheDisk() throws Exception { - enableCache(UrlRequestContextConfig.HTTP_CACHE_DISK); + enableCache(CronetEngine.Builder.HTTP_CACHE_DISK); String url = NativeTestServer.getFileURL("/cacheable.txt"); checkRequestCaching(url, false); checkRequestCaching(url, true); @@ -643,7 +636,7 @@ @SmallTest @Feature({"Cronet"}) public void testEnableHttpCacheDiskNoHttp() throws Exception { - enableCache(UrlRequestContextConfig.HTTP_CACHE_DISABLED); + enableCache(CronetEngine.Builder.HTTP_CACHE_DISABLED); String url = NativeTestServer.getFileURL("/cacheable.txt"); checkRequestCaching(url, false); checkRequestCaching(url, false); @@ -653,7 +646,7 @@ @SmallTest @Feature({"Cronet"}) public void testDisableCache() throws Exception { - enableCache(UrlRequestContextConfig.HTTP_CACHE_DISK); + enableCache(CronetEngine.Builder.HTTP_CACHE_DISK); String url = NativeTestServer.getFileURL("/cacheable.txt"); // When cache is disabled, making a request does not write to the cache. @@ -670,10 +663,10 @@ // Cache is disabled after server is shut down, request should fail. TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - url, listener, listener.getExecutor()); - urlRequest.disableCache(); - urlRequest.start(); + UrlRequest.Builder urlRequestBuilder = new UrlRequest.Builder( + url, listener, listener.getExecutor(), mActivity.mCronetEngine); + urlRequestBuilder.disableCache(); + urlRequestBuilder.build().start(); listener.blockForDone(); assertNotNull(listener.mError); assertEquals("Exception in CronetUrlRequest: net::ERR_CONNECTION_REFUSED", @@ -682,8 +675,8 @@ @SmallTest @Feature({"Cronet"}) - public void testEnableHttpCacheDiskNewContext() throws Exception { - enableCache(UrlRequestContextConfig.HTTP_CACHE_DISK); + public void testEnableHttpCacheDiskNewEngine() throws Exception { + enableCache(CronetEngine.Builder.HTTP_CACHE_DISK); String url = NativeTestServer.getFileURL("/cacheable.txt"); checkRequestCaching(url, false); checkRequestCaching(url, true); @@ -691,41 +684,40 @@ checkRequestCaching(url, true); // Shutdown original context and create another that uses the same cache. - mActivity.mUrlRequestContext.shutdown(); - mActivity.mUrlRequestContext = UrlRequestContext.createContext( - getInstrumentation().getTargetContext(), mActivity.getContextConfig()); + mActivity.mCronetEngine.shutdown(); + mActivity.mCronetEngine = mActivity.getCronetEngineBuilder().build(); checkRequestCaching(url, true); } @SmallTest @Feature({"Cronet"}) - public void testInitContextAndStartRequest() { + public void testInitEngineAndStartRequest() { CronetTestActivity activity = launchCronetTestAppAndSkipFactoryInit(); - // Immediately make a request after initializing the context. - UrlRequestContext requestContext = activity.initRequestContext(); + // Immediately make a request after initializing the engine. + CronetEngine cronetEngine = activity.initCronetEngine(); TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = - requestContext.createRequest(TEST_URL, listener, listener.getExecutor()); - urlRequest.start(); + UrlRequest.Builder urlRequestBuilder = + new UrlRequest.Builder(TEST_URL, listener, listener.getExecutor(), cronetEngine); + urlRequestBuilder.build().start(); listener.blockForDone(); assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); } @SmallTest @Feature({"Cronet"}) - public void testInitContextStartTwoRequests() throws Exception { + public void testInitEngineStartTwoRequests() throws Exception { CronetTestActivity activity = launchCronetTestAppAndSkipFactoryInit(); // Make two requests after initializing the context. - UrlRequestContext requestContext = activity.initRequestContext(); + CronetEngine cronetEngine = activity.initCronetEngine(); int[] statusCodes = {0, 0}; String[] urls = {TEST_URL, URL_404}; for (int i = 0; i < 2; i++) { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = - requestContext.createRequest(urls[i], listener, listener.getExecutor()); - urlRequest.start(); + UrlRequest.Builder urlRequestBuilder = + new UrlRequest.Builder(urls[i], listener, listener.getExecutor(), cronetEngine); + urlRequestBuilder.build().start(); listener.blockForDone(); statusCodes[i] = listener.mResponseInfo.getHttpStatusCode(); } @@ -735,7 +727,7 @@ @SmallTest @Feature({"Cronet"}) - public void testInitTwoContextsSimultaneously() throws Exception { + public void testInitTwoEnginesSimultaneously() throws Exception { final CronetTestActivity activity = launchCronetTestAppAndSkipFactoryInit(); // Threads will block on runBlocker to ensure simultaneous execution. @@ -754,7 +746,7 @@ @SmallTest @Feature({"Cronet"}) - public void testInitTwoContextsInSequence() throws Exception { + public void testInitTwoEnginesInSequence() throws Exception { final CronetTestActivity activity = launchCronetTestAppAndSkipFactoryInit(); ConditionVariable runBlocker = new ConditionVariable(true); @@ -771,19 +763,19 @@ @SmallTest @Feature({"Cronet"}) - public void testInitDifferentContexts() throws Exception { + public void testInitDifferentEngines() throws Exception { // Test that concurrently instantiating Cronet context's upon various // different versions of the same Android Context does not cause crashes // like crbug.com/453845 mActivity = launchCronetTestApp(); - CronetUrlRequestContext firstContext = - new CronetUrlRequestContext(mActivity, mActivity.getContextConfig()); - CronetUrlRequestContext secondContext = new CronetUrlRequestContext( - mActivity.getApplicationContext(), mActivity.getContextConfig()); - CronetUrlRequestContext thirdContext = new CronetUrlRequestContext( - new ContextWrapper(mActivity), mActivity.getContextConfig()); - firstContext.shutdown(); - secondContext.shutdown(); - thirdContext.shutdown(); + CronetEngine firstEngine = + new CronetUrlRequestContext(mActivity.createCronetEngineBuilder(mActivity)); + CronetEngine secondEngine = new CronetUrlRequestContext( + mActivity.createCronetEngineBuilder(mActivity.getApplicationContext())); + CronetEngine thirdEngine = new CronetUrlRequestContext( + mActivity.createCronetEngineBuilder(new ContextWrapper(mActivity))); + firstEngine.shutdown(); + secondEngine.shutdown(); + thirdEngine.shutdown(); } }
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java index 6eae9ae..8c33d76 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java
@@ -44,7 +44,7 @@ @Override protected void tearDown() throws Exception { NativeTestServer.shutdownNativeTestServer(); - mActivity.mUrlRequestContext.shutdown(); + mActivity.mCronetEngine.shutdown(); super.tearDown(); } @@ -52,8 +52,9 @@ throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); // Create request. - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - url, listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder( + url, listener, listener.getExecutor(), mActivity.mCronetEngine); + UrlRequest urlRequest = builder.build(); urlRequest.start(); listener.blockForDone(); assertTrue(urlRequest.isDone()); @@ -82,6 +83,42 @@ @SmallTest @Feature({"Cronet"}) + public void testBuilderChecks() throws Exception { + TestUrlRequestListener listener = new TestUrlRequestListener(); + try { + new UrlRequest.Builder(null, listener, listener.getExecutor(), mActivity.mCronetEngine); + fail("URL not null-checked"); + } catch (NullPointerException e) { + assertEquals("URL is required.", e.getMessage()); + } + try { + new UrlRequest.Builder(NativeTestServer.getRedirectURL(), null, listener.getExecutor(), + mActivity.mCronetEngine); + fail("Listener not null-checked"); + } catch (NullPointerException e) { + assertEquals("Listener is required.", e.getMessage()); + } + try { + new UrlRequest.Builder( + NativeTestServer.getRedirectURL(), listener, null, mActivity.mCronetEngine); + fail("Executor not null-checked"); + } catch (NullPointerException e) { + assertEquals("Executor is required.", e.getMessage()); + } + try { + new UrlRequest.Builder( + NativeTestServer.getRedirectURL(), listener, listener.getExecutor(), null); + fail("CronetEngine not null-checked"); + } catch (NullPointerException e) { + assertEquals("CronetEngine is required.", e.getMessage()); + } + // Verify successful creation doesn't throw. + new UrlRequest.Builder(NativeTestServer.getRedirectURL(), listener, listener.getExecutor(), + mActivity.mCronetEngine); + } + + @SmallTest + @Feature({"Cronet"}) public void testSimpleGet() throws Exception { TestUrlRequestListener listener = startAndWaitForComplete( NativeTestServer.getEchoMethodURL()); @@ -107,8 +144,9 @@ // Start the request and wait to see the redirect. TestUrlRequestListener listener = new TestUrlRequestListener(); listener.setAutoAdvance(false); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getRedirectURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getRedirectURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); + UrlRequest urlRequest = builder.build(); urlRequest.start(); listener.waitForNextStep(); @@ -217,25 +255,18 @@ public void testSetHttpMethod() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); String methodName = "HEAD"; - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoMethodURL(), listener, - listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoMethodURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); // Try to set 'null' method. try { - urlRequest.setHttpMethod(null); + builder.setHttpMethod(null); fail("Exception not thrown"); } catch (NullPointerException e) { assertEquals("Method is required.", e.getMessage()); } - urlRequest.setHttpMethod(methodName); - urlRequest.start(); - try { - urlRequest.setHttpMethod("toolate"); - fail("Exception not thrown"); - } catch (IllegalStateException e) { - assertEquals("Request is already started.", e.getMessage()); - } + builder.setHttpMethod(methodName); + builder.build().start(); listener.blockForDone(); assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); assertEquals(0, listener.mHttpResponseDataLength); @@ -245,11 +276,11 @@ @Feature({"Cronet"}) public void testBadMethod() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - TEST_URL, listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder( + TEST_URL, listener, listener.getExecutor(), mActivity.mCronetEngine); try { - urlRequest.setHttpMethod("bad:method!"); - urlRequest.start(); + builder.setHttpMethod("bad:method!"); + builder.build().start(); fail("IllegalArgumentException not thrown."); } catch (IllegalArgumentException e) { assertEquals("Invalid http method bad:method!", @@ -261,11 +292,11 @@ @Feature({"Cronet"}) public void testBadHeaderName() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - TEST_URL, listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder( + TEST_URL, listener, listener.getExecutor(), mActivity.mCronetEngine); try { - urlRequest.addHeader("header:name", "headervalue"); - urlRequest.start(); + builder.addHeader("header:name", "headervalue"); + builder.build().start(); fail("IllegalArgumentException not thrown."); } catch (IllegalArgumentException e) { assertEquals("Invalid header header:name=headervalue", @@ -277,11 +308,11 @@ @Feature({"Cronet"}) public void testBadHeaderValue() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - TEST_URL, listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder( + TEST_URL, listener, listener.getExecutor(), mActivity.mCronetEngine); try { - urlRequest.addHeader("headername", "bad header\r\nvalue"); - urlRequest.start(); + builder.addHeader("headername", "bad header\r\nvalue"); + builder.build().start(); fail("IllegalArgumentException not thrown."); } catch (IllegalArgumentException e) { assertEquals("Invalid header headername=bad header\r\nvalue", @@ -295,18 +326,12 @@ TestUrlRequestListener listener = new TestUrlRequestListener(); String headerName = "header-name"; String headerValue = "header-value"; - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoHeaderURL(headerName), listener, - listener.getExecutor()); + UrlRequest.Builder builder = + new UrlRequest.Builder(NativeTestServer.getEchoHeaderURL(headerName), listener, + listener.getExecutor(), mActivity.mCronetEngine); - urlRequest.addHeader(headerName, headerValue); - urlRequest.start(); - try { - urlRequest.addHeader("header2", "value"); - fail("Exception not thrown"); - } catch (IllegalStateException e) { - assertEquals("Request is already started.", e.getMessage()); - } + builder.addHeader(headerName, headerValue); + builder.build().start(); listener.blockForDone(); assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); assertEquals(headerValue, listener.mResponseAsString); @@ -319,12 +344,11 @@ String headerName = "header-name"; String headerValue1 = "header-value1"; String headerValue2 = "header-value2"; - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoAllHeadersURL(), listener, - listener.getExecutor()); - urlRequest.addHeader(headerName, headerValue1); - urlRequest.addHeader(headerName, headerValue2); - urlRequest.start(); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoAllHeadersURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); + builder.addHeader(headerName, headerValue1); + builder.addHeader(headerName, headerValue2); + builder.build().start(); listener.blockForDone(); assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); String headers = listener.mResponseAsString; @@ -344,11 +368,11 @@ TestUrlRequestListener listener = new TestUrlRequestListener(); String userAgentName = "User-Agent"; String userAgentValue = "User-Agent-Value"; - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoHeaderURL(userAgentName), listener, - listener.getExecutor()); - urlRequest.addHeader(userAgentName, userAgentValue); - urlRequest.start(); + UrlRequest.Builder builder = + new UrlRequest.Builder(NativeTestServer.getEchoHeaderURL(userAgentName), listener, + listener.getExecutor(), mActivity.mCronetEngine); + builder.addHeader(userAgentName, userAgentValue); + builder.build().start(); listener.blockForDone(); assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); assertEquals(userAgentValue, listener.mResponseAsString); @@ -359,10 +383,10 @@ public void testDefaultUserAgent() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); String headerName = "User-Agent"; - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoHeaderURL(headerName), listener, - listener.getExecutor()); - urlRequest.start(); + UrlRequest.Builder builder = + new UrlRequest.Builder(NativeTestServer.getEchoHeaderURL(headerName), listener, + listener.getExecutor(), mActivity.mCronetEngine); + builder.build().start(); listener.blockForDone(); assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); assertTrue("Default User-Agent should contain Cronet/n.n.n.n but is " @@ -540,9 +564,9 @@ listener.setAutoAdvance(false); // Since the default method is "GET", the expected response body is also // "GET". - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoMethodURL(), - listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoMethodURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); + UrlRequest urlRequest = builder.build(); urlRequest.start(); listener.waitForNextStep(); @@ -627,8 +651,9 @@ listener.setAutoAdvance(false); // Since the default method is "GET", the expected response body is also // "GET". - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoMethodURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoMethodURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); + UrlRequest urlRequest = builder.build(); urlRequest.start(); listener.waitForNextStep(); @@ -708,9 +733,9 @@ public void testBadBuffers() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); listener.setAutoAdvance(false); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoMethodURL(), listener, - listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoMethodURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); + UrlRequest urlRequest = builder.build(); urlRequest.start(); listener.waitForNextStep(); @@ -749,8 +774,10 @@ public void testUnexpectedReads() throws Exception { final TestUrlRequestListener listener = new TestUrlRequestListener(); listener.setAutoAdvance(false); - final UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getRedirectURL(), listener, listener.getExecutor()); + final UrlRequest urlRequest = + new UrlRequest.Builder(NativeTestServer.getRedirectURL(), listener, + listener.getExecutor(), mActivity.mCronetEngine) + .build(); // Try to read before starting request. try { @@ -832,8 +859,10 @@ public void testUnexpectedFollowRedirects() throws Exception { final TestUrlRequestListener listener = new TestUrlRequestListener(); listener.setAutoAdvance(false); - final UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getRedirectURL(), listener, listener.getExecutor()); + final UrlRequest urlRequest = + new UrlRequest.Builder(NativeTestServer.getRedirectURL(), listener, + listener.getExecutor(), mActivity.mCronetEngine) + .build(); // Try to follow a redirect before starting the request. try { @@ -912,11 +941,11 @@ @Feature({"Cronet"}) public void testUploadSetDataProvider() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoBodyURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoBodyURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); try { - urlRequest.setUploadDataProvider(null, listener.getExecutor()); + builder.setUploadDataProvider(null, listener.getExecutor()); fail("Exception not thrown"); } catch (NullPointerException e) { assertEquals("Invalid UploadDataProvider.", e.getMessage()); @@ -924,9 +953,9 @@ TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.SYNC, listener.getExecutor()); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); try { - urlRequest.start(); + builder.build().start(); fail("Exception not thrown"); } catch (IllegalArgumentException e) { assertEquals("Requests with upload data must have a Content-Type.", e.getMessage()); @@ -937,14 +966,14 @@ @Feature({"Cronet"}) public void testUploadEmptyBodySync() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoBodyURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoBodyURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.SYNC, listener.getExecutor()); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); - urlRequest.start(); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); + builder.build().start(); listener.blockForDone(); assertEquals(0, dataProvider.getLength()); @@ -959,15 +988,15 @@ @Feature({"Cronet"}) public void testUploadSync() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoBodyURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoBodyURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.SYNC, listener.getExecutor()); dataProvider.addRead("test".getBytes()); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); - urlRequest.start(); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); + builder.build().start(); listener.blockForDone(); assertEquals(4, dataProvider.getLength()); @@ -982,8 +1011,8 @@ @Feature({"Cronet"}) public void testUploadMultiplePiecesSync() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoBodyURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoBodyURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.SYNC, listener.getExecutor()); @@ -992,9 +1021,9 @@ dataProvider.addRead("another ".getBytes()); dataProvider.addRead("test".getBytes()); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); - urlRequest.start(); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); + builder.build().start(); listener.blockForDone(); assertEquals(16, dataProvider.getLength()); @@ -1009,8 +1038,8 @@ @Feature({"Cronet"}) public void testUploadMultiplePiecesAsync() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoBodyURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoBodyURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.ASYNC, listener.getExecutor()); @@ -1019,9 +1048,9 @@ dataProvider.addRead("another ".getBytes()); dataProvider.addRead("test".getBytes()); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); - urlRequest.start(); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); + builder.build().start(); listener.blockForDone(); assertEquals(16, dataProvider.getLength()); @@ -1036,15 +1065,15 @@ @Feature({"Cronet"}) public void testUploadChangesDefaultMethod() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoMethodURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoMethodURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.SYNC, listener.getExecutor()); dataProvider.addRead("test".getBytes()); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); - urlRequest.start(); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); + builder.build().start(); listener.blockForDone(); assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); @@ -1055,18 +1084,18 @@ @Feature({"Cronet"}) public void testUploadWithSetMethod() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoMethodURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoMethodURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); final String method = "PUT"; - urlRequest.setHttpMethod(method); + builder.setHttpMethod(method); TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.SYNC, listener.getExecutor()); dataProvider.addRead("test".getBytes()); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); - urlRequest.start(); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); + builder.build().start(); listener.blockForDone(); assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); @@ -1077,15 +1106,16 @@ @Feature({"Cronet"}) public void testUploadRedirectSync() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getRedirectToEchoBody(), listener, listener.getExecutor()); + UrlRequest.Builder builder = + new UrlRequest.Builder(NativeTestServer.getRedirectToEchoBody(), listener, + listener.getExecutor(), mActivity.mCronetEngine); TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.SYNC, listener.getExecutor()); dataProvider.addRead("test".getBytes()); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); - urlRequest.start(); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); + builder.build().start(); listener.blockForDone(); // 1 read call before the rewind, 1 after. @@ -1100,15 +1130,16 @@ @Feature({"Cronet"}) public void testUploadRedirectAsync() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getRedirectToEchoBody(), listener, listener.getExecutor()); + UrlRequest.Builder builder = + new UrlRequest.Builder(NativeTestServer.getRedirectToEchoBody(), listener, + listener.getExecutor(), mActivity.mCronetEngine); TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.ASYNC, listener.getExecutor()); dataProvider.addRead("test".getBytes()); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); - urlRequest.start(); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); + builder.build().start(); listener.blockForDone(); // 1 read call before the rewind, 1 after. @@ -1123,8 +1154,8 @@ @Feature({"Cronet"}) public void testUploadReadFailSync() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoBodyURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoBodyURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.SYNC, listener.getExecutor()); @@ -1132,9 +1163,9 @@ // This will never be read, but if the length is 0, read may never be // called. dataProvider.addRead("test".getBytes()); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); - urlRequest.start(); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); + builder.build().start(); listener.blockForDone(); assertEquals(1, dataProvider.getNumReadCalls()); @@ -1149,8 +1180,8 @@ @Feature({"Cronet"}) public void testUploadReadFailAsync() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoBodyURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoBodyURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.SYNC, listener.getExecutor()); @@ -1158,9 +1189,9 @@ // This will never be read, but if the length is 0, read may never be // called. dataProvider.addRead("test".getBytes()); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); - urlRequest.start(); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); + builder.build().start(); listener.blockForDone(); assertEquals(1, dataProvider.getNumReadCalls()); @@ -1175,8 +1206,8 @@ @Feature({"Cronet"}) public void testUploadReadFailThrown() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoBodyURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoBodyURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.SYNC, listener.getExecutor()); @@ -1184,9 +1215,9 @@ // This will never be read, but if the length is 0, read may never be // called. dataProvider.addRead("test".getBytes()); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); - urlRequest.start(); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); + builder.build().start(); listener.blockForDone(); assertEquals(1, dataProvider.getNumReadCalls()); @@ -1201,16 +1232,17 @@ @Feature({"Cronet"}) public void testUploadRewindFailSync() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getRedirectToEchoBody(), listener, listener.getExecutor()); + UrlRequest.Builder builder = + new UrlRequest.Builder(NativeTestServer.getRedirectToEchoBody(), listener, + listener.getExecutor(), mActivity.mCronetEngine); TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.SYNC, listener.getExecutor()); dataProvider.setRewindFailure(TestUploadDataProvider.FailMode.CALLBACK_SYNC); dataProvider.addRead("test".getBytes()); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); - urlRequest.start(); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); + builder.build().start(); listener.blockForDone(); assertEquals(1, dataProvider.getNumReadCalls()); @@ -1225,16 +1257,17 @@ @Feature({"Cronet"}) public void testUploadRewindFailAsync() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getRedirectToEchoBody(), listener, listener.getExecutor()); + UrlRequest.Builder builder = + new UrlRequest.Builder(NativeTestServer.getRedirectToEchoBody(), listener, + listener.getExecutor(), mActivity.mCronetEngine); TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.ASYNC, listener.getExecutor()); dataProvider.setRewindFailure(TestUploadDataProvider.FailMode.CALLBACK_ASYNC); dataProvider.addRead("test".getBytes()); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); - urlRequest.start(); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); + builder.build().start(); listener.blockForDone(); assertEquals(1, dataProvider.getNumReadCalls()); @@ -1249,16 +1282,17 @@ @Feature({"Cronet"}) public void testUploadRewindFailThrown() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getRedirectToEchoBody(), listener, listener.getExecutor()); + UrlRequest.Builder builder = + new UrlRequest.Builder(NativeTestServer.getRedirectToEchoBody(), listener, + listener.getExecutor(), mActivity.mCronetEngine); TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.SYNC, listener.getExecutor()); dataProvider.setRewindFailure(TestUploadDataProvider.FailMode.THROWN); dataProvider.addRead("test".getBytes()); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); - urlRequest.start(); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); + builder.build().start(); listener.blockForDone(); assertEquals(1, dataProvider.getNumReadCalls()); @@ -1273,19 +1307,19 @@ @Feature({"Cronet"}) public void testUploadChunked() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoBodyURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoBodyURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.SYNC, listener.getExecutor()); dataProvider.addRead("test hello".getBytes()); dataProvider.setChunked(true); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); assertEquals(-1, dataProvider.getLength()); - urlRequest.start(); + builder.build().start(); listener.blockForDone(); // 1 read call for one data chunk. @@ -1297,8 +1331,8 @@ @Feature({"Cronet"}) public void testUploadChunkedLastReadZeroLengthBody() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoBodyURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoBodyURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.SYNC, listener.getExecutor()); @@ -1307,12 +1341,12 @@ dataProvider.addRead("!".getBytes()); dataProvider.addRead("".getBytes()); dataProvider.setChunked(true); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); assertEquals(-1, dataProvider.getLength()); - urlRequest.start(); + builder.build().start(); listener.blockForDone(); // 2 read call for the first two data chunks, and 1 for final chunk. @@ -1326,8 +1360,8 @@ @Feature({"Cronet"}) public void testUploadFailsWithoutInitializingStream() throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoBodyURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoBodyURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); // Shut down the test server, so connecting to it fails. Note that // calling shutdown again during teardown is safe. NativeTestServer.shutdownNativeTestServer(); @@ -1335,9 +1369,9 @@ TestUploadDataProvider dataProvider = new TestUploadDataProvider( TestUploadDataProvider.SuccessCallbackMode.SYNC, listener.getExecutor()); dataProvider.addRead("test".getBytes()); - urlRequest.setUploadDataProvider(dataProvider, listener.getExecutor()); - urlRequest.addHeader("Content-Type", "useless/string"); - urlRequest.start(); + builder.setUploadDataProvider(dataProvider, listener.getExecutor()); + builder.addHeader("Content-Type", "useless/string"); + builder.build().start(); listener.blockForDone(); assertNull(listener.mResponseInfo); @@ -1349,8 +1383,9 @@ boolean expectResponseInfo, boolean expectError) { TestUrlRequestListener listener = new TestUrlRequestListener(); listener.setFailure(failureType, failureStep); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getRedirectURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getRedirectURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); + UrlRequest urlRequest = builder.build(); urlRequest.start(); listener.blockForDone(); assertEquals(1, listener.mRedirectCount); @@ -1397,8 +1432,9 @@ public void testThrowON_SUCCEEDED() { TestUrlRequestListener listener = new TestUrlRequestListener(); listener.setFailure(FailureType.THROW_SYNC, ResponseStep.ON_SUCCEEDED); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getRedirectURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getRedirectURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); + UrlRequest urlRequest = builder.build(); urlRequest.start(); listener.blockForDone(); assertEquals(1, listener.mRedirectCount); @@ -1415,9 +1451,9 @@ TestUrlRequestListener listener = new TestUrlRequestListener(); listener.setAutoAdvance(false); - CronetUrlRequest urlRequest = - (CronetUrlRequest) mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoBodyURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoBodyURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); + CronetUrlRequest urlRequest = (CronetUrlRequest) builder.build(); urlRequest.start(); listener.waitForNextStep(); assertFalse(listener.isDone()); @@ -1470,13 +1506,14 @@ } TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - NativeTestServer.getEchoBodyURL(), listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder(NativeTestServer.getEchoBodyURL(), + listener, listener.getExecutor(), mActivity.mCronetEngine); ExecutorService uploadExecutor = Executors.newSingleThreadExecutor(); HangingUploadDataProvider dataProvider = new HangingUploadDataProvider(); - urlRequest.setUploadDataProvider(dataProvider, uploadExecutor); - urlRequest.addHeader("Content-Type", "useless/string"); + builder.setUploadDataProvider(dataProvider, uploadExecutor); + builder.addHeader("Content-Type", "useless/string"); + UrlRequest urlRequest = builder.build(); urlRequest.start(); // Wait for read to be called on executor. dataProvider.mReadCalled.block();
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/GetStatusTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/GetStatusTest.java index 8291ce0c..f146695 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/GetStatusTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/GetStatusTest.java
@@ -45,7 +45,7 @@ @Override protected void tearDown() throws Exception { NativeTestServer.shutdownNativeTestServer(); - mActivity.mUrlRequestContext.shutdown(); + mActivity.mCronetEngine.shutdown(); super.tearDown(); } @@ -55,8 +55,9 @@ String url = NativeTestServer.getEchoMethodURL(); TestUrlRequestListener listener = new TestUrlRequestListener(); listener.setAutoAdvance(false); - UrlRequest urlRequest = - mActivity.mUrlRequestContext.createRequest(url, listener, listener.getExecutor()); + UrlRequest.Builder builder = new UrlRequest.Builder( + url, listener, listener.getExecutor(), mActivity.mCronetEngine); + UrlRequest urlRequest = builder.build(); // Calling before request is started should give Status.INVALID, // since the native adapter is not created. TestStatusListener statusListener0 = new TestStatusListener();
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/HistogramManagerTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/HistogramManagerTest.java index 9922a12..30f8147 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/HistogramManagerTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/HistogramManagerTest.java
@@ -26,9 +26,9 @@ byte delta1[] = mActivity.mHistogramManager.getHistogramDeltas(); TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest urlRequest = mActivity.mUrlRequestContext.createRequest( - TEST_URL, listener, listener.getExecutor()); - urlRequest.start(); + UrlRequest.Builder builder = new UrlRequest.Builder( + TEST_URL, listener, listener.getExecutor(), mActivity.mCronetEngine); + builder.build().start(); listener.blockForDone(); byte delta2[] = mActivity.mHistogramManager.getHistogramDeltas(); assertTrue(delta2.length != 0);
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java index 7e66627..000d7cd 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java
@@ -30,13 +30,13 @@ // Load library first, since we need the Quic test server's URL. System.loadLibrary("cronet_tests"); QuicTestServer.startQuicTestServer(getInstrumentation().getTargetContext()); - UrlRequestContextConfig config = new UrlRequestContextConfig(); - config.enableQUIC(true); - config.addQuicHint(QuicTestServer.getServerHost(), QuicTestServer.getServerPort(), + CronetEngine.Builder builder = new CronetEngine.Builder(mActivity); + builder.enableQUIC(true); + builder.addQuicHint(QuicTestServer.getServerHost(), QuicTestServer.getServerPort(), QuicTestServer.getServerPort()); - config.setExperimentalQuicConnectionOptions("PACE,IW10,FOO,DEADBEEF"); + builder.setExperimentalQuicConnectionOptions("PACE,IW10,FOO,DEADBEEF"); - String[] commandLineArgs = {CronetTestActivity.CONFIG_KEY, config.toString(), + String[] commandLineArgs = {CronetTestActivity.CONFIG_KEY, builder.toString(), CronetTestActivity.CACHE_KEY, CronetTestActivity.CACHE_DISK_NO_HTTP}; mActivity = launchCronetTestAppWithUrlAndCommandLineArgs(null, commandLineArgs); } @@ -80,9 +80,9 @@ // since there is no http server running on the corresponding TCP port, // QUIC will always succeed with a 200 (see // net::HttpStreamFactoryImpl::Request::OnStreamFailed). - UrlRequest request = mActivity.mUrlRequestContext.createRequest( - quicURL, listener, listener.getExecutor()); - request.start(); + UrlRequest.Builder requestBuilder = new UrlRequest.Builder( + quicURL, listener, listener.getExecutor(), mActivity.mCronetEngine); + requestBuilder.build().start(); listener.blockForDone(); assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); @@ -109,18 +109,19 @@ } assertTrue(fileContainsString("local_prefs.json", QuicTestServer.getServerHost() + ":" + QuicTestServer.getServerPort())); - mActivity.mUrlRequestContext.shutdown(); + mActivity.mCronetEngine.shutdown(); // Make another request using a new context but with no QUIC hints. - UrlRequestContextConfig config = new UrlRequestContextConfig(); - config.setStoragePath(mActivity.getTestStorage()); - config.enableHttpCache(UrlRequestContextConfig.HTTP_CACHE_DISK, 1000 * 1024); - config.enableQUIC(true); - CronetUrlRequestContext newContext = - new CronetUrlRequestContext(getInstrumentation().getTargetContext(), config); + CronetEngine.Builder builder = + new CronetEngine.Builder(getInstrumentation().getTargetContext()); + builder.setStoragePath(mActivity.getTestStorage()); + builder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK, 1000 * 1024); + builder.enableQUIC(true); + CronetEngine newEngine = new CronetUrlRequestContext(builder); TestUrlRequestListener listener2 = new TestUrlRequestListener(); - UrlRequest request2 = newContext.createRequest(quicURL, listener2, listener2.getExecutor()); - request2.start(); + requestBuilder = + new UrlRequest.Builder(quicURL, listener2, listener2.getExecutor(), newEngine); + requestBuilder.build().start(); listener2.blockForDone(); assertEquals(200, listener2.mResponseInfo.getHttpStatusCode()); assertEquals(expectedContent, listener2.mResponseAsString);
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java index ca4a426c..4b5a689a 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java
@@ -48,7 +48,7 @@ launchCronetTestAppWithUrlAndCommandLineArgs(null, commandLineArgs.toArray(args)); long urlRequestContextAdapter = (api == Api.LEGACY) ? getContextAdapter((ChromiumUrlRequestFactory) mActivity.mRequestFactory) - : getContextAdapter((CronetUrlRequestContext) mActivity.mUrlRequestContext); + : getContextAdapter((CronetUrlRequestContext) mActivity.mCronetEngine); NativeTestServer.registerHostResolverProc(urlRequestContextAdapter, api == Api.LEGACY); // Start NativeTestServer. assertTrue(NativeTestServer.startNativeTestServer(getInstrumentation().getTargetContext())); @@ -128,14 +128,13 @@ public void testSdchEnabled() throws Exception { setUp(Sdch.ENABLED, Api.ASYNC); String targetUrl = NativeTestServer.getSdchURL() + "/sdch/test"; - long contextAdapter = - getContextAdapter((CronetUrlRequestContext) mActivity.mUrlRequestContext); + long contextAdapter = getContextAdapter((CronetUrlRequestContext) mActivity.mCronetEngine); DictionaryAddedObserver observer = new DictionaryAddedObserver(targetUrl, contextAdapter, false /** Legacy Api */); // Make a request to /sdch which advertises the dictionary. - TestUrlRequestListener listener1 = startAndWaitForComplete(mActivity.mUrlRequestContext, - NativeTestServer.getSdchURL() + "/sdch/index?q=LeQxM80O"); + TestUrlRequestListener listener1 = startAndWaitForComplete( + mActivity.mCronetEngine, NativeTestServer.getSdchURL() + "/sdch/index?q=LeQxM80O"); assertEquals(200, listener1.mResponseInfo.getHttpStatusCode()); assertEquals("This is an index page.\n", listener1.mResponseAsString); assertEquals(Arrays.asList("/sdch/dict/LeQxM80O"), @@ -145,15 +144,15 @@ // Make a request to fetch encoded response at /sdch/test. TestUrlRequestListener listener2 = - startAndWaitForComplete(mActivity.mUrlRequestContext, targetUrl); + startAndWaitForComplete(mActivity.mCronetEngine, targetUrl); assertEquals(200, listener2.mResponseInfo.getHttpStatusCode()); assertEquals("The quick brown fox jumps over the lazy dog.\n", listener2.mResponseAsString); // Wait for a bit until SimpleCache finished closing entries before - // calling shutdown on the UrlRequestContext. + // calling shutdown on the CronetEngine. // TODO(xunjieli): Remove once crbug.com/486120 is fixed. Thread.sleep(5000); - mActivity.mUrlRequestContext.shutdown(); + mActivity.mCronetEngine.shutdown(); // Shutting down the context will make JsonPrefStore to flush pending // writes to disk. @@ -161,8 +160,8 @@ assertTrue(fileContainsString("local_prefs.json", dictUrl)); // Test persistence. - CronetUrlRequestContext newContext = new CronetUrlRequestContext( - getInstrumentation().getTargetContext(), mActivity.getContextConfig()); + CronetUrlRequestContext newContext = + new CronetUrlRequestContext(mActivity.getCronetEngineBuilder()); long newContextAdapter = getContextAdapter(newContext); NativeTestServer.registerHostResolverProc(newContextAdapter, false); @@ -182,8 +181,8 @@ setUp(Sdch.DISABLED, Api.ASYNC); // Make a request to /sdch. // Since Sdch is not enabled, no dictionary should be advertised. - TestUrlRequestListener listener = startAndWaitForComplete(mActivity.mUrlRequestContext, - NativeTestServer.getSdchURL() + "/sdch/index?q=LeQxM80O"); + TestUrlRequestListener listener = startAndWaitForComplete( + mActivity.mCronetEngine, NativeTestServer.getSdchURL() + "/sdch/index?q=LeQxM80O"); assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); assertEquals("This is an index page.\n", listener.mResponseAsString); assertEquals(null, listener.mResponseInfo.getAllHeaders().get("Get-Dictionary")); @@ -195,8 +194,8 @@ setUp(Sdch.ENABLED, Api.ASYNC); // Make a request to /sdch/index which advertises a bad dictionary that // does not exist. - TestUrlRequestListener listener1 = startAndWaitForComplete(mActivity.mUrlRequestContext, - NativeTestServer.getSdchURL() + "/sdch/index?q=NotFound"); + TestUrlRequestListener listener1 = startAndWaitForComplete( + mActivity.mCronetEngine, NativeTestServer.getSdchURL() + "/sdch/index?q=NotFound"); assertEquals(200, listener1.mResponseInfo.getHttpStatusCode()); assertEquals("This is an index page.\n", listener1.mResponseAsString); assertEquals(Arrays.asList("/sdch/dict/NotFound"), @@ -204,7 +203,7 @@ // Make a request to fetch /sdch/test, and make sure Sdch encoding is not used. TestUrlRequestListener listener2 = startAndWaitForComplete( - mActivity.mUrlRequestContext, NativeTestServer.getSdchURL() + "/sdch/test"); + mActivity.mCronetEngine, NativeTestServer.getSdchURL() + "/sdch/test"); assertEquals(200, listener2.mResponseInfo.getHttpStatusCode()); assertEquals("Sdch is not used.\n", listener2.mResponseAsString); } @@ -248,11 +247,12 @@ return listener; } - private TestUrlRequestListener startAndWaitForComplete( - UrlRequestContext requestContext, String url) throws Exception { + private TestUrlRequestListener startAndWaitForComplete(CronetEngine cronetEngine, String url) + throws Exception { TestUrlRequestListener listener = new TestUrlRequestListener(); - UrlRequest request = requestContext.createRequest(url, listener, listener.getExecutor()); - request.start(); + UrlRequest.Builder builder = + new UrlRequest.Builder(url, listener, listener.getExecutor(), cronetEngine); + builder.build().start(); listener.blockForDone(); return listener; }
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetHttpURLStreamHandlerTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetHttpURLStreamHandlerTest.java index 7d9bbf9..19b81d5 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetHttpURLStreamHandlerTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetHttpURLStreamHandlerTest.java
@@ -18,6 +18,9 @@ import java.net.Proxy; import java.net.URL; +/** + * Tests for CronetHttpURLStreamHandler class. + */ public class CronetHttpURLStreamHandlerTest extends CronetTestBase { private CronetTestActivity mActivity; @@ -40,7 +43,7 @@ public void testOpenConnectionHttp() throws Exception { URL url = new URL(NativeTestServer.getEchoMethodURL()); CronetHttpURLStreamHandler streamHandler = - new CronetHttpURLStreamHandler(mActivity.mUrlRequestContext); + new CronetHttpURLStreamHandler(mActivity.mCronetEngine); HttpURLConnection connection = (HttpURLConnection) streamHandler.openConnection(url); assertEquals(200, connection.getResponseCode()); @@ -54,7 +57,7 @@ public void testOpenConnectionHttps() throws Exception { URL url = new URL("https://example.com"); CronetHttpURLStreamHandler streamHandler = - new CronetHttpURLStreamHandler(mActivity.mUrlRequestContext); + new CronetHttpURLStreamHandler(mActivity.mCronetEngine); HttpURLConnection connection = (HttpURLConnection) streamHandler.openConnection(url); assertNotNull(connection); @@ -65,7 +68,7 @@ public void testOpenConnectionProtocolNotSupported() throws Exception { URL url = new URL("ftp://example.com"); CronetHttpURLStreamHandler streamHandler = - new CronetHttpURLStreamHandler(mActivity.mUrlRequestContext); + new CronetHttpURLStreamHandler(mActivity.mCronetEngine); try { streamHandler.openConnection(url); fail(); @@ -79,7 +82,7 @@ public void testOpenConnectionWithProxy() throws Exception { URL url = new URL(NativeTestServer.getEchoMethodURL()); CronetHttpURLStreamHandler streamHandler = - new CronetHttpURLStreamHandler(mActivity.mUrlRequestContext); + new CronetHttpURLStreamHandler(mActivity.mCronetEngine); Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8080)); try {
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetURLStreamHandlerFactoryTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetURLStreamHandlerFactoryTest.java index 110bcf7f..23f4675 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetURLStreamHandlerFactoryTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetURLStreamHandlerFactoryTest.java
@@ -7,18 +7,20 @@ import android.test.suitebuilder.annotation.SmallTest; import org.chromium.base.test.util.Feature; -import org.chromium.net.CronetTestActivity; import org.chromium.net.CronetTestBase; +/** + * Test for CronetURLStreamHandlerFactory. + */ public class CronetURLStreamHandlerFactoryTest extends CronetTestBase { @SmallTest @Feature({"Cronet"}) public void testRequireConfig() throws Exception { - CronetTestActivity activity = launchCronetTestApp(); + launchCronetTestApp(); try { - new CronetURLStreamHandlerFactory(activity, null); + new CronetURLStreamHandlerFactory(null); } catch (NullPointerException e) { - assertEquals("UrlRequestContextConfig is null.", e.getMessage()); + assertEquals("CronetEngine is null.", e.getMessage()); } } }
diff --git a/components/cronet/android/test/src/org/chromium/net/CronetTestActivity.java b/components/cronet/android/test/src/org/chromium/net/CronetTestActivity.java index 956cbac..0a3cdadc 100644 --- a/components/cronet/android/test/src/org/chromium/net/CronetTestActivity.java +++ b/components/cronet/android/test/src/org/chromium/net/CronetTestActivity.java
@@ -5,6 +5,7 @@ package org.chromium.net; import android.app.Activity; +import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.Environment; @@ -67,7 +68,7 @@ public static final String LIBRARY_INIT_WRAPPER = "wrapperOnly"; public CronetURLStreamHandlerFactory mStreamHandlerFactory; - public UrlRequestContext mUrlRequestContext; + public CronetEngine mCronetEngine; HttpUrlRequestFactory mRequestFactory; @SuppressFBWarnings("URF_UNREAD_FIELD") HistogramManager mHistogramManager; @@ -78,8 +79,8 @@ int mHttpStatusCode = 0; - // UrlRequestContextConfig used for this activity. - private UrlRequestContextConfig mConfig; + // CronetEngine.Builder used for this activity. + private CronetEngine.Builder mCronetEngineBuilder; class TestHttpUrlRequestListener implements HttpUrlRequestListener { public TestHttpUrlRequestListener() { @@ -116,21 +117,21 @@ } } - // Initializes UrlRequestContextConfig from commandLine args. - mConfig = initializeContextConfig(); - Log.i(TAG, "Using Config: " + mConfig.toString()); + // Initializes CronetEngine.Builder from commandLine args. + mCronetEngineBuilder = initializeCronetEngineBuilder(); + Log.i(TAG, "Using Config: " + mCronetEngineBuilder.toString()); String initString = getCommandLineArg(LIBRARY_INIT_KEY); if (LIBRARY_INIT_SKIP.equals(initString)) { return; } + mCronetEngine = initCronetEngine(); + if (LIBRARY_INIT_WRAPPER.equals(initString)) { - mStreamHandlerFactory = - new CronetURLStreamHandlerFactory(this, mConfig); + mStreamHandlerFactory = new CronetURLStreamHandlerFactory(mCronetEngine); } - mUrlRequestContext = initRequestContext(); mHistogramManager = HistogramManager.createHistogramManager(); if (LIBRARY_INIT_CRONET_ONLY.equals(initString)) { @@ -171,19 +172,23 @@ return path.delete(); } - UrlRequestContextConfig getContextConfig() { - return mConfig; + CronetEngine.Builder getCronetEngineBuilder() { + return mCronetEngineBuilder; } - private UrlRequestContextConfig initializeContextConfig() { - UrlRequestContextConfig config = new UrlRequestContextConfig(); - config.enableHTTP2(true).enableQUIC(true); + private CronetEngine.Builder initializeCronetEngineBuilder() { + return createCronetEngineBuilder(this); + } + + CronetEngine.Builder createCronetEngineBuilder(Context context) { + CronetEngine.Builder cronetEngineBuilder = new CronetEngine.Builder(context); + cronetEngineBuilder.enableHTTP2(true).enableQUIC(true); // Override config if it is passed from the launcher. String configString = getCommandLineArg(CONFIG_KEY); if (configString != null) { try { - config = new UrlRequestContextConfig(configString); + cronetEngineBuilder = new CronetEngine.Builder(this, configString); } catch (org.json.JSONException e) { Log.e(TAG, "Invalid Config.", e); finish(); @@ -193,33 +198,35 @@ String cacheString = getCommandLineArg(CACHE_KEY); if (CACHE_DISK.equals(cacheString)) { - config.setStoragePath(getTestStorage()); - config.enableHttpCache(UrlRequestContextConfig.HTTP_CACHE_DISK, 1000 * 1024); + cronetEngineBuilder.setStoragePath(getTestStorage()); + cronetEngineBuilder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK, 1000 * 1024); } else if (CACHE_DISK_NO_HTTP.equals(cacheString)) { - config.setStoragePath(getTestStorage()); - config.enableHttpCache(UrlRequestContextConfig.HTTP_CACHE_DISK_NO_HTTP, 1000 * 1024); + cronetEngineBuilder.setStoragePath(getTestStorage()); + cronetEngineBuilder.enableHttpCache( + CronetEngine.Builder.HTTP_CACHE_DISK_NO_HTTP, 1000 * 1024); } else if (CACHE_IN_MEMORY.equals(cacheString)) { - config.enableHttpCache(UrlRequestContextConfig.HTTP_CACHE_IN_MEMORY, 100 * 1024); + cronetEngineBuilder.enableHttpCache( + CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024); } String sdchString = getCommandLineArg(SDCH_KEY); if (SDCH_ENABLE.equals(sdchString)) { - config.enableSDCH(true); + cronetEngineBuilder.enableSDCH(true); } // Setting this here so it isn't overridden on the command line - config.setLibraryName("cronet_tests"); - return config; + cronetEngineBuilder.setLibraryName("cronet_tests"); + return cronetEngineBuilder; } - // Helper function to initialize request context. Also used in testing. - public UrlRequestContext initRequestContext() { - return UrlRequestContext.createContext(this, mConfig); + // Helper function to initialize Cronet engine. Also used in testing. + public CronetEngine initCronetEngine() { + return mCronetEngineBuilder.build(); } // Helper function to initialize request factory. Also used in testing. public HttpUrlRequestFactory initRequestFactory() { - return HttpUrlRequestFactory.createFactory(this, mConfig); + return HttpUrlRequestFactory.createFactory(this, mCronetEngineBuilder); } private static String getUrlFromIntent(Intent intent) { @@ -285,9 +292,9 @@ + "/cronet_sample_netlog_old_api.json", false); } - if (mUrlRequestContext != null) { - mUrlRequestContext.startNetLogToFile(Environment.getExternalStorageDirectory().getPath() - + "/cronet_sample_netlog_new_api.json", + if (mCronetEngine != null) { + mCronetEngine.startNetLogToFile(Environment.getExternalStorageDirectory().getPath() + + "/cronet_sample_netlog_new_api.json", false); } } @@ -296,8 +303,8 @@ if (mRequestFactory != null) { mRequestFactory.stopNetLog(); } - if (mUrlRequestContext != null) { - mUrlRequestContext.stopNetLog(); + if (mCronetEngine != null) { + mCronetEngine.stopNetLog(); } } }
diff --git a/components/cronet/cronet_static.gypi b/components/cronet/cronet_static.gypi index 08601ce..f2dce0d1 100644 --- a/components/cronet/cronet_static.gypi +++ b/components/cronet/cronet_static.gypi
@@ -8,7 +8,7 @@ '../base/base.gyp:base', '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', 'cronet_jni_headers', - 'cronet_url_request_context_config_list', + 'cronet_engine_builder_list', 'cronet_url_request_java', 'cronet_version', 'cronet_version_header',
diff --git a/components/html_viewer/web_test_delegate_impl.cc b/components/html_viewer/web_test_delegate_impl.cc index 4e958fd..b2dceec 100644 --- a/components/html_viewer/web_test_delegate_impl.cc +++ b/components/html_viewer/web_test_delegate_impl.cc
@@ -310,6 +310,12 @@ NOTIMPLEMENTED(); } +bool WebTestDelegateImpl::AddMediaStreamSourceAndTrack( + blink::WebMediaStream* stream) { + NOTIMPLEMENTED(); + return false; +} + cc::SharedBitmapManager* WebTestDelegateImpl::GetSharedBitmapManager() { NOTIMPLEMENTED(); return nullptr;
diff --git a/components/html_viewer/web_test_delegate_impl.h b/components/html_viewer/web_test_delegate_impl.h index b3ae0e8..e13be3b 100644 --- a/components/html_viewer/web_test_delegate_impl.h +++ b/components/html_viewer/web_test_delegate_impl.h
@@ -108,6 +108,7 @@ const GURL& origin, const GURL& embedding_origin) override; void ResetPermissions() override; + bool AddMediaStreamSourceAndTrack(blink::WebMediaStream* stream) override; cc::SharedBitmapManager* GetSharedBitmapManager() override; void DispatchBeforeInstallPromptEvent( int request_id,
diff --git a/components/mus/gles2/command_buffer_driver.cc b/components/mus/gles2/command_buffer_driver.cc index a03a357..acffd14 100644 --- a/components/mus/gles2/command_buffer_driver.cc +++ b/components/mus/gles2/command_buffer_driver.cc
@@ -12,7 +12,6 @@ #include "components/mus/gles2/gpu_memory_tracker.h" #include "components/mus/gles2/gpu_state.h" #include "components/mus/gles2/mojo_buffer_backing.h" -#include "gpu/command_buffer/common/constants.h" #include "gpu/command_buffer/common/value_state.h" #include "gpu/command_buffer/service/command_buffer_service.h" #include "gpu/command_buffer/service/context_group.h" @@ -117,6 +116,10 @@ base::Bind(&CommandBufferDriver::OnResize, base::Unretained(this))); decoder_->SetWaitSyncPointCallback(base::Bind( &CommandBufferDriver::OnWaitSyncPoint, base::Unretained(this))); + decoder_->SetFenceSyncReleaseCallback(base::Bind( + &CommandBufferDriver::OnFenceSyncRelease, base::Unretained(this))); + decoder_->SetWaitFenceSyncCallback(base::Bind( + &CommandBufferDriver::OnWaitFenceSync, base::Unretained(this))); gpu::gles2::DisallowedFeatures disallowed_features; @@ -293,6 +296,45 @@ return scheduler_->scheduled(); } +void CommandBufferDriver::OnFenceSyncRelease(uint64_t release) { + // TODO(dyen): Implement once CommandBufferID has been figured out and + // we have a SyncPointClient. It would probably look like what is commented + // out below: + // if (!sync_point_client_->client_state()->IsFenceSyncReleased(release)) + // sync_point_client_->ReleaseFenceSync(release); + NOTIMPLEMENTED(); +} + +bool CommandBufferDriver::OnWaitFenceSync( + gpu::CommandBufferNamespace namespace_id, + uint64_t command_buffer_id, + uint64_t release) { + gpu::SyncPointManager* sync_point_manager = gpu_state_->sync_point_manager(); + DCHECK(sync_point_manager); + + scoped_refptr<gpu::SyncPointClientState> release_state = + sync_point_manager->GetSyncPointClientState(namespace_id, + command_buffer_id); + + if (!release_state) + return true; + + if (release_state->IsFenceSyncReleased(release)) + return true; + + // TODO(dyen): Implement once CommandBufferID has been figured out and + // we have a SyncPointClient. It would probably look like what is commented + // out below: + // scheduler_->SetScheduled(false); + // sync_point_client_->Wait( + // release_state.get(), + // release, + // base::Bind(&CommandBufferDriver::OnSyncPointRetired, + // weak_factory_.GetWeakPtr())); + NOTIMPLEMENTED(); + return scheduler_->scheduled(); +} + void CommandBufferDriver::OnSyncPointRetired() { scheduler_->SetScheduled(true); }
diff --git a/components/mus/gles2/command_buffer_driver.h b/components/mus/gles2/command_buffer_driver.h index 97ede0c..9029d575 100644 --- a/components/mus/gles2/command_buffer_driver.h +++ b/components/mus/gles2/command_buffer_driver.h
@@ -12,6 +12,7 @@ #include "base/single_thread_task_runner.h" #include "base/timer/timer.h" #include "components/mus/public/interfaces/command_buffer.mojom.h" +#include "gpu/command_buffer/common/constants.h" #include "ui/gfx/geometry/size.h" namespace gpu { @@ -73,6 +74,10 @@ mojo::Array<int32_t> attribs); void OnResize(gfx::Size size, float scale_factor); bool OnWaitSyncPoint(uint32_t sync_point); + void OnFenceSyncRelease(uint64_t release); + bool OnWaitFenceSync(gpu::CommandBufferNamespace namespace_id, + uint64_t command_buffer_id, + uint64_t release); void OnSyncPointRetired(); void OnParseError(); void OnContextLost(uint32_t reason);
diff --git a/components/mus/gles2/command_buffer_local.cc b/components/mus/gles2/command_buffer_local.cc index 27442cb3..bb6f854 100644 --- a/components/mus/gles2/command_buffer_local.cc +++ b/components/mus/gles2/command_buffer_local.cc
@@ -32,6 +32,7 @@ : widget_(widget), gpu_state_(gpu_state), client_(client), + next_fence_sync_release_(1), weak_factory_(this) {} CommandBufferLocal::~CommandBufferLocal() { @@ -92,6 +93,10 @@ base::Bind(&CommandBufferLocal::OnResize, base::Unretained(this))); decoder_->SetWaitSyncPointCallback( base::Bind(&CommandBufferLocal::OnWaitSyncPoint, base::Unretained(this))); + decoder_->SetFenceSyncReleaseCallback(base::Bind( + &CommandBufferLocal::OnFenceSyncRelease, base::Unretained(this))); + decoder_->SetWaitFenceSyncCallback( + base::Bind(&CommandBufferLocal::OnWaitFenceSync, base::Unretained(this))); gpu::gles2::DisallowedFeatures disallowed_features; @@ -220,6 +225,18 @@ return 0; } +uint64_t CommandBufferLocal::GenerateFenceSyncRelease() { + return next_fence_sync_release_++; +} + +bool CommandBufferLocal::IsFenceSyncRelease(uint64_t release) { + return release > 0 && release < next_fence_sync_release_; +} + +bool CommandBufferLocal::IsFenceSyncFlushed(uint64_t release) { + return IsFenceSyncRelease(release); +} + void CommandBufferLocal::PumpCommands() { if (!decoder_->MakeCurrent()) { command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); @@ -253,6 +270,45 @@ return scheduler_->scheduled(); } +void CommandBufferLocal::OnFenceSyncRelease(uint64_t release) { + // TODO(dyen): Implement once CommandBufferID has been figured out and + // we have a SyncPointClient. It would probably look like what is commented + // out below: + // if (!sync_point_client_->client_state()->IsFenceSyncReleased(release)) + // sync_point_client_->ReleaseFenceSync(release); + NOTIMPLEMENTED(); +} + +bool CommandBufferLocal::OnWaitFenceSync( + gpu::CommandBufferNamespace namespace_id, + uint64_t command_buffer_id, + uint64_t release) { + gpu::SyncPointManager* sync_point_manager = gpu_state_->sync_point_manager(); + DCHECK(sync_point_manager); + + scoped_refptr<gpu::SyncPointClientState> release_state = + sync_point_manager->GetSyncPointClientState(namespace_id, + command_buffer_id); + + if (!release_state) + return true; + + if (release_state->IsFenceSyncReleased(release)) + return true; + + // TODO(dyen): Implement once CommandBufferID has been figured out and + // we have a SyncPointClient. It would probably look like what is commented + // out below: + // scheduler_->SetScheduled(false); + // sync_point_client_->Wait( + // release_state.get(), + // release, + // base::Bind(&CommandBufferLocal::OnSyncPointRetired, + // weak_factory_.GetWeakPtr())); + NOTIMPLEMENTED(); + return scheduler_->scheduled(); +} + void CommandBufferLocal::OnParseError() { gpu::CommandBuffer::State state = command_buffer_->GetLastState(); OnContextLost(state.context_lost_reason);
diff --git a/components/mus/gles2/command_buffer_local.h b/components/mus/gles2/command_buffer_local.h index 92a79661..75c7bc4 100644 --- a/components/mus/gles2/command_buffer_local.h +++ b/components/mus/gles2/command_buffer_local.h
@@ -73,6 +73,9 @@ bool IsGpuChannelLost() override; gpu::CommandBufferNamespace GetNamespaceID() const override; uint64_t GetCommandBufferID() const override; + uint64_t GenerateFenceSyncRelease() override; + bool IsFenceSyncRelease(uint64_t release) override; + bool IsFenceSyncFlushed(uint64_t release) override; private: void PumpCommands(); @@ -81,6 +84,10 @@ void OnUpdateVSyncParameters(const base::TimeTicks timebase, const base::TimeDelta interval); bool OnWaitSyncPoint(uint32_t sync_point); + void OnFenceSyncRelease(uint64_t release); + bool OnWaitFenceSync(gpu::CommandBufferNamespace namespace_id, + uint64_t command_buffer_id, + uint64_t release); void OnParseError(); void OnContextLost(uint32_t reason); void OnSyncPointRetired(); @@ -94,6 +101,8 @@ scoped_refptr<gfx::GLSurface> surface_; CommandBufferLocalClient* client_; + uint64_t next_fence_sync_release_; + base::WeakPtrFactory<CommandBufferLocal> weak_factory_; DISALLOW_COPY_AND_ASSIGN(CommandBufferLocal);
diff --git a/components/password_manager/core/browser/login_database.cc b/components/password_manager/core/browser/login_database.cc index 788b4f4..30199b4d 100644 --- a/components/password_manager/core/browser/login_database.cc +++ b/components/password_manager/core/browser/login_database.cc
@@ -455,21 +455,27 @@ const int original_version = meta_table_.GetVersionNumber(); switch (original_version) { case 1: - if (!db_.Execute("ALTER TABLE logins " - "ADD COLUMN password_type INTEGER") || + // Column could exist because of https://crbug.com/295851 + if (!db_.DoesColumnExist("logins", "password_type") && + !db_.Execute("ALTER TABLE logins " + "ADD COLUMN password_type INTEGER")) { + return false; + } + if (!db_.DoesColumnExist("logins", "possible_usernames") && !db_.Execute("ALTER TABLE logins " "ADD COLUMN possible_usernames BLOB")) { return false; } // Fall through. case 2: - if (!db_.Execute("ALTER TABLE logins ADD COLUMN times_used INTEGER")) { + // Column could exist because of https://crbug.com/295851 + if (!db_.DoesColumnExist("logins", "times_used") && + !db_.Execute("ALTER TABLE logins ADD COLUMN times_used INTEGER")) { return false; } // Fall through. case 3: - // We need to check if the column exists because of - // https://crbug.com/295851 + // Column could exist because of https://crbug.com/295851 if (!db_.DoesColumnExist("logins", "form_data") && !db_.Execute("ALTER TABLE logins ADD COLUMN form_data BLOB")) { return false;
diff --git a/components/password_manager/core/browser/login_database_unittest.cc b/components/password_manager/core/browser/login_database_unittest.cc index 7faa7f6fd..00a1e06 100644 --- a/components/password_manager/core/browser/login_database_unittest.cc +++ b/components/password_manager/core/browser/login_database_unittest.cc
@@ -1511,11 +1511,22 @@ MigrationToVCurrent("login_db_v9_without_use_additional_auth_field.sql"); } +class LoginDatabaseMigrationTestBroken : public LoginDatabaseMigrationTest {}; + +// Test migrating certain databases with incorrect version. +// http://crbug.com/295851 +TEST_P(LoginDatabaseMigrationTestBroken, Broken) { + MigrationToVCurrent(base::StringPrintf("login_db_v%d_broken.sql", version())); +} + INSTANTIATE_TEST_CASE_P(MigrationToVCurrent, LoginDatabaseMigrationTest, testing::Range(1, kCurrentVersionNumber)); INSTANTIATE_TEST_CASE_P(MigrationToVCurrent, LoginDatabaseMigrationTestV9, testing::Values(9)); +INSTANTIATE_TEST_CASE_P(MigrationToVCurrent, + LoginDatabaseMigrationTestBroken, + testing::Range(1, 4)); } // namespace password_manager
diff --git a/components/policy/core/common/BUILD.gn b/components/policy/core/common/BUILD.gn index dcdd6a7..0bdcae6 100644 --- a/components/policy/core/common/BUILD.gn +++ b/components/policy/core/common/BUILD.gn
@@ -260,6 +260,18 @@ ] } + if (is_android || is_ios) { + sources -= [ + "cloud/component_cloud_policy_service_unittest.cc", + "cloud/component_cloud_policy_store_unittest.cc", + "cloud/component_cloud_policy_updater_unittest.cc", + "cloud/external_policy_data_fetcher_unittest.cc", + "cloud/external_policy_data_updater_unittest.cc", + "cloud/resource_cache_unittest.cc", + "config_dir_policy_loader_unittest.cc", + ] + } + deps = [ "//testing/gmock", "//testing/gtest",
diff --git a/components/test/data/password_manager/login_db_v1_broken.sql b/components/test/data/password_manager/login_db_v1_broken.sql new file mode 100644 index 0000000..3db20259 --- /dev/null +++ b/components/test/data/password_manager/login_db_v1_broken.sql
@@ -0,0 +1,66 @@ +-- Version 4 schema with meta.version==1. Tests http://crbug.com/295851 +PRAGMA foreign_keys=OFF; +BEGIN TRANSACTION; +CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); +INSERT INTO "meta" VALUES('last_compatible_version','1'); +INSERT INTO "meta" VALUES('version','1'); +CREATE TABLE logins ( +origin_url VARCHAR NOT NULL, +action_url VARCHAR, +username_element VARCHAR, +username_value VARCHAR, +password_element VARCHAR, +password_value BLOB, +submit_element VARCHAR, +signon_realm VARCHAR NOT NULL, +ssl_valid INTEGER NOT NULL, +preferred INTEGER NOT NULL, +date_created INTEGER NOT NULL, +blacklisted_by_user INTEGER NOT NULL, +scheme INTEGER NOT NULL, +password_type INTEGER, +possible_usernames BLOB, +times_used INTEGER, +form_data BLOB, +UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); +INSERT INTO "logins" VALUES( +'https://accounts.google.com/ServiceLogin', /* origin_url */ +'https://accounts.google.com/ServiceLoginAuth', /* action_url */ +'Email', /* username_element */ +'theerikchen', /* username_value */ +'Passwd', /* password_element */ +X'', /* password_value */ +'', /* submit_element */ +'https://accounts.google.com/', /* signon_realm */ +1, /* ssl_valid */ +1, /* preferred */ +1402955745, /* date_created */ +0, /* blacklisted_by_user */ +0, /* scheme */ +0, /* password_type */ +X'00000000', /* possible_usernames */ +1, /* times_used */ +X'18000000020000000000000000000000000000000000000000000000' /* form_data */ +); +INSERT INTO "logins" VALUES( +'https://accounts.google.com/ServiceLogin', /* origin_url */ +'https://accounts.google.com/ServiceLoginAuth', /* action_url */ +'Email', /* username_element */ +'theerikchen2', /* username_value */ +'Passwd', /* password_element */ +X'', /* password_value */ +'', /* submit_element */ +'https://accounts.google.com/', /* signon_realm */ +1, /* ssl_valid */ +1, /* preferred */ +1402950000, /* date_created */ +0, /* blacklisted_by_user */ +0, /* scheme */ +0, /* password_type */ +X'00000000', /* possible_usernames */ +1, /* times_used */ +X'18000000020000000000000000000000000000000000000000000000' /* form_data */ +); +CREATE INDEX logins_signon ON logins (signon_realm); +COMMIT; +
diff --git a/components/test/data/password_manager/login_db_v2_broken.sql b/components/test/data/password_manager/login_db_v2_broken.sql new file mode 100644 index 0000000..10da38b3 --- /dev/null +++ b/components/test/data/password_manager/login_db_v2_broken.sql
@@ -0,0 +1,66 @@ +-- Version 4 schema with meta.version==2. Tests http://crbug.com/295851 +PRAGMA foreign_keys=OFF; +BEGIN TRANSACTION; +CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); +INSERT INTO "meta" VALUES('last_compatible_version','1'); +INSERT INTO "meta" VALUES('version','2'); +CREATE TABLE logins ( +origin_url VARCHAR NOT NULL, +action_url VARCHAR, +username_element VARCHAR, +username_value VARCHAR, +password_element VARCHAR, +password_value BLOB, +submit_element VARCHAR, +signon_realm VARCHAR NOT NULL, +ssl_valid INTEGER NOT NULL, +preferred INTEGER NOT NULL, +date_created INTEGER NOT NULL, +blacklisted_by_user INTEGER NOT NULL, +scheme INTEGER NOT NULL, +password_type INTEGER, +possible_usernames BLOB, +times_used INTEGER, +form_data BLOB, +UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); +INSERT INTO "logins" VALUES( +'https://accounts.google.com/ServiceLogin', /* origin_url */ +'https://accounts.google.com/ServiceLoginAuth', /* action_url */ +'Email', /* username_element */ +'theerikchen', /* username_value */ +'Passwd', /* password_element */ +X'', /* password_value */ +'', /* submit_element */ +'https://accounts.google.com/', /* signon_realm */ +1, /* ssl_valid */ +1, /* preferred */ +1402955745, /* date_created */ +0, /* blacklisted_by_user */ +0, /* scheme */ +0, /* password_type */ +X'00000000', /* possible_usernames */ +1, /* times_used */ +X'18000000020000000000000000000000000000000000000000000000' /* form_data */ +); +INSERT INTO "logins" VALUES( +'https://accounts.google.com/ServiceLogin', /* origin_url */ +'https://accounts.google.com/ServiceLoginAuth', /* action_url */ +'Email', /* username_element */ +'theerikchen2', /* username_value */ +'Passwd', /* password_element */ +X'', /* password_value */ +'', /* submit_element */ +'https://accounts.google.com/', /* signon_realm */ +1, /* ssl_valid */ +1, /* preferred */ +1402950000, /* date_created */ +0, /* blacklisted_by_user */ +0, /* scheme */ +0, /* password_type */ +X'00000000', /* possible_usernames */ +1, /* times_used */ +X'18000000020000000000000000000000000000000000000000000000' /* form_data */ +); +CREATE INDEX logins_signon ON logins (signon_realm); +COMMIT; +
diff --git a/components/test/data/password_manager/login_db_v3_broken.sql b/components/test/data/password_manager/login_db_v3_broken.sql new file mode 100644 index 0000000..41262ff --- /dev/null +++ b/components/test/data/password_manager/login_db_v3_broken.sql
@@ -0,0 +1,66 @@ +-- Version 4 schema with meta.version==3. Tests http://crbug.com/295851 +PRAGMA foreign_keys=OFF; +BEGIN TRANSACTION; +CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); +INSERT INTO "meta" VALUES('last_compatible_version','1'); +INSERT INTO "meta" VALUES('version','3'); +CREATE TABLE logins ( +origin_url VARCHAR NOT NULL, +action_url VARCHAR, +username_element VARCHAR, +username_value VARCHAR, +password_element VARCHAR, +password_value BLOB, +submit_element VARCHAR, +signon_realm VARCHAR NOT NULL, +ssl_valid INTEGER NOT NULL, +preferred INTEGER NOT NULL, +date_created INTEGER NOT NULL, +blacklisted_by_user INTEGER NOT NULL, +scheme INTEGER NOT NULL, +password_type INTEGER, +possible_usernames BLOB, +times_used INTEGER, +form_data BLOB, +UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); +INSERT INTO "logins" VALUES( +'https://accounts.google.com/ServiceLogin', /* origin_url */ +'https://accounts.google.com/ServiceLoginAuth', /* action_url */ +'Email', /* username_element */ +'theerikchen', /* username_value */ +'Passwd', /* password_element */ +X'', /* password_value */ +'', /* submit_element */ +'https://accounts.google.com/', /* signon_realm */ +1, /* ssl_valid */ +1, /* preferred */ +1402955745, /* date_created */ +0, /* blacklisted_by_user */ +0, /* scheme */ +0, /* password_type */ +X'00000000', /* possible_usernames */ +1, /* times_used */ +X'18000000020000000000000000000000000000000000000000000000' /* form_data */ +); +INSERT INTO "logins" VALUES( +'https://accounts.google.com/ServiceLogin', /* origin_url */ +'https://accounts.google.com/ServiceLoginAuth', /* action_url */ +'Email', /* username_element */ +'theerikchen2', /* username_value */ +'Passwd', /* password_element */ +X'', /* password_value */ +'', /* submit_element */ +'https://accounts.google.com/', /* signon_realm */ +1, /* ssl_valid */ +1, /* preferred */ +1402950000, /* date_created */ +0, /* blacklisted_by_user */ +0, /* scheme */ +0, /* password_type */ +X'00000000', /* possible_usernames */ +1, /* times_used */ +X'18000000020000000000000000000000000000000000000000000000' /* form_data */ +); +CREATE INDEX logins_signon ON logins (signon_realm); +COMMIT; +
diff --git a/components/test_runner/mock_web_user_media_client.cc b/components/test_runner/mock_web_user_media_client.cc index f30fac9..7cff4c3 100644 --- a/components/test_runner/mock_web_user_media_client.cc +++ b/components/test_runner/mock_web_user_media_client.cc
@@ -18,7 +18,6 @@ #include "third_party/WebKit/public/platform/WebVector.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebMediaDevicesRequest.h" -#include "third_party/WebKit/public/web/WebMediaStreamRegistry.h" #include "third_party/WebKit/public/web/WebUserMediaRequest.h" using blink::WebMediaConstraints; @@ -161,34 +160,34 @@ return; } - const size_t zero = 0; - const size_t one = 1; - WebVector<WebMediaStreamTrack> audio_tracks(request.audio() ? one : zero); - WebVector<WebMediaStreamTrack> video_tracks(request.video() ? one : zero); + WebMediaStream stream; + stream.initialize(WebVector<WebMediaStreamTrack>(), + WebVector<WebMediaStreamTrack>()); + stream.setExtraData(new MockExtraData()); if (request.audio()) { WebMediaStreamSource source; source.initialize("MockAudioDevice#1", WebMediaStreamSource::TypeAudio, "Mock audio device", - false /* remote */, true /* readonly */); - audio_tracks[0].initialize(source); + false /* remote */, + true /* readonly */); + WebMediaStreamTrack web_track; + web_track.initialize(source); + stream.addTrack(web_track); } - if (request.video()) { + if (request.video() && !delegate_->AddMediaStreamSourceAndTrack(&stream)) { WebMediaStreamSource source; source.initialize("MockVideoDevice#1", WebMediaStreamSource::TypeVideo, "Mock video device", false /* remote */, true /* readonly */); - video_tracks[0].initialize(source); + WebMediaStreamTrack web_track; + web_track.initialize(source); + stream.addTrack(web_track); } - WebMediaStream stream; - stream.initialize(audio_tracks, video_tracks); - - stream.setExtraData(new MockExtraData()); - delegate_->PostTask(new UserMediaRequestTask(this, request, stream)); }
diff --git a/components/test_runner/mock_web_user_media_client.h b/components/test_runner/mock_web_user_media_client.h index dda0d4df..33b55d5 100644 --- a/components/test_runner/mock_web_user_media_client.h +++ b/components/test_runner/mock_web_user_media_client.h
@@ -5,7 +5,6 @@ #ifndef COMPONENTS_TEST_RUNNER_MOCK_WEB_USER_MEDIA_CLIENT_H_ #define COMPONENTS_TEST_RUNNER_MOCK_WEB_USER_MEDIA_CLIENT_H_ -#include "base/macros.h" #include "components/test_runner/web_task.h" #include "third_party/WebKit/public/web/WebUserMediaClient.h"
diff --git a/components/test_runner/test_runner.h b/components/test_runner/test_runner.h index 45ee51a..b227a7ee 100644 --- a/components/test_runner/test_runner.h +++ b/components/test_runner/test_runner.h
@@ -23,6 +23,7 @@ namespace blink { class WebContentSettingsClient; class WebFrame; +class WebMediaStream; class WebString; class WebView; class WebURLResponse;
diff --git a/components/test_runner/web_test_delegate.h b/components/test_runner/web_test_delegate.h index 26b135a6..d53852e 100644 --- a/components/test_runner/web_test_delegate.h +++ b/components/test_runner/web_test_delegate.h
@@ -27,13 +27,14 @@ class WebHistoryItem; class WebLayer; class WebLocalFrame; +class WebMediaStream; class WebPlugin; struct WebPluginParams; -class WebURLResponse; -class WebView; struct WebRect; struct WebSize; struct WebURLError; +class WebURLResponse; +class WebView; } namespace cc { @@ -244,6 +245,9 @@ // Clear all the permissions set via SetPermission(). virtual void ResetPermissions() = 0; + // Add content MediaStream classes to the Blink MediaStream ones. + virtual bool AddMediaStreamSourceAndTrack(blink::WebMediaStream* stream) = 0; + virtual cc::SharedBitmapManager* GetSharedBitmapManager() = 0; // Causes the beforeinstallprompt event to be sent to the renderer with a
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc index f893d6a..c2dda31 100644 --- a/content/app/content_main_runner.cc +++ b/content/app/content_main_runner.cc
@@ -453,7 +453,7 @@ // See note at the initialization of ExitManager, below; basically, // only Android builds have the ctor/dtor handlers set up to use // TRACE_EVENT right away. - TRACE_EVENT0("startup", "ContentMainRunnerImpl::Initialize"); + TRACE_EVENT0("startup,benchmark", "ContentMainRunnerImpl::Initialize"); #endif // OS_ANDROID // NOTE(willchan): One might ask why these TCMalloc-related calls are done @@ -638,7 +638,7 @@ // Android tracing started at the beginning of the method. // Other OSes have to wait till we get here in order for all the memory // management setup to be completed. - TRACE_EVENT0("startup", "ContentMainRunnerImpl::Initialize"); + TRACE_EVENT0("startup,benchmark", "ContentMainRunnerImpl::Initialize"); #endif // !OS_ANDROID #if defined(OS_MACOSX) && !defined(OS_IOS)
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index 150d0f4..8df6ad27 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc
@@ -640,6 +640,29 @@ GetRole() == ui::AX_ROLE_ROW_HEADER); } +bool BrowserAccessibility::HasCaret() const { + if (IsEditableText() && !HasState(ui::AX_STATE_RICHLY_EDITABLE) && + HasIntAttribute(ui::AX_ATTR_TEXT_SEL_START) && + HasIntAttribute(ui::AX_ATTR_TEXT_SEL_END)) { + return true; + } + + BrowserAccessibility* root = manager()->GetRoot(); + // The caret is always at the focus of the selection. + int32 focus_id; + if (!root || !root->GetIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, &focus_id)) + return false; + + BrowserAccessibility* focus_object = manager()->GetFromID(focus_id); + if (!focus_object) + return false; + + if (!focus_object->IsDescendantOf(this)) + return false; + + return true; +} + bool BrowserAccessibility::IsEditableText() const { return HasState(ui::AX_STATE_EDITABLE); }
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h index 9e61c4af..10bde83 100644 --- a/content/browser/accessibility/browser_accessibility.h +++ b/content/browser/accessibility/browser_accessibility.h
@@ -265,6 +265,9 @@ // Returns true if this node is an cell or an table header. bool IsCellOrTableHeaderRole() const; + // Returns true if the caret is active on this object. + bool HasCaret() const; + // Returns true if this node is an editable text field of any kind. bool IsEditableText() const;
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc index 8501ba61..2704b423 100644 --- a/content/browser/accessibility/browser_accessibility_win.cc +++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -2013,9 +2013,12 @@ if (!offset) return E_INVALIDARG; + if (!HasCaret()) + return S_FALSE; + int selection_start, selection_end; GetSelectionOffsets(&selection_start, &selection_end); - // The caret is always at the end of the selection, if a selection exists. + // The caret is always at the end of the selection. *offset = selection_end; if (*offset < 0) return S_FALSE; @@ -3847,27 +3850,22 @@ if (*selection_start < 0 || *selection_end < 0) return; - // If the selection is collapsed or if it only spans one character, return the - // selection offsets only if the caret is active on this object or any of its - // children. - // The focus object indicates the caret position. - if (*selection_start == *selection_end) { - BrowserAccessibility* root = manager()->GetRoot(); - int32 focus_id; - if (!root || !root->GetIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, &focus_id)) - return; - - BrowserAccessibilityWin* focus_object = - manager()->GetFromID(focus_id)->ToBrowserAccessibilityWin(); - if (!focus_object) - return; - - if (!focus_object->IsDescendantOf(this) && - !(IsTextOnlyObject() && GetParent() == focus_object)) { - *selection_start = -1; - *selection_end = -1; - return; - } + // There are three cases when a selection would start and end on the same + // character: + // 1. Anchor and focus are both in a subtree that is to the right of this + // object. + // 2. Anchor and focus are both in a subtree that is to the left of this + // object. + // 3. Anchor and focus are in a subtree represented by a single embedded + // object character. + // Only case 3 refers to a valid selection because cases 1 and 2 fall + // outside this object in their entirety. + // Selections that span more than one character are by definition inside this + // object, so checking them is not necessary. + if (*selection_start == *selection_end && !HasCaret()) { + *selection_start = -1; + *selection_end = -1; + return; } // The IA2 Spec says that if the largest of the two offsets falls on an
diff --git a/content/browser/accessibility/browser_accessibility_win_unittest.cc b/content/browser/accessibility/browser_accessibility_win_unittest.cc index c1d99b2..008dcc70 100644 --- a/content/browser/accessibility/browser_accessibility_win_unittest.cc +++ b/content/browser/accessibility/browser_accessibility_win_unittest.cc
@@ -951,9 +951,9 @@ link_text.SetName("here"); // Place the caret between 'h' and 'e'. - root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OBJECT_ID, 4); + root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OBJECT_ID, 5); root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OFFSET, 1); - root.AddIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, 4); + root.AddIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, 5); root.AddIntAttribute(ui::AX_ATTR_FOCUS_OFFSET, 1); root.child_ids.push_back(2); @@ -1065,7 +1065,7 @@ link_text.state = (1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_LINKED); link_text.SetName("here"); - // Select the part of the text "lick here". + // Select the following part of the text: "lick here". root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OBJECT_ID, 3); root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OFFSET, 1); root.AddIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, 5);
diff --git a/content/browser/background_sync/background_sync_manager.h b/content/browser/background_sync/background_sync_manager.h index a066cd6..ee1bb84 100644 --- a/content/browser/background_sync/background_sync_manager.h +++ b/content/browser/background_sync/background_sync_manager.h
@@ -36,17 +36,8 @@ // registrations across all registered service workers for a profile. // Registrations are stored along with their associated Service Worker // registration in ServiceWorkerStorage. If the ServiceWorker is unregistered, -// the sync registrations are removed. This class expects to be run on the IO +// the sync registrations are removed. This class must be run on the IO // thread. The asynchronous methods are executed sequentially. - -// TODO(jkarlin): Check permissions when registering, scheduling, and firing -// background sync. In the meantime, --enable-service-worker-sync is required to -// fire a sync event. -// TODO(jkarlin): Unregister syncs when permission is revoked. -// TODO(jkarlin): Create a background sync scheduler to actually run the -// registered events. -// TODO(jkarlin): Keep the browser alive if "Let Google Chrome Run in the -// Background" is true and a sync is registered. class CONTENT_EXPORT BackgroundSyncManager : NON_EXPORTED_BASE(public ServiceWorkerContextObserver) { public:
diff --git a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc index 4d8c198c..a14cfb5 100644 --- a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc +++ b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -414,4 +414,46 @@ observer.Wait(); } +IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, + InspectDuringLocalToRemoteFrameSwap) { + host_resolver()->AddRule("*", "127.0.0.1"); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); + content::SetupCrossSiteRedirector(embedded_test_server()); + + GURL test_url1 = + embedded_test_server()->GetURL("A.com", "/devtools/navigation.html"); + NavigateToURLBlockUntilNavigationsComplete(shell(), test_url1, 1); + + ShellAddedObserver new_shell_observer; + EXPECT_TRUE(ExecuteScript(shell()->web_contents(), + "window.open('about:blank','foo');")); + Shell* new_shell = new_shell_observer.GetShell(); + EXPECT_TRUE(new_shell->web_contents()->HasOpener()); + + agent_host_ = DevToolsAgentHost::GetOrCreateFor(new_shell->web_contents()); + agent_host_->AttachClient(this); + + GURL test_url2 = + embedded_test_server()->GetURL("B.com", "/devtools/navigation.html"); + + // After this navigation, if the bug exists, the process will crash. + NavigateToURLBlockUntilNavigationsComplete(new_shell, test_url2, 1); + + // Ensure that the A.com process is still alive by executing a script in the + // original tab. + // + // TODO(alexmos, nasko): A better way to do this is to navigate the original + // tab to another site, watch for process exit, and check whether there was a + // crash. However, currently there's no way to wait for process exit + // regardless of whether it's a crash or not. RenderProcessHostWatcher + // should be fixed to support waiting on both WATCH_FOR_PROCESS_EXIT and + // WATCH_FOR_HOST_DESTRUCTION, and then used here. + bool success = false; + EXPECT_TRUE(ExecuteScriptAndExtractBool(shell()->web_contents(), + "window.domAutomationController.send(" + " !!window.open('', 'foo'));", + &success)); + EXPECT_TRUE(success); +} + } // namespace content
diff --git a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc index 777f508..4f637605 100644 --- a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc +++ b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
@@ -17,7 +17,7 @@ #include "content/common/generic_shared_memory_id_generator.h" #include "content/common/gpu/client/gpu_memory_buffer_impl.h" #include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h" -#include "content/common/gpu/gpu_memory_buffer_factory_shared_memory.h" +#include "content/common/gpu/gpu_memory_buffer_factory.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/content_switches.h" #include "gpu/GLES2/gl2extchromium.h" @@ -47,31 +47,26 @@ FROM_HERE, base::Bind(destruction_callback, sync_point)); } -bool IsGpuMemoryBufferFactoryConfigurationSupported( - gfx::GpuMemoryBufferType type, - const GpuMemoryBufferFactory::Configuration& configuration) { - switch (type) { +bool IsNativeGpuMemoryBufferFactoryConfigurationSupported( + gfx::BufferFormat format, + gfx::BufferUsage usage) { + switch (GpuMemoryBufferFactory::GetNativeType()) { case gfx::SHARED_MEMORY_BUFFER: - return GpuMemoryBufferFactorySharedMemory:: - IsGpuMemoryBufferConfigurationSupported(configuration.format, - configuration.usage); + return false; #if defined(OS_MACOSX) case gfx::IO_SURFACE_BUFFER: return GpuMemoryBufferFactoryIOSurface:: - IsGpuMemoryBufferConfigurationSupported(configuration.format, - configuration.usage); + IsGpuMemoryBufferConfigurationSupported(format, usage); #endif #if defined(OS_ANDROID) case gfx::SURFACE_TEXTURE_BUFFER: return GpuMemoryBufferFactorySurfaceTexture:: - IsGpuMemoryBufferConfigurationSupported(configuration.format, - configuration.usage); + IsGpuMemoryBufferConfigurationSupported(format, usage); #endif #if defined(USE_OZONE) case gfx::OZONE_NATIVE_PIXMAP: return GpuMemoryBufferFactoryOzoneNativePixmap:: - IsGpuMemoryBufferConfigurationSupported(configuration.format, - configuration.usage); + IsGpuMemoryBufferConfigurationSupported(format, usage); #endif default: NOTREACHED(); @@ -79,18 +74,8 @@ } } -gfx::GpuMemoryBufferType GetGpuMemoryBufferFactoryType() { - std::vector<gfx::GpuMemoryBufferType> supported_types; - GpuMemoryBufferFactory::GetSupportedTypes(&supported_types); - DCHECK(!supported_types.empty()); - - // The GPU service will always use the preferred type. - return supported_types[0]; -} - -std::vector<GpuMemoryBufferFactory::Configuration> -GetSupportedGpuMemoryBufferConfigurations(gfx::GpuMemoryBufferType type) { - std::vector<GpuMemoryBufferFactory::Configuration> configurations; +GpuMemoryBufferConfigurationSet GetNativeGpuMemoryBufferConfigurations() { + GpuMemoryBufferConfigurationSet configurations; #if defined(OS_MACOSX) bool enable_native_gpu_memory_buffers = !base::CommandLine::ForCurrentProcess()->HasSwitch( @@ -101,45 +86,46 @@ switches::kEnableNativeGpuMemoryBuffers); #endif +#if defined(USE_OZONE) || defined(OS_MACOSX) + bool force_native_scanout_formats = true; +#else + bool force_native_scanout_formats = false; +#endif + // Disable native buffers when using Mesa. if (base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( switches::kUseGL) == gfx::kGLImplementationOSMesaName) { enable_native_gpu_memory_buffers = false; + force_native_scanout_formats = false; } if (enable_native_gpu_memory_buffers) { - const GpuMemoryBufferFactory::Configuration kNativeConfigurations[] = { - {gfx::BufferFormat::R_8, gfx::BufferUsage::MAP}, - {gfx::BufferFormat::R_8, gfx::BufferUsage::PERSISTENT_MAP}, - {gfx::BufferFormat::RGBA_4444, gfx::BufferUsage::MAP}, - {gfx::BufferFormat::RGBA_4444, gfx::BufferUsage::PERSISTENT_MAP}, - {gfx::BufferFormat::RGBA_8888, gfx::BufferUsage::MAP}, - {gfx::BufferFormat::RGBA_8888, gfx::BufferUsage::PERSISTENT_MAP}, - {gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::MAP}, - {gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::PERSISTENT_MAP}, - {gfx::BufferFormat::UYVY_422, gfx::BufferUsage::MAP}, - {gfx::BufferFormat::UYVY_422, gfx::BufferUsage::PERSISTENT_MAP}, - {gfx::BufferFormat::YUV_420_BIPLANAR, gfx::BufferUsage::MAP}, - {gfx::BufferFormat::YUV_420_BIPLANAR, gfx::BufferUsage::PERSISTENT_MAP}, - }; - for (auto& configuration : kNativeConfigurations) { - if (IsGpuMemoryBufferFactoryConfigurationSupported(type, configuration)) - configurations.push_back(configuration); + const gfx::BufferFormat kNativeFormats[] = { + gfx::BufferFormat::R_8, gfx::BufferFormat::RGBA_4444, + gfx::BufferFormat::RGBA_8888, gfx::BufferFormat::BGRA_8888, + gfx::BufferFormat::UYVY_422, gfx::BufferFormat::YUV_420_BIPLANAR}; + const gfx::BufferUsage kNativeUsages[] = {gfx::BufferUsage::MAP, + gfx::BufferUsage::PERSISTENT_MAP}; + for (auto& format : kNativeFormats) { + for (auto& usage : kNativeUsages) { + if (IsNativeGpuMemoryBufferFactoryConfigurationSupported(format, usage)) + configurations.insert(std::make_pair(format, usage)); + } } } -#if defined(USE_OZONE) || defined(OS_MACOSX) - const GpuMemoryBufferFactory::Configuration kScanoutConfigurations[] = { - {gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::SCANOUT}, - {gfx::BufferFormat::BGRX_8888, gfx::BufferUsage::SCANOUT}, - {gfx::BufferFormat::UYVY_422, gfx::BufferUsage::SCANOUT}, - {gfx::BufferFormat::YUV_420_BIPLANAR, gfx::BufferUsage::SCANOUT}, - }; - for (auto& configuration : kScanoutConfigurations) { - if (IsGpuMemoryBufferFactoryConfigurationSupported(type, configuration)) - configurations.push_back(configuration); + if (force_native_scanout_formats) { + const gfx::BufferFormat kScanoutFormats[] = { + gfx::BufferFormat::BGRA_8888, gfx::BufferFormat::BGRX_8888, + gfx::BufferFormat::UYVY_422, gfx::BufferFormat::YUV_420_BIPLANAR}; + for (auto& format : kScanoutFormats) { + if (IsNativeGpuMemoryBufferFactoryConfigurationSupported( + format, gfx::BufferUsage::SCANOUT)) { + configurations.insert( + std::make_pair(format, gfx::BufferUsage::SCANOUT)); + } + } } -#endif return configurations; } @@ -173,9 +159,7 @@ BrowserGpuMemoryBufferManager::BrowserGpuMemoryBufferManager( int gpu_client_id, uint64_t gpu_client_tracing_id) - : factory_type_(GetGpuMemoryBufferFactoryType()), - supported_configurations_( - GetSupportedGpuMemoryBufferConfigurations(factory_type_)), + : native_configurations_(GetNativeGpuMemoryBufferConfigurations()), gpu_client_id_(gpu_client_id), gpu_client_tracing_id_(gpu_client_tracing_id), gpu_host_id_(0) { @@ -196,25 +180,30 @@ uint32 BrowserGpuMemoryBufferManager::GetImageTextureTarget( gfx::BufferFormat format, gfx::BufferUsage usage) { - gfx::GpuMemoryBufferType type = GetGpuMemoryBufferFactoryType(); - for (auto& configuration : GetSupportedGpuMemoryBufferConfigurations(type)) { - if (configuration.format != format || configuration.usage != usage) - continue; - - switch (type) { - case gfx::SURFACE_TEXTURE_BUFFER: - case gfx::OZONE_NATIVE_PIXMAP: - // GPU memory buffers that are shared with the GL using EGLImages - // require TEXTURE_EXTERNAL_OES. - return GL_TEXTURE_EXTERNAL_OES; - case gfx::IO_SURFACE_BUFFER: - // IOSurface backed images require GL_TEXTURE_RECTANGLE_ARB. - return GL_TEXTURE_RECTANGLE_ARB; - default: - return GL_TEXTURE_2D; - } + GpuMemoryBufferConfigurationSet native_configurations = + GetNativeGpuMemoryBufferConfigurations(); + if (native_configurations.find(std::make_pair(format, usage)) == + native_configurations.end()) { + return GL_TEXTURE_2D; } + switch (GpuMemoryBufferFactory::GetNativeType()) { + case gfx::SURFACE_TEXTURE_BUFFER: + case gfx::OZONE_NATIVE_PIXMAP: + // GPU memory buffers that are shared with the GL using EGLImages + // require TEXTURE_EXTERNAL_OES. + return GL_TEXTURE_EXTERNAL_OES; + case gfx::IO_SURFACE_BUFFER: + // IOSurface backed images require GL_TEXTURE_RECTANGLE_ARB. + return GL_TEXTURE_RECTANGLE_ARB; + case gfx::SHARED_MEMORY_BUFFER: + return GL_TEXTURE_2D; + case gfx::EMPTY_BUFFER: + NOTREACHED(); + return GL_TEXTURE_2D; + } + + NOTREACHED(); return GL_TEXTURE_2D; } @@ -245,8 +234,8 @@ const AllocationCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - // Use service side allocation if this is a supported configuration. - if (IsGpuMemoryBufferConfigurationSupported(format, usage)) { + // Use service side allocation for native configurations. + if (IsNativeGpuMemoryBufferConfiguration(format, usage)) { AllocateGpuMemoryBufferOnIO(id, size, format, usage, child_client_id, 0, false, callback); return; @@ -391,14 +380,11 @@ return request.result.Pass(); } -bool BrowserGpuMemoryBufferManager::IsGpuMemoryBufferConfigurationSupported( +bool BrowserGpuMemoryBufferManager::IsNativeGpuMemoryBufferConfiguration( gfx::BufferFormat format, gfx::BufferUsage usage) const { - for (auto& configuration : supported_configurations_) { - if (configuration.format == format && configuration.usage == usage) - return true; - } - return false; + return native_configurations_.find(std::make_pair(format, usage)) != + native_configurations_.end(); } void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurfaceOnIO( @@ -407,9 +393,8 @@ gfx::GpuMemoryBufferId new_id = content::GetNextGenericSharedMemoryId(); - // Use service side allocation if this is a supported configuration. - if (IsGpuMemoryBufferConfigurationSupported(request->format, - request->usage)) { + // Use service side allocation for native configurations. + if (IsNativeGpuMemoryBufferConfiguration(request->format, request->usage)) { // Note: Unretained is safe as this is only used for synchronous allocation // from a non-IO thread. AllocateGpuMemoryBufferOnIO(
diff --git a/content/browser/gpu/browser_gpu_memory_buffer_manager.h b/content/browser/gpu/browser_gpu_memory_buffer_manager.h index 12fd082..4c27505 100644 --- a/content/browser/gpu/browser_gpu_memory_buffer_manager.h +++ b/content/browser/gpu/browser_gpu_memory_buffer_manager.h
@@ -5,16 +5,37 @@ #ifndef CONTENT_BROWSER_GPU_BROWSER_GPU_MEMORY_BUFFER_MANAGER_H_ #define CONTENT_BROWSER_GPU_BROWSER_GPU_MEMORY_BUFFER_MANAGER_H_ -#include <vector> +#include <utility> #include "base/callback.h" +#include "base/containers/hash_tables.h" #include "base/trace_event/memory_dump_provider.h" #include "content/common/content_export.h" -#include "content/common/gpu/gpu_memory_buffer_factory.h" #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" namespace content { +using GpuMemoryBufferConfigurationKey = + std::pair<gfx::BufferFormat, gfx::BufferUsage>; +using GpuMemoryBufferConfigurationSet = + base::hash_set<GpuMemoryBufferConfigurationKey>; + +} // content + +namespace BASE_HASH_NAMESPACE { + +template <> +struct hash<content::GpuMemoryBufferConfigurationKey> { + size_t operator()(const content::GpuMemoryBufferConfigurationKey& key) const { + return base::HashPair(static_cast<int>(key.first), + static_cast<int>(key.second)); + } +}; + +} // namespace BASE_HASH_NAMESPACE + +namespace content { + class CONTENT_EXPORT BrowserGpuMemoryBufferManager : public gpu::GpuMemoryBufferManager, public base::trace_event::MemoryDumpProvider { @@ -97,8 +118,8 @@ gfx::BufferFormat format, gfx::BufferUsage usage, int32 surface_id); - bool IsGpuMemoryBufferConfigurationSupported(gfx::BufferFormat format, - gfx::BufferUsage usage) const; + bool IsNativeGpuMemoryBufferConfiguration(gfx::BufferFormat format, + gfx::BufferUsage usage) const; void AllocateGpuMemoryBufferForSurfaceOnIO( AllocateGpuMemoryBufferRequest* request); void GpuMemoryBufferAllocatedForSurfaceOnIO( @@ -125,9 +146,7 @@ uint64_t ClientIdToTracingProcessId(int client_id) const; - const gfx::GpuMemoryBufferType factory_type_; - const std::vector<GpuMemoryBufferFactory::Configuration> - supported_configurations_; + const GpuMemoryBufferConfigurationSet native_configurations_; const int gpu_client_id_; const uint64_t gpu_client_tracing_id_;
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc index e0db04b..97ac7b5 100644 --- a/content/browser/indexed_db/indexed_db_backing_store.cc +++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -1090,8 +1090,10 @@ } LOG(ERROR) << "IndexedDB backing store cleanup succeeded, reopening"; - leveldb_factory->OpenLevelDB(file_path, comparator.get(), &db, NULL); - if (!db) { + *status = + leveldb_factory->OpenLevelDB(file_path, comparator.get(), &db, NULL); + if (!status->ok()) { + DCHECK(!db); LOG(ERROR) << "IndexedDB backing store reopen after recovery failed"; HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_FAILED, origin_url); @@ -1111,11 +1113,14 @@ task_runner, status); - if (clean_journal && backing_store.get() && - !backing_store->CleanUpBlobJournal(LiveBlobJournalKey::Encode()).ok()) { - HistogramOpenStatus( - INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR, origin_url); - return scoped_refptr<IndexedDBBackingStore>(); + if (clean_journal && backing_store.get()) { + *status = backing_store->CleanUpBlobJournal(LiveBlobJournalKey::Encode()); + if (!status->ok()) { + HistogramOpenStatus( + INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR, + origin_url); + return scoped_refptr<IndexedDBBackingStore>(); + } } return backing_store; }
diff --git a/content/browser/loader/cross_site_resource_handler.cc b/content/browser/loader/cross_site_resource_handler.cc index 0b9e6a77..45397357 100644 --- a/content/browser/loader/cross_site_resource_handler.cc +++ b/content/browser/loader/cross_site_resource_handler.cc
@@ -96,8 +96,10 @@ // Without a valid RFH against which to check, we must cancel the request, // to prevent the resource at |url| from being delivered to a potentially // unsuitable renderer process. + // TODO(nick): Switch this back to NavigationDecision::CANCEL once we fix + // existing transfer unittests that don't specify a valid rfh ID. if (!rfh) - return CrossSiteResourceHandler::NavigationDecision::CANCEL_REQUEST; + return CrossSiteResourceHandler::NavigationDecision::USE_EXISTING_RENDERER; RenderFrameHostManager* manager = rfh->frame_tree_node()->render_manager(); if (manager->IsRendererTransferNeededForNavigation(rfh, real_url))
diff --git a/content/browser/loader/cross_site_resource_handler_browsertest.cc b/content/browser/loader/cross_site_resource_handler_browsertest.cc index 4d66c1a..ba0f3cc 100644 --- a/content/browser/loader/cross_site_resource_handler_browsertest.cc +++ b/content/browser/loader/cross_site_resource_handler_browsertest.cc
@@ -239,8 +239,10 @@ // Regression test for https://crbug.com/538784 -- ensures that one can't // sidestep CrossSiteResourceHandler by detaching a frame mid-request. +// +// TODO(nick): Disabled until we re-land the fix for https://crbug.com/538784. IN_PROC_BROWSER_TEST_F(CrossSiteResourceHandlerTest, - NoDeliveryToDetachedFrame) { + DISABLED_NoDeliveryToDetachedFrame) { GURL attacker_page = embedded_test_server()->GetURL( "evil.com", "/cross_site_iframe_factory.html?evil(evil)"); EXPECT_TRUE(NavigateToURL(shell(), attacker_page));
diff --git a/content/browser/renderer_host/input/web_input_event_builders_mac.mm b/content/browser/renderer_host/input/web_input_event_builders_mac.mm index 00d34f8..1e116e84 100644 --- a/content/browser/renderer_host/input/web_input_event_builders_mac.mm +++ b/content/browser/renderer_host/input/web_input_event_builders_mac.mm
@@ -502,7 +502,7 @@ result->globalX = screen_local.x; // Flip y. NSScreen* primary_screen = ([[NSScreen screens] count] > 0) - ? [[NSScreen screens] objectAtIndex:0] + ? [[NSScreen screens] firstObject] : nil; if (primary_screen) result->globalY = [primary_screen frame].size.height - screen_local.y;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index dc03b79..0f7b2378 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1226,6 +1226,7 @@ switches::kDisableAcceleratedVideoDecode, switches::kDisableBlinkFeatures, switches::kDisableBreakpad, + switches::kDisableCompositorAnimationTimelines, switches::kDisablePreferCompositingToLCDText, switches::kDisableDatabases, switches::kDisableDelayAgnosticAec, @@ -1264,7 +1265,6 @@ switches::kDomAutomationController, switches::kEnableBlinkFeatures, switches::kEnableBrowserSideNavigation, - switches::kEnableCompositorAnimationTimelines, switches::kEnableCredentialManagerAPI, switches::kEnableDisplayList2dCanvas, switches::kEnableDistanceFieldText,
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index 8db1f59b..00c46f2 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -354,7 +354,7 @@ if (!g_screen_info_up_to_date) { if ([[NSScreen screens] count] > 0) { screen_zero_height = - [[[NSScreen screens] objectAtIndex:0] frame].size.height; + [[[NSScreen screens] firstObject] frame].size.height; g_screen_info_up_to_date = true; } else { return y;
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm index 9e1f792..5588f1f 100644 --- a/content/browser/web_contents/web_contents_view_mac.mm +++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -122,7 +122,7 @@ bounds.origin = [window convertBaseToScreen:bounds.origin]; // Flip y to account for screen flip. - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* screen = [[NSScreen screens] firstObject]; bounds.origin.y = [screen frame].size.height - bounds.origin.y - bounds.size.height; *out = gfx::Rect(NSRectToCGRect(bounds));
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.cc b/content/common/gpu/client/command_buffer_proxy_impl.cc index fc0cb83..cb509a83 100644 --- a/content/common/gpu/client/command_buffer_proxy_impl.cc +++ b/content/common/gpu/client/command_buffer_proxy_impl.cc
@@ -46,6 +46,9 @@ flush_count_(0), last_put_offset_(-1), last_barrier_put_offset_(-1), + next_fence_sync_release_(1), + flushed_fence_sync_release_(0), + verified_fence_sync_release_(0), next_signal_id_(0) { DCHECK(channel); } @@ -212,8 +215,18 @@ last_barrier_put_offset_ = put_offset; if (channel_) { - channel_->OrderingBarrier(route_id_, stream_id_, put_offset, ++flush_count_, - latency_info_, put_offset_changed, true); + const uint32_t flush_id = channel_->OrderingBarrier( + route_id_, stream_id_, put_offset, ++flush_count_, latency_info_, + put_offset_changed, true); + if (put_offset_changed) { + DCHECK(flush_id); + const uint64_t fence_sync_release = next_fence_sync_release_ - 1; + if (fence_sync_release > flushed_fence_sync_release_) { + flushed_fence_sync_release_ = fence_sync_release; + flushed_release_flush_id_.push( + std::make_pair(fence_sync_release, flush_id)); + } + } } if (put_offset_changed) @@ -231,8 +244,18 @@ last_barrier_put_offset_ = put_offset; if (channel_) { - channel_->OrderingBarrier(route_id_, stream_id_, put_offset, ++flush_count_, - latency_info_, put_offset_changed, false); + const uint32_t flush_id = channel_->OrderingBarrier( + route_id_, stream_id_, put_offset, ++flush_count_, latency_info_, + put_offset_changed, false); + if (put_offset_changed) { + DCHECK(flush_id); + const uint64_t fence_sync_release = next_fence_sync_release_ - 1; + if (fence_sync_release > flushed_fence_sync_release_) { + flushed_fence_sync_release_ = fence_sync_release; + flushed_release_flush_id_.push( + std::make_pair(fence_sync_release, flush_id)); + } + } } if (put_offset_changed) @@ -473,6 +496,38 @@ return command_buffer_id_; } +uint64_t CommandBufferProxyImpl::GenerateFenceSyncRelease() { + return next_fence_sync_release_++; +} + +bool CommandBufferProxyImpl::IsFenceSyncRelease(uint64_t release) { + return release != 0 && release < next_fence_sync_release_; +} + +bool CommandBufferProxyImpl::IsFenceSyncFlushed(uint64_t release) { + CheckLock(); + if (last_state_.error != gpu::error::kNoError) + return false; + + if (release <= verified_fence_sync_release_) + return true; + + // Check if we have actually flushed the fence sync release. + if (release <= flushed_fence_sync_release_) { + DCHECK(!flushed_release_flush_id_.empty()); + // Check if it has already been validated by another context. + UpdateVerifiedReleases(channel_->GetHighestValidatedFlushID(stream_id_)); + if (release <= verified_fence_sync_release_) + return true; + + // Has not been validated, validate it now. + UpdateVerifiedReleases(channel_->ValidateFlushIDReachedServer(stream_id_)); + return release <= verified_fence_sync_release_; + } + + return false; +} + uint32 CommandBufferProxyImpl::InsertSyncPoint() { CheckLock(); if (last_state_.error != gpu::error::kNoError) @@ -619,6 +674,17 @@ shared_state()->Read(&last_state_); } +void CommandBufferProxyImpl::UpdateVerifiedReleases(uint32_t verified_flush) { + while (!flushed_release_flush_id_.empty()) { + const std::pair<uint64_t, uint32_t>& front_item = + flushed_release_flush_id_.front(); + if (front_item.second > verified_flush) + break; + verified_fence_sync_release_ = front_item.first; + flushed_release_flush_id_.pop(); + } +} + gpu::CommandBufferSharedState* CommandBufferProxyImpl::shared_state() const { return reinterpret_cast<gpu::CommandBufferSharedState*>( shared_state_shm_->memory());
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.h b/content/common/gpu/client/command_buffer_proxy_impl.h index 98f8ed7..61ba775 100644 --- a/content/common/gpu/client/command_buffer_proxy_impl.h +++ b/content/common/gpu/client/command_buffer_proxy_impl.h
@@ -123,6 +123,9 @@ bool IsGpuChannelLost() override; gpu::CommandBufferNamespace GetNamespaceID() const override; uint64_t GetCommandBufferID() const override; + uint64_t GenerateFenceSyncRelease() override; + bool IsFenceSyncRelease(uint64_t release) override; + bool IsFenceSyncFlushed(uint64_t release) override; bool ProduceFrontBuffer(const gpu::Mailbox& mailbox); void SetContextLostCallback(const base::Closure& callback); @@ -191,6 +194,9 @@ // Try to read an updated copy of the state from shared memory. void TryUpdateState(); + // Updates the highest verified release fence sync. + void UpdateVerifiedReleases(uint32_t verified_flush); + // The shared memory area used to update state. gpu::CommandBufferSharedState* shared_state() const; @@ -215,6 +221,18 @@ int32 last_put_offset_; int32 last_barrier_put_offset_; + // Next generated fence sync. + uint64_t next_fence_sync_release_; + + // Unverified flushed fence syncs with their corresponding flush id. + std::queue<std::pair<uint64_t, uint32_t>> flushed_release_flush_id_; + + // Last flushed fence sync release, same as last item in queue if not empty. + uint64_t flushed_fence_sync_release_; + + // Last verified fence sync. + uint64_t verified_fence_sync_release_; + base::Closure context_lost_callback_; GpuConsoleMessageCallback console_message_callback_;
diff --git a/content/common/gpu/client/gpu_channel_host.cc b/content/common/gpu/client/gpu_channel_host.cc index a87051a..b637624 100644 --- a/content/common/gpu/client/gpu_channel_host.cc +++ b/content/common/gpu/client/gpu_channel_host.cc
@@ -35,10 +35,14 @@ } // namespace GpuChannelHost::StreamFlushInfo::StreamFlushInfo() - : flush_pending(false), + : next_stream_flush_id(1), + flushed_stream_flush_id(0), + verified_stream_flush_id(0), + flush_pending(false), route_id(MSG_ROUTING_NONE), put_offset(0), - flush_count(0) {} + flush_count(0), + flush_id(0) {} GpuChannelHost::StreamFlushInfo::~StreamFlushInfo() {} @@ -127,7 +131,7 @@ return result; } -void GpuChannelHost::OrderingBarrier( +uint32_t GpuChannelHost::OrderingBarrier( int32 route_id, int32 stream_id, int32 put_offset, @@ -138,30 +142,38 @@ AutoLock lock(context_lock_); StreamFlushInfo& flush_info = stream_flush_info_[stream_id]; if (flush_info.flush_pending && flush_info.route_id != route_id) - InternalFlush(stream_id); + InternalFlush(&flush_info); if (put_offset_changed) { + const uint32_t flush_id = flush_info.next_stream_flush_id++; flush_info.flush_pending = true; flush_info.route_id = route_id; flush_info.put_offset = put_offset; flush_info.flush_count = flush_count; + flush_info.flush_id = flush_id; flush_info.latency_info.insert(flush_info.latency_info.end(), latency_info.begin(), latency_info.end()); if (do_flush) - InternalFlush(stream_id); + InternalFlush(&flush_info); + + return flush_id; } + return 0; } -void GpuChannelHost::InternalFlush(int32 stream_id) { +void GpuChannelHost::InternalFlush(StreamFlushInfo* flush_info) { context_lock_.AssertAcquired(); - StreamFlushInfo& flush_info = stream_flush_info_[stream_id]; - DCHECK(flush_info.flush_pending); + DCHECK(flush_info); + DCHECK(flush_info->flush_pending); + DCHECK_LT(flush_info->flushed_stream_flush_id, flush_info->flush_id); Send(new GpuCommandBufferMsg_AsyncFlush( - flush_info.route_id, flush_info.put_offset, flush_info.flush_count, - flush_info.latency_info)); - flush_info.latency_info.clear(); - flush_info.flush_pending = false; + flush_info->route_id, flush_info->put_offset, flush_info->flush_count, + flush_info->latency_info)); + flush_info->latency_info.clear(); + flush_info->flush_pending = false; + + flush_info->flushed_stream_flush_id = flush_info->flush_id; } scoped_ptr<CommandBufferProxyImpl> GpuChannelHost::CreateViewCommandBuffer( @@ -290,8 +302,9 @@ RemoveRoute(route_id); AutoLock lock(context_lock_); - if (stream_flush_info_[stream_id].route_id == route_id) - stream_flush_info_.erase(stream_id); + StreamFlushInfo& flush_info = stream_flush_info_[stream_id]; + if (flush_info.flush_pending && flush_info.route_id == route_id) + flush_info.flush_pending = false; } void GpuChannelHost::DestroyChannel() { @@ -384,6 +397,62 @@ return next_stream_id_.GetNext(); } +uint32_t GpuChannelHost::ValidateFlushIDReachedServer(int32 stream_id) { + // Store what flush ids we will be validating for all streams. + base::hash_map<int32, uint32_t> validate_flushes; + uint32_t flushed_stream_flush_id = 0; + uint32_t verified_stream_flush_id = 0; + { + AutoLock lock(context_lock_); + for (const auto& iter : stream_flush_info_) { + const int32 iter_stream_id = iter.first; + const StreamFlushInfo& flush_info = iter.second; + if (iter_stream_id == stream_id) { + flushed_stream_flush_id = flush_info.flushed_stream_flush_id; + verified_stream_flush_id = flush_info.verified_stream_flush_id; + } + + if (flush_info.flushed_stream_flush_id > + flush_info.verified_stream_flush_id) { + validate_flushes.insert( + std::make_pair(iter_stream_id, flush_info.flushed_stream_flush_id)); + } + } + } + + if (flushed_stream_flush_id == verified_stream_flush_id) { + // Current stream has no unverified flushes. + return verified_stream_flush_id; + } + + if (Send(new GpuChannelMsg_Nop())) { + // Update verified flush id for all streams. + uint32_t highest_flush_id = 0; + AutoLock lock(context_lock_); + for (const auto& iter : validate_flushes) { + const int32 validated_stream_id = iter.first; + const uint32_t validated_flush_id = iter.second; + StreamFlushInfo& flush_info = stream_flush_info_[validated_stream_id]; + if (flush_info.verified_stream_flush_id < validated_flush_id) { + flush_info.verified_stream_flush_id = validated_flush_id; + } + + if (validated_stream_id == stream_id) + highest_flush_id = flush_info.verified_stream_flush_id; + } + + return highest_flush_id; + } + + return 0; +} + +uint32_t GpuChannelHost::GetHighestValidatedFlushID(int32 stream_id) { + AutoLock lock(context_lock_); + StreamFlushInfo& flush_info = stream_flush_info_[stream_id]; + return flush_info.verified_stream_flush_id; +} + GpuChannelHost::~GpuChannelHost() { #if DCHECK_IS_ON() AutoLock lock(context_lock_);
diff --git a/content/common/gpu/client/gpu_channel_host.h b/content/common/gpu/client/gpu_channel_host.h index 46dd9343..a161a78 100644 --- a/content/common/gpu/client/gpu_channel_host.h +++ b/content/common/gpu/client/gpu_channel_host.h
@@ -107,13 +107,14 @@ // Set an ordering barrier. AsyncFlushes any pending barriers on other // routes. Combines multiple OrderingBarriers into a single AsyncFlush. - void OrderingBarrier(int32 route_id, - int32 stream_id, - int32 put_offset, - uint32 flush_count, - const std::vector<ui::LatencyInfo>& latency_info, - bool put_offset_changed, - bool do_flush); + // Returns the flush ID for the stream or 0 if put offset was not changed. + uint32_t OrderingBarrier(int32 route_id, + int32 stream_id, + int32 put_offset, + uint32 flush_count, + const std::vector<ui::LatencyInfo>& latency_info, + bool put_offset_changed, + bool do_flush); // Create and connect to a command buffer in the GPU process. scoped_ptr<CommandBufferProxyImpl> CreateViewCommandBuffer( @@ -181,6 +182,19 @@ // Generate a stream ID guaranteed to be unique for this channel. int32 GenerateStreamID(); + // Sends a synchronous nop to the server which validate that all previous IPC + // messages have been received. Once the synchronous nop has been sent to the + // server all previous flushes will all be marked as validated, including + // flushes for other streams on the same channel. Once a validation has been + // sent, it will return the highest validated flush id for the stream. + // If the validation fails (which can only happen upon context lost), the + // highest validated flush id will not change. If no flush ID were ever + // validated then it will return 0 (Note the lowest valid flush ID is 1). + uint32_t ValidateFlushIDReachedServer(int32 stream_id); + + // Returns the highest validated flush ID for a given stream. + uint32_t GetHighestValidatedFlushID(int32 stream_id); + private: friend class base::RefCountedThreadSafe<GpuChannelHost>; @@ -234,10 +248,17 @@ StreamFlushInfo(); ~StreamFlushInfo(); + // These are global per stream. + uint32_t next_stream_flush_id; + uint32_t flushed_stream_flush_id; + uint32_t verified_stream_flush_id; + + // These are local per context. bool flush_pending; int32 route_id; int32 put_offset; uint32 flush_count; + uint32_t flush_id; std::vector<ui::LatencyInfo> latency_info; }; @@ -249,7 +270,7 @@ void Connect(const IPC::ChannelHandle& channel_handle, base::WaitableEvent* shutdown_event); bool InternalSend(IPC::Message* msg); - void InternalFlush(int32 stream_id); + void InternalFlush(StreamFlushInfo* flush_info); // Threading notes: all fields are constant during the lifetime of |this| // except:
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl.cc b/content/common/gpu/client/gpu_memory_buffer_impl.cc index 44c44a25..38107a5 100644 --- a/content/common/gpu/client/gpu_memory_buffer_impl.cc +++ b/content/common/gpu/client/gpu_memory_buffer_impl.cc
@@ -5,10 +5,7 @@ #include "content/common/gpu/client/gpu_memory_buffer_impl.h" #include "base/logging.h" -#include "base/numerics/safe_math.h" #include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h" -#include "ui/gfx/buffer_format_util.h" -#include "ui/gl/gl_bindings.h" #if defined(OS_MACOSX) #include "content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h" @@ -50,7 +47,7 @@ switch (handle.type) { case gfx::SHARED_MEMORY_BUFFER: return GpuMemoryBufferImplSharedMemory::CreateFromHandle( - handle, size, format, callback); + handle, size, format, usage, callback); #if defined(OS_MACOSX) case gfx::IO_SURFACE_BUFFER: return GpuMemoryBufferImplIOSurface::CreateFromHandle( @@ -59,7 +56,7 @@ #if defined(OS_ANDROID) case gfx::SURFACE_TEXTURE_BUFFER: return GpuMemoryBufferImplSurfaceTexture::CreateFromHandle( - handle, size, format, callback); + handle, size, format, usage, callback); #endif #if defined(USE_OZONE) case gfx::OZONE_NATIVE_PIXMAP:
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.cc b/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.cc index 7a3f044..13d2cc7 100644 --- a/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.cc +++ b/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.cc
@@ -5,6 +5,7 @@ #include "content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h" #include "base/logging.h" +#include "content/common/gpu/gpu_memory_buffer_factory_io_surface.h" #include "content/common/mac/io_surface_manager.h" #include "ui/gfx/buffer_format_util.h" @@ -24,6 +25,10 @@ return 0; } +void FreeIOSurfaceForTesting(gfx::GpuMemoryBufferId id) { + IOSurfaceManager::GetInstance()->UnregisterIOSurface(id, 0); +} + } // namespace GpuMemoryBufferImplIOSurface::GpuMemoryBufferImplIOSurface( @@ -41,7 +46,8 @@ } // static -scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImplIOSurface::CreateFromHandle( +scoped_ptr<GpuMemoryBufferImplIOSurface> +GpuMemoryBufferImplIOSurface::CreateFromHandle( const gfx::GpuMemoryBufferHandle& handle, const gfx::Size& size, gfx::BufferFormat format, @@ -52,11 +58,37 @@ if (!io_surface) return nullptr; - return make_scoped_ptr<GpuMemoryBufferImpl>( + return make_scoped_ptr( new GpuMemoryBufferImplIOSurface(handle.id, size, format, callback, io_surface.release(), LockFlags(usage))); } +// static +bool GpuMemoryBufferImplIOSurface::IsConfigurationSupported( + gfx::BufferFormat format, + gfx::BufferUsage usage) { + return GpuMemoryBufferFactoryIOSurface:: + IsGpuMemoryBufferConfigurationSupported(format, usage); +} + +// static +base::Closure GpuMemoryBufferImplIOSurface::AllocateForTesting( + const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + gfx::GpuMemoryBufferHandle* handle) { + base::ScopedCFTypeRef<IOSurfaceRef> io_surface( + GpuMemoryBufferFactoryIOSurface::CreateIOSurface(size, format)); + DCHECK(io_surface); + gfx::GpuMemoryBufferId kBufferId(1); + bool rv = IOSurfaceManager::GetInstance()->RegisterIOSurface(kBufferId, 0, + io_surface); + DCHECK(rv); + handle->type = gfx::IO_SURFACE_BUFFER; + handle->id = kBufferId; + return base::Bind(&FreeIOSurfaceForTesting, kBufferId); +} + bool GpuMemoryBufferImplIOSurface::Map(void** data) { DCHECK(!mapped_); IOReturn status = IOSurfaceLock(io_surface_, lock_flags_, NULL);
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h b/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h index d224938..d75c9d1e 100644 --- a/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h +++ b/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h
@@ -8,20 +8,31 @@ #include <IOSurface/IOSurface.h> #include "base/mac/scoped_cftyperef.h" +#include "content/common/content_export.h" #include "content/common/gpu/client/gpu_memory_buffer_impl.h" namespace content { // Implementation of GPU memory buffer based on IO surfaces. -class GpuMemoryBufferImplIOSurface : public GpuMemoryBufferImpl { +class CONTENT_EXPORT GpuMemoryBufferImplIOSurface : public GpuMemoryBufferImpl { public: - static scoped_ptr<GpuMemoryBufferImpl> CreateFromHandle( + ~GpuMemoryBufferImplIOSurface() override; + + static scoped_ptr<GpuMemoryBufferImplIOSurface> CreateFromHandle( const gfx::GpuMemoryBufferHandle& handle, const gfx::Size& size, gfx::BufferFormat format, gfx::BufferUsage usage, const DestructionCallback& callback); + static bool IsConfigurationSupported(gfx::BufferFormat format, + gfx::BufferUsage usage); + + static base::Closure AllocateForTesting(const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + gfx::GpuMemoryBufferHandle* handle); + // Overridden from gfx::GpuMemoryBuffer: bool Map(void** data) override; void Unmap() override; @@ -35,7 +46,6 @@ const DestructionCallback& callback, IOSurfaceRef io_surface, uint32_t lock_flags); - ~GpuMemoryBufferImplIOSurface() override; base::ScopedCFTypeRef<IOSurfaceRef> io_surface_; uint32_t lock_flags_;
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_io_surface_unittest.cc b/content/common/gpu/client/gpu_memory_buffer_impl_io_surface_unittest.cc new file mode 100644 index 0000000..83edce6 --- /dev/null +++ b/content/common/gpu/client/gpu_memory_buffer_impl_io_surface_unittest.cc
@@ -0,0 +1,16 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h" +#include "content/test/gpu_memory_buffer_impl_test_template.h" + +namespace content { +namespace { + +INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferImplIOSurface, + GpuMemoryBufferImplTest, + GpuMemoryBufferImplIOSurface); + +} // namespace +} // namespace content
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.cc b/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.cc index afeeb2ca4..8ebd1f8 100644 --- a/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.cc +++ b/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.cc
@@ -4,10 +4,21 @@ #include "content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.h" +#include "content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h" #include "ui/ozone/public/client_native_pixmap_factory.h" +#include "ui/ozone/public/native_pixmap.h" +#include "ui/ozone/public/ozone_platform.h" #include "ui/ozone/public/surface_factory_ozone.h" namespace content { +namespace { + +void FreeNativePixmapForTesting(scoped_refptr<ui::NativePixmap> native_pixmap) { + // Nothing to do here. |native_pixmap| will be freed when this function + // returns and reference count drops to 0. +} + +} // namespace GpuMemoryBufferImplOzoneNativePixmap::GpuMemoryBufferImplOzoneNativePixmap( gfx::GpuMemoryBufferId id, @@ -20,7 +31,7 @@ GpuMemoryBufferImplOzoneNativePixmap::~GpuMemoryBufferImplOzoneNativePixmap() {} // static -scoped_ptr<GpuMemoryBufferImpl> +scoped_ptr<GpuMemoryBufferImplOzoneNativePixmap> GpuMemoryBufferImplOzoneNativePixmap::CreateFromHandle( const gfx::GpuMemoryBufferHandle& handle, const gfx::Size& size, @@ -35,6 +46,29 @@ handle.id, size, format, callback, native_pixmap.Pass())); } +// static +bool GpuMemoryBufferImplOzoneNativePixmap::IsConfigurationSupported( + gfx::BufferFormat format, + gfx::BufferUsage usage) { + return GpuMemoryBufferFactoryOzoneNativePixmap:: + IsGpuMemoryBufferConfigurationSupported(format, usage); +} + +// static +base::Closure GpuMemoryBufferImplOzoneNativePixmap::AllocateForTesting( + const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + gfx::GpuMemoryBufferHandle* handle) { + scoped_refptr<ui::NativePixmap> pixmap = + ui::OzonePlatform::GetInstance() + ->GetSurfaceFactoryOzone() + ->CreateNativePixmap(gfx::kNullPluginWindow, size, format, usage); + handle->type = gfx::OZONE_NATIVE_PIXMAP; + handle->native_pixmap_handle = pixmap->ExportHandle(); + return base::Bind(&FreeNativePixmapForTesting, pixmap); +} + bool GpuMemoryBufferImplOzoneNativePixmap::Map(void** data) { *data = pixmap_->Map(); mapped_ = true;
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.h b/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.h index 74f1bfe..f129ddd 100644 --- a/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.h +++ b/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.h
@@ -5,6 +5,7 @@ #ifndef CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_OZONE_NATIVE_PIXMAP_H_ #define CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_OZONE_NATIVE_PIXMAP_H_ +#include "content/common/content_export.h" #include "content/common/gpu/client/gpu_memory_buffer_impl.h" namespace ui { @@ -14,17 +15,26 @@ namespace content { // Implementation of GPU memory buffer based on Ozone native pixmap. -class GpuMemoryBufferImplOzoneNativePixmap : public GpuMemoryBufferImpl { +class CONTENT_EXPORT GpuMemoryBufferImplOzoneNativePixmap + : public GpuMemoryBufferImpl { public: ~GpuMemoryBufferImplOzoneNativePixmap() override; - static scoped_ptr<GpuMemoryBufferImpl> CreateFromHandle( + static scoped_ptr<GpuMemoryBufferImplOzoneNativePixmap> CreateFromHandle( const gfx::GpuMemoryBufferHandle& handle, const gfx::Size& size, gfx::BufferFormat format, gfx::BufferUsage usage, const DestructionCallback& callback); + static bool IsConfigurationSupported(gfx::BufferFormat format, + gfx::BufferUsage usage); + + static base::Closure AllocateForTesting(const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + gfx::GpuMemoryBufferHandle* handle); + // Overridden from gfx::GpuMemoryBuffer: bool Map(void** data) override; void Unmap() override;
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap_unittest.cc b/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap_unittest.cc new file mode 100644 index 0000000..08295c51 --- /dev/null +++ b/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap_unittest.cc
@@ -0,0 +1,16 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap.h" +#include "content/test/gpu_memory_buffer_impl_test_template.h" + +namespace content { +namespace { + +INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferImplOzoneNativePixmap, + GpuMemoryBufferImplTest, + GpuMemoryBufferImplOzoneNativePixmap); + +} // namespace +} // namespace content
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc b/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc index efa641b7..02437ff 100644 --- a/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc +++ b/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc
@@ -11,6 +11,11 @@ #include "ui/gl/gl_bindings.h" namespace content { +namespace { + +void Noop() {} + +} // namespace GpuMemoryBufferImplSharedMemory::GpuMemoryBufferImplSharedMemory( gfx::GpuMemoryBufferId id, @@ -28,11 +33,11 @@ } // static -scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImplSharedMemory::Create( - gfx::GpuMemoryBufferId id, - const gfx::Size& size, - gfx::BufferFormat format, - const DestructionCallback& callback) { +scoped_ptr<GpuMemoryBufferImplSharedMemory> +GpuMemoryBufferImplSharedMemory::Create(gfx::GpuMemoryBufferId id, + const gfx::Size& size, + gfx::BufferFormat format, + const DestructionCallback& callback) { size_t buffer_size = 0u; if (!gfx::BufferSizeForBufferFormatChecked(size, format, &buffer_size)) return nullptr; @@ -68,11 +73,12 @@ } // static -scoped_ptr<GpuMemoryBufferImpl> +scoped_ptr<GpuMemoryBufferImplSharedMemory> GpuMemoryBufferImplSharedMemory::CreateFromHandle( const gfx::GpuMemoryBufferHandle& handle, const gfx::Size& size, gfx::BufferFormat format, + gfx::BufferUsage usage, const DestructionCallback& callback) { if (!base::SharedMemory::IsHandleValid(handle.handle)) return nullptr; @@ -83,13 +89,8 @@ if (!shared_memory->Map(buffer_size)) base::TerminateBecauseOutOfMemory(buffer_size); - return make_scoped_ptr<GpuMemoryBufferImpl>( - new GpuMemoryBufferImplSharedMemory( - handle.id, - size, - format, - callback, - shared_memory.Pass())); + return make_scoped_ptr(new GpuMemoryBufferImplSharedMemory( + handle.id, size, format, callback, shared_memory.Pass())); } // static @@ -131,6 +132,13 @@ } // static +bool GpuMemoryBufferImplSharedMemory::IsConfigurationSupported( + gfx::BufferFormat format, + gfx::BufferUsage usage) { + return IsFormatSupported(format) && IsUsageSupported(usage); +} + +// static bool GpuMemoryBufferImplSharedMemory::IsSizeValidForFormat( const gfx::Size& size, gfx::BufferFormat format) { @@ -167,6 +175,21 @@ return false; } +// static +base::Closure GpuMemoryBufferImplSharedMemory::AllocateForTesting( + const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + gfx::GpuMemoryBufferHandle* handle) { + base::SharedMemory shared_memory; + bool rv = shared_memory.CreateAnonymous( + gfx::BufferSizeForBufferFormat(size, format)); + DCHECK(rv); + handle->type = gfx::SHARED_MEMORY_BUFFER; + handle->handle = base::SharedMemory::DuplicateHandle(shared_memory.handle()); + return base::Bind(&Noop); +} + bool GpuMemoryBufferImplSharedMemory::Map(void** data) { DCHECK(!mapped_); size_t offset = 0;
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h b/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h index fedeae7..c3c39b9 100644 --- a/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h +++ b/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h
@@ -5,16 +5,18 @@ #ifndef CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_SHARED_MEMORY_H_ #define CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_SHARED_MEMORY_H_ +#include "content/common/content_export.h" #include "content/common/gpu/client/gpu_memory_buffer_impl.h" namespace content { // Implementation of GPU memory buffer based on shared memory. -class GpuMemoryBufferImplSharedMemory : public GpuMemoryBufferImpl { +class CONTENT_EXPORT GpuMemoryBufferImplSharedMemory + : public GpuMemoryBufferImpl { public: ~GpuMemoryBufferImplSharedMemory() override; - static scoped_ptr<GpuMemoryBufferImpl> Create( + static scoped_ptr<GpuMemoryBufferImplSharedMemory> Create( gfx::GpuMemoryBufferId id, const gfx::Size& size, gfx::BufferFormat format, @@ -26,17 +28,25 @@ gfx::BufferFormat format, base::ProcessHandle child_process); - static scoped_ptr<GpuMemoryBufferImpl> CreateFromHandle( + static scoped_ptr<GpuMemoryBufferImplSharedMemory> CreateFromHandle( const gfx::GpuMemoryBufferHandle& handle, const gfx::Size& size, gfx::BufferFormat format, + gfx::BufferUsage usage, const DestructionCallback& callback); static bool IsFormatSupported(gfx::BufferFormat format); static bool IsUsageSupported(gfx::BufferUsage usage); + static bool IsConfigurationSupported(gfx::BufferFormat format, + gfx::BufferUsage usage); static bool IsSizeValidForFormat(const gfx::Size& size, gfx::BufferFormat format); + static base::Closure AllocateForTesting(const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + gfx::GpuMemoryBufferHandle* handle); + // Overridden from gfx::GpuMemoryBuffer: bool Map(void** data) override; void Unmap() override;
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory_unittest.cc b/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory_unittest.cc new file mode 100644 index 0000000..06262ce --- /dev/null +++ b/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory_unittest.cc
@@ -0,0 +1,43 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h" +#include "content/test/gpu_memory_buffer_impl_test_template.h" + +namespace content { +namespace { + +INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferImplSharedMemory, + GpuMemoryBufferImplTest, + GpuMemoryBufferImplSharedMemory); + +void BufferDestroyed(bool* destroyed, uint32 sync_point) { + *destroyed = true; +} + +TEST(GpuMemoryBufferImplSharedMemoryTest, Create) { + const gfx::GpuMemoryBufferId kBufferId(1); + + gfx::Size buffer_size(8, 8); + + for (auto format : gfx::GetBufferFormats()) { + if (!GpuMemoryBufferImplSharedMemory::IsFormatSupported(format)) + continue; + + bool destroyed = false; + scoped_ptr<GpuMemoryBufferImplSharedMemory> buffer( + GpuMemoryBufferImplSharedMemory::Create( + kBufferId, buffer_size, format, + base::Bind(&BufferDestroyed, base::Unretained(&destroyed)))); + ASSERT_TRUE(buffer); + EXPECT_EQ(buffer->GetFormat(), format); + + // Check if destruction callback is executed when deleting the buffer. + buffer.reset(); + ASSERT_TRUE(destroyed); + } +} + +} // namespace +} // namespace content
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc b/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc index b3471d1..6449f99e 100644 --- a/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc +++ b/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc
@@ -7,7 +7,9 @@ #include "base/logging.h" #include "base/trace_event/trace_event.h" #include "content/common/android/surface_texture_manager.h" +#include "content/common/gpu/gpu_memory_buffer_factory_surface_texture.h" #include "ui/gfx/buffer_format_util.h" +#include "ui/gl/android/surface_texture.h" #include "ui/gl/gl_bindings.h" namespace content { @@ -37,6 +39,12 @@ return 0; } +void FreeSurfaceTextureForTesting( + scoped_refptr<gfx::SurfaceTexture> surface_texture, + gfx::GpuMemoryBufferId id) { + SurfaceTextureManager::GetInstance()->UnregisterSurfaceTexture(id.id, 0); +} + } // namespace GpuMemoryBufferImplSurfaceTexture::GpuMemoryBufferImplSurfaceTexture( @@ -54,24 +62,49 @@ } // static -scoped_ptr<GpuMemoryBufferImpl> +scoped_ptr<GpuMemoryBufferImplSurfaceTexture> GpuMemoryBufferImplSurfaceTexture::CreateFromHandle( const gfx::GpuMemoryBufferHandle& handle, const gfx::Size& size, gfx::BufferFormat format, + gfx::BufferUsage usage, const DestructionCallback& callback) { ANativeWindow* native_window = SurfaceTextureManager::GetInstance() ->AcquireNativeWidgetForSurfaceTexture(handle.id.id); if (!native_window) - return scoped_ptr<GpuMemoryBufferImpl>(); + return nullptr; ANativeWindow_setBuffersGeometry( native_window, size.width(), size.height(), WindowFormat(format)); - return make_scoped_ptr<GpuMemoryBufferImpl>( - new GpuMemoryBufferImplSurfaceTexture( - handle.id, size, format, callback, native_window)); + return make_scoped_ptr(new GpuMemoryBufferImplSurfaceTexture( + handle.id, size, format, callback, native_window)); +} + +// static +bool GpuMemoryBufferImplSurfaceTexture::IsConfigurationSupported( + gfx::BufferFormat format, + gfx::BufferUsage usage) { + return GpuMemoryBufferFactorySurfaceTexture:: + IsGpuMemoryBufferConfigurationSupported(format, usage); +} + +// static +base::Closure GpuMemoryBufferImplSurfaceTexture::AllocateForTesting( + const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + gfx::GpuMemoryBufferHandle* handle) { + scoped_refptr<gfx::SurfaceTexture> surface_texture = + gfx::SurfaceTexture::Create(0); + DCHECK(surface_texture); + gfx::GpuMemoryBufferId kBufferId(1); + SurfaceTextureManager::GetInstance()->RegisterSurfaceTexture( + kBufferId.id, 0, surface_texture.get()); + handle->type = gfx::SURFACE_TEXTURE_BUFFER; + handle->id = kBufferId; + return base::Bind(&FreeSurfaceTextureForTesting, surface_texture, kBufferId); } bool GpuMemoryBufferImplSurfaceTexture::Map(void** data) {
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h b/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h index 244d160b..959976f 100644 --- a/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h +++ b/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h
@@ -5,6 +5,7 @@ #ifndef CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_SURFACE_TEXTURE_H_ #define CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_SURFACE_TEXTURE_H_ +#include "content/common/content_export.h" #include "content/common/gpu/client/gpu_memory_buffer_impl.h" struct ANativeWindow; @@ -12,14 +13,26 @@ namespace content { // Implementation of GPU memory buffer based on SurfaceTextures. -class GpuMemoryBufferImplSurfaceTexture : public GpuMemoryBufferImpl { +class CONTENT_EXPORT GpuMemoryBufferImplSurfaceTexture + : public GpuMemoryBufferImpl { public: - static scoped_ptr<GpuMemoryBufferImpl> CreateFromHandle( + ~GpuMemoryBufferImplSurfaceTexture() override; + + static scoped_ptr<GpuMemoryBufferImplSurfaceTexture> CreateFromHandle( const gfx::GpuMemoryBufferHandle& handle, const gfx::Size& size, gfx::BufferFormat format, + gfx::BufferUsage usage, const DestructionCallback& callback); + static bool IsConfigurationSupported(gfx::BufferFormat format, + gfx::BufferUsage usage); + + static base::Closure AllocateForTesting(const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + gfx::GpuMemoryBufferHandle* handle); + // Overridden from gfx::GpuMemoryBuffer: bool Map(void** data) override; void Unmap() override; @@ -32,7 +45,6 @@ gfx::BufferFormat format, const DestructionCallback& callback, ANativeWindow* native_window); - ~GpuMemoryBufferImplSurfaceTexture() override; ANativeWindow* native_window_; size_t stride_;
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture_unittest.cc b/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture_unittest.cc new file mode 100644 index 0000000..1cd513d --- /dev/null +++ b/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture_unittest.cc
@@ -0,0 +1,16 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h" +#include "content/test/gpu_memory_buffer_impl_test_template.h" + +namespace content { +namespace { + +INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferImplSurfaceTexture, + GpuMemoryBufferImplTest, + GpuMemoryBufferImplSurfaceTexture); + +} // namespace +} // namespace content
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_unittest.cc b/content/common/gpu/client/gpu_memory_buffer_impl_unittest.cc deleted file mode 100644 index 587c024..0000000 --- a/content/common/gpu/client/gpu_memory_buffer_impl_unittest.cc +++ /dev/null
@@ -1,240 +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 "content/common/gpu/client/gpu_memory_buffer_impl.h" - -#include "base/bind.h" -#include "content/common/gpu/gpu_memory_buffer_factory.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/gfx/buffer_format_util.h" - -namespace content { -namespace { - -const int kClientId = 1; - -class GpuMemoryBufferImplTest - : public testing::TestWithParam<gfx::GpuMemoryBufferType> { - public: - GpuMemoryBufferImplTest() : buffer_count_(0), factory_(nullptr) {} - - // Overridden from testing::Test: - void SetUp() override { - factory_ = GpuMemoryBufferFactory::Create(GetParam()); - factory_->GetSupportedGpuMemoryBufferConfigurations( - &supported_configurations_); - } - void TearDown() override { factory_.reset(); } - - gfx::GpuMemoryBufferHandle CreateGpuMemoryBuffer(gfx::GpuMemoryBufferId id, - const gfx::Size& size, - gfx::BufferFormat format, - gfx::BufferUsage usage) { - ++buffer_count_; - return factory_->CreateGpuMemoryBuffer(id, size, format, usage, kClientId, - gfx::kNullPluginWindow); - } - - void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, uint32 sync_point) { - factory_->DestroyGpuMemoryBuffer(id, kClientId); - DCHECK_GT(buffer_count_, 0); - --buffer_count_; - } - - std::vector<GpuMemoryBufferFactory::Configuration> supported_configurations_; - int buffer_count_; - - private: - scoped_ptr<GpuMemoryBufferFactory> factory_; -}; - -TEST_P(GpuMemoryBufferImplTest, CreateFromHandle) { - const gfx::GpuMemoryBufferId kBufferId(1); - - gfx::Size buffer_size(8, 8); - - for (auto configuration : supported_configurations_) { - scoped_ptr<GpuMemoryBufferImpl> buffer( - GpuMemoryBufferImpl::CreateFromHandle( - CreateGpuMemoryBuffer(kBufferId, buffer_size, configuration.format, - configuration.usage), - buffer_size, configuration.format, configuration.usage, - base::Bind(&GpuMemoryBufferImplTest::DestroyGpuMemoryBuffer, - base::Unretained(this), kBufferId))); - EXPECT_EQ(1, buffer_count_); - ASSERT_TRUE(buffer); - EXPECT_EQ(buffer->GetFormat(), configuration.format); - - // Check if destruction callback is executed when deleting the buffer. - buffer.reset(); - EXPECT_EQ(0, buffer_count_); - } -} - -TEST_P(GpuMemoryBufferImplTest, Map) { - const gfx::GpuMemoryBufferId kBufferId(1); - - // Use a multiple of 4 for both dimensions to support compressed formats. - gfx::Size buffer_size(4, 4); - - for (auto configuration : supported_configurations_) { - if (configuration.usage != gfx::BufferUsage::MAP) - continue; - - scoped_ptr<GpuMemoryBufferImpl> buffer( - GpuMemoryBufferImpl::CreateFromHandle( - CreateGpuMemoryBuffer(kBufferId, buffer_size, configuration.format, - configuration.usage), - buffer_size, configuration.format, configuration.usage, - base::Bind(&GpuMemoryBufferImplTest::DestroyGpuMemoryBuffer, - base::Unretained(this), kBufferId))); - ASSERT_TRUE(buffer); - EXPECT_FALSE(buffer->IsMapped()); - - size_t num_planes = - gfx::NumberOfPlanesForBufferFormat(configuration.format); - - // Map buffer into user space. - scoped_ptr<void*[]> mapped_buffers(new void*[num_planes]); - bool rv = buffer->Map(mapped_buffers.get()); - ASSERT_TRUE(rv); - EXPECT_TRUE(buffer->IsMapped()); - - // Get strides. - scoped_ptr<int[]> strides(new int[num_planes]); - buffer->GetStride(strides.get()); - - // Copy and compare mapped buffers. - for (size_t plane = 0; plane < num_planes; ++plane) { - size_t row_size_in_bytes = 0; - EXPECT_TRUE(gfx::RowSizeForBufferFormatChecked( - buffer_size.width(), configuration.format, plane, - &row_size_in_bytes)); - EXPECT_GT(row_size_in_bytes, 0u); - - scoped_ptr<char[]> data(new char[row_size_in_bytes]); - memset(data.get(), 0x2a + plane, row_size_in_bytes); - - size_t height = - buffer_size.height() / - gfx::SubsamplingFactorForBufferFormat(configuration.format, plane); - for (size_t y = 0; y < height; ++y) { - memcpy(static_cast<char*>(mapped_buffers[plane]) + y * strides[plane], - data.get(), row_size_in_bytes); - EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers[plane]) + - y * strides[plane], - data.get(), row_size_in_bytes), - 0); - } - } - - buffer->Unmap(); - EXPECT_FALSE(buffer->IsMapped()); - } -} - -TEST_P(GpuMemoryBufferImplTest, PersistentMap) { - const gfx::GpuMemoryBufferId kBufferId(1); - - // Use a multiple of 4 for both dimensions to support compressed formats. - gfx::Size buffer_size(4, 4); - - for (auto configuration : supported_configurations_) { - if (configuration.usage != gfx::BufferUsage::PERSISTENT_MAP) - continue; - - scoped_ptr<GpuMemoryBufferImpl> buffer( - GpuMemoryBufferImpl::CreateFromHandle( - CreateGpuMemoryBuffer(kBufferId, buffer_size, configuration.format, - configuration.usage), - buffer_size, configuration.format, configuration.usage, - base::Bind(&GpuMemoryBufferImplTest::DestroyGpuMemoryBuffer, - base::Unretained(this), kBufferId))); - ASSERT_TRUE(buffer); - EXPECT_FALSE(buffer->IsMapped()); - - size_t num_planes = - gfx::NumberOfPlanesForBufferFormat(configuration.format); - - // Map buffer into user space. - scoped_ptr<void* []> mapped_buffers(new void* [num_planes]); - bool rv = buffer->Map(mapped_buffers.get()); - ASSERT_TRUE(rv); - EXPECT_TRUE(buffer->IsMapped()); - - // Get strides. - scoped_ptr<int[]> strides(new int[num_planes]); - buffer->GetStride(strides.get()); - - // Copy and compare mapped buffers. - for (size_t plane = 0; plane < num_planes; ++plane) { - size_t row_size_in_bytes; - EXPECT_TRUE(gfx::RowSizeForBufferFormatChecked( - buffer_size.width(), configuration.format, plane, - &row_size_in_bytes)); - - scoped_ptr<char[]> data(new char[row_size_in_bytes]); - memset(data.get(), 0x2a + plane, row_size_in_bytes); - - size_t height = - buffer_size.height() / - gfx::SubsamplingFactorForBufferFormat(configuration.format, plane); - for (size_t y = 0; y < height; ++y) { - memcpy(static_cast<char*>(mapped_buffers[plane]) + y * strides[plane], - data.get(), row_size_in_bytes); - EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers[plane]) + - y * strides[plane], - data.get(), row_size_in_bytes), - 0); - } - } - - buffer->Unmap(); - EXPECT_FALSE(buffer->IsMapped()); - - // Remap the buffer, and compare again. It should contain the same data. - rv = buffer->Map(mapped_buffers.get()); - ASSERT_TRUE(rv); - EXPECT_TRUE(buffer->IsMapped()); - - buffer->GetStride(strides.get()); - - for (size_t plane = 0; plane < num_planes; ++plane) { - size_t row_size_in_bytes; - EXPECT_TRUE(gfx::RowSizeForBufferFormatChecked( - buffer_size.width(), configuration.format, plane, - &row_size_in_bytes)); - - scoped_ptr<char[]> data(new char[row_size_in_bytes]); - memset(data.get(), 0x2a + plane, row_size_in_bytes); - - size_t height = - buffer_size.height() / - gfx::SubsamplingFactorForBufferFormat(configuration.format, plane); - for (size_t y = 0; y < height; ++y) { - EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers[plane]) + - y * strides[plane], - data.get(), row_size_in_bytes), - 0); - } - } - - buffer->Unmap(); - EXPECT_FALSE(buffer->IsMapped()); - } -} - -std::vector<gfx::GpuMemoryBufferType> GetSupportedGpuMemoryBufferTypes() { - std::vector<gfx::GpuMemoryBufferType> supported_types; - GpuMemoryBufferFactory::GetSupportedTypes(&supported_types); - return supported_types; -} - -INSTANTIATE_TEST_CASE_P( - GpuMemoryBufferImplTests, - GpuMemoryBufferImplTest, - ::testing::ValuesIn(GetSupportedGpuMemoryBufferTypes())); - -} // namespace -} // namespace content
diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc index 4a43a752..acff5d4 100644 --- a/content/common/gpu/gpu_channel.cc +++ b/content/common/gpu/gpu_channel.cc
@@ -76,16 +76,16 @@ return new GpuChannelMessageQueue(gpu_channel, task_runner); } -scoped_refptr<gpu::SyncPointClientState> - GpuChannelMessageQueue::GetSyncPointClientState() { - return sync_point_client_state_; +scoped_refptr<gpu::SyncPointOrderData> +GpuChannelMessageQueue::GetSyncPointOrderData() { + return sync_point_order_data_; } GpuChannelMessageQueue::GpuChannelMessageQueue( const base::WeakPtr<GpuChannel>& gpu_channel, base::SingleThreadTaskRunner* task_runner) : enabled_(true), - sync_point_client_state_(gpu::SyncPointClientState::Create()), + sync_point_order_data_(gpu::SyncPointOrderData::Create()), gpu_channel_(gpu_channel), task_runner_(task_runner) {} @@ -94,11 +94,11 @@ } uint32_t GpuChannelMessageQueue::GetUnprocessedOrderNum() const { - return sync_point_client_state_->unprocessed_order_num(); + return sync_point_order_data_->unprocessed_order_num(); } uint32_t GpuChannelMessageQueue::GetProcessedOrderNum() const { - return sync_point_client_state_->processed_order_num(); + return sync_point_order_data_->processed_order_num(); } void GpuChannelMessageQueue::PushBackMessage( @@ -147,9 +147,9 @@ base::AutoLock auto_lock(channel_messages_lock_); if (!channel_messages_.empty()) { DCHECK_GT(channel_messages_.front()->order_number, - sync_point_client_state_->processed_order_num()); + sync_point_order_data_->processed_order_num()); DCHECK_LE(channel_messages_.front()->order_number, - sync_point_client_state_->unprocessed_order_num()); + sync_point_order_data_->unprocessed_order_num()); return channel_messages_.front(); } @@ -158,7 +158,7 @@ void GpuChannelMessageQueue::BeginMessageProcessing( const GpuChannelMessage* msg) { - sync_point_client_state_->BeginProcessingOrderNumber(msg->order_number); + sync_point_order_data_->BeginProcessingOrderNumber(msg->order_number); } bool GpuChannelMessageQueue::MessageProcessed() { @@ -166,7 +166,7 @@ DCHECK(!channel_messages_.empty()); scoped_ptr<GpuChannelMessage> msg(channel_messages_.front()); channel_messages_.pop_front(); - sync_point_client_state_->FinishProcessingOrderNumber(msg->order_number); + sync_point_order_data_->FinishProcessingOrderNumber(msg->order_number); return !channel_messages_.empty(); } @@ -193,6 +193,11 @@ msg->sync_point); } } + + if (sync_point_order_data_) { + sync_point_order_data_->Destroy(); + sync_point_order_data_ = nullptr; + } } void GpuChannelMessageQueue::ScheduleHandleMessage() { @@ -206,9 +211,8 @@ channel_messages_lock_.AssertAcquired(); DCHECK(enabled_); - msg->order_number = - sync_point_client_state_->GenerateUnprocessedOrderNumber( - sync_point_manager); + msg->order_number = sync_point_order_data_->GenerateUnprocessedOrderNumber( + sync_point_manager); msg->time_received = base::TimeTicks::Now(); bool had_messages = !channel_messages_.empty(); @@ -301,6 +305,12 @@ return true; } + if (message.type() == GpuChannelMsg_Nop::ID) { + IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message); + Send(reply); + return true; + } + for (scoped_refptr<IPC::MessageFilter>& filter : channel_filters_) { if (filter->OnMessageReceived(message)) { return true; @@ -788,8 +798,8 @@ return handled; } -scoped_refptr<gpu::SyncPointClientState> GpuChannel::GetSyncPointClientState() { - return message_queue_->GetSyncPointClientState(); +scoped_refptr<gpu::SyncPointOrderData> GpuChannel::GetSyncPointOrderData() { + return message_queue_->GetSyncPointOrderData(); } void GpuChannel::HandleMessage() {
diff --git a/content/common/gpu/gpu_channel.h b/content/common/gpu/gpu_channel.h index 69c49eb..53b706b 100644 --- a/content/common/gpu/gpu_channel.h +++ b/content/common/gpu/gpu_channel.h
@@ -36,7 +36,7 @@ namespace gpu { class PreemptionFlag; -class SyncPointClientState; +class SyncPointOrderData; class SyncPointManager; union ValueState; class ValueStateMap; @@ -172,8 +172,8 @@ // Returns the global order number for the last unprocessed IPC message. uint32_t GetUnprocessedOrderNum() const; - // Returns the shared sync point client state. - scoped_refptr<gpu::SyncPointClientState> GetSyncPointClientState(); + // Returns the shared sync point global order data. + scoped_refptr<gpu::SyncPointOrderData> GetSyncPointOrderData(); void HandleMessage(); @@ -410,7 +410,7 @@ const base::WeakPtr<GpuChannel>& gpu_channel, base::SingleThreadTaskRunner* task_runner); - scoped_refptr<gpu::SyncPointClientState> GetSyncPointClientState(); + scoped_refptr<gpu::SyncPointOrderData> GetSyncPointOrderData(); // Returns the global order number for the last unprocessed IPC message. uint32_t GetUnprocessedOrderNum() const; @@ -461,7 +461,7 @@ mutable base::Lock channel_messages_lock_; // Keeps track of sync point related state such as message order numbers. - scoped_refptr<gpu::SyncPointClientState> sync_point_client_state_; + scoped_refptr<gpu::SyncPointOrderData> sync_point_order_data_; base::WeakPtr<GpuChannel> gpu_channel_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc index 6f49445..381f354a 100644 --- a/content/common/gpu/gpu_command_buffer_stub.cc +++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -536,11 +536,9 @@ scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), decoder_.get(), decoder_.get())); - sync_point_client_ = - sync_point_manager->CreateSyncPointClient( - channel_->GetSyncPointClientState(), - gpu::CommandBufferNamespace::GPU_IO, - command_buffer_id_); + sync_point_client_ = sync_point_manager->CreateSyncPointClient( + channel_->GetSyncPointOrderData(), gpu::CommandBufferNamespace::GPU_IO, + command_buffer_id_); if (preemption_flag_.get()) scheduler_->SetPreemptByFlag(preemption_flag_); @@ -645,6 +643,10 @@ decoder_->SetWaitSyncPointCallback( base::Bind(&GpuCommandBufferStub::OnWaitSyncPoint, base::Unretained(this))); + decoder_->SetFenceSyncReleaseCallback(base::Bind( + &GpuCommandBufferStub::OnFenceSyncRelease, base::Unretained(this))); + decoder_->SetWaitFenceSyncCallback(base::Bind( + &GpuCommandBufferStub::OnWaitFenceSync, base::Unretained(this))); command_buffer_->SetPutOffsetChangeCallback( base::Bind(&GpuCommandBufferStub::PutChanged, base::Unretained(this))); @@ -933,8 +935,15 @@ gpu::gles2::MailboxManager* mailbox_manager = context_group_->mailbox_manager(); - if (mailbox_manager->UsesSync() && MakeCurrent()) - mailbox_manager->PushTextureUpdates(sync_point); + if (mailbox_manager->UsesSync() && MakeCurrent()) { + // Old sync points are global and do not have a command buffer ID, + // We can simply use the global sync point number as the release count with + // 0 for the command buffer ID (under normal circumstances 0 is invalid so + // will not be used) until the old sync points are replaced. + gpu::gles2::SyncToken sync_token = {gpu::CommandBufferNamespace::GPU_IO, 0, + sync_point}; + mailbox_manager->PushTextureUpdates(sync_token); + } GpuChannelManager* manager = channel_->gpu_channel_manager(); manager->sync_point_manager()->RetireSyncPoint(sync_point); @@ -947,7 +956,11 @@ return true; GpuChannelManager* manager = channel_->gpu_channel_manager(); if (manager->sync_point_manager()->IsSyncPointRetired(sync_point)) { - PullTextureUpdates(sync_point); + // Old sync points are global and do not have a command buffer ID, + // We can simply use the global sync point number as the release count with + // 0 for the command buffer ID (under normal circumstances 0 is invalid so + // will not be used) until the old sync points are replaced. + PullTextureUpdates(gpu::CommandBufferNamespace::GPU_IO, 0, sync_point); return true; } @@ -969,16 +982,26 @@ DCHECK(!scheduler_->scheduled()); TRACE_EVENT_ASYNC_END1("gpu", "WaitSyncPoint", this, "GpuCommandBufferStub", this); - PullTextureUpdates(sync_point); + // Old sync points are global and do not have a command buffer ID, + // We can simply use the global sync point number as the release count with + // 0 for the command buffer ID (under normal circumstances 0 is invalid so + // will not be used) until the old sync points are replaced. + PullTextureUpdates(gpu::CommandBufferNamespace::GPU_IO, 0, sync_point); waiting_for_sync_point_ = false; scheduler_->SetScheduled(true); } -void GpuCommandBufferStub::PullTextureUpdates(uint32 sync_point) { +void GpuCommandBufferStub::PullTextureUpdates( + gpu::CommandBufferNamespace namespace_id, + uint64_t command_buffer_id, + uint32_t release) { gpu::gles2::MailboxManager* mailbox_manager = context_group_->mailbox_manager(); - if (mailbox_manager->UsesSync() && MakeCurrent()) - mailbox_manager->PullTextureUpdates(sync_point); + if (mailbox_manager->UsesSync() && MakeCurrent()) { + gpu::gles2::SyncToken sync_token = {namespace_id, command_buffer_id, + release}; + mailbox_manager->PullTextureUpdates(sync_token); + } } void GpuCommandBufferStub::OnSignalSyncPoint(uint32 sync_point, uint32 id) { @@ -1013,6 +1036,73 @@ OnSignalSyncPointAck(id); } +void GpuCommandBufferStub::OnFenceSyncRelease(uint64_t release) { + if (sync_point_client_->client_state()->IsFenceSyncReleased(release)) { + DLOG(ERROR) << "Fence Sync has already been released."; + return; + } + + gpu::gles2::MailboxManager* mailbox_manager = + context_group_->mailbox_manager(); + if (mailbox_manager->UsesSync() && MakeCurrent()) { + gpu::gles2::SyncToken sync_token = {gpu::CommandBufferNamespace::GPU_IO, + command_buffer_id_, release}; + mailbox_manager->PushTextureUpdates(sync_token); + } + + sync_point_client_->ReleaseFenceSync(release); +} + +bool GpuCommandBufferStub::OnWaitFenceSync( + gpu::CommandBufferNamespace namespace_id, + uint64_t command_buffer_id, + uint64_t release) { + DCHECK(!waiting_for_sync_point_); + DCHECK(scheduler_->scheduled()); + + GpuChannelManager* manager = channel_->gpu_channel_manager(); + DCHECK(manager); + + gpu::SyncPointManager* sync_point_manager = manager->sync_point_manager(); + DCHECK(sync_point_manager); + + scoped_refptr<gpu::SyncPointClientState> release_state = + sync_point_manager->GetSyncPointClientState(namespace_id, + command_buffer_id); + + if (!release_state) + return true; + + if (release_state->IsFenceSyncReleased(release)) { + PullTextureUpdates(namespace_id, command_buffer_id, release); + return true; + } + + TRACE_EVENT_ASYNC_BEGIN1("gpu", "WaitFenceSync", this, "GpuCommandBufferStub", + this); + scheduler_->SetScheduled(false); + waiting_for_sync_point_ = true; + sync_point_client_->WaitNonThreadSafe( + release_state.get(), release, task_runner_, + base::Bind(&GpuCommandBufferStub::OnWaitFenceSyncCompleted, + this->AsWeakPtr(), namespace_id, command_buffer_id, release)); + + return scheduler_->scheduled(); +} + +void GpuCommandBufferStub::OnWaitFenceSyncCompleted( + gpu::CommandBufferNamespace namespace_id, + uint64_t command_buffer_id, + uint64_t release) { + DCHECK(waiting_for_sync_point_); + DCHECK(!scheduler_->scheduled()); + TRACE_EVENT_ASYNC_END1("gpu", "WaitFenceSync", this, "GpuCommandBufferStub", + this); + PullTextureUpdates(namespace_id, command_buffer_id, release); + waiting_for_sync_point_ = false; + scheduler_->SetScheduled(true); +} + void GpuCommandBufferStub::OnCreateImage(int32 id, gfx::GpuMemoryBufferHandle handle, gfx::Size size,
diff --git a/content/common/gpu/gpu_command_buffer_stub.h b/content/common/gpu/gpu_command_buffer_stub.h index 8e854df..b139a78 100644 --- a/content/common/gpu/gpu_command_buffer_stub.h +++ b/content/common/gpu/gpu_command_buffer_stub.h
@@ -202,6 +202,14 @@ void OnSignalSyncPointAck(uint32 id); void OnSignalQuery(uint32 query, uint32 id); + void OnFenceSyncRelease(uint64_t release); + bool OnWaitFenceSync(gpu::CommandBufferNamespace namespace_id, + uint64_t command_buffer_id, + uint64_t release); + void OnWaitFenceSyncCompleted(gpu::CommandBufferNamespace namespace_id, + uint64_t command_buffer_id, + uint64_t release); + void OnCreateImage(int32 id, gfx::GpuMemoryBufferHandle handle, gfx::Size size, @@ -233,7 +241,9 @@ bool CheckContextLost(); void CheckCompleteWaits(); - void PullTextureUpdates(uint32 sync_point); + void PullTextureUpdates(gpu::CommandBufferNamespace namespace_id, + uint64_t command_buffer_id, + uint32_t release); // The lifetime of objects of this class is managed by a GpuChannel. The // GpuChannels destroy all the GpuCommandBufferStubs that they own when they
diff --git a/content/common/gpu/gpu_memory_buffer_factory.cc b/content/common/gpu/gpu_memory_buffer_factory.cc index 2c5bd39..31e2dbc 100644 --- a/content/common/gpu/gpu_memory_buffer_factory.cc +++ b/content/common/gpu/gpu_memory_buffer_factory.cc
@@ -5,7 +5,6 @@ #include "content/common/gpu/gpu_memory_buffer_factory.h" #include "base/logging.h" -#include "content/common/gpu/gpu_memory_buffer_factory_shared_memory.h" #if defined(OS_MACOSX) #include "content/common/gpu/gpu_memory_buffer_factory_io_surface.h" @@ -22,45 +21,32 @@ namespace content { // static -void GpuMemoryBufferFactory::GetSupportedTypes( - std::vector<gfx::GpuMemoryBufferType>* types) { - const gfx::GpuMemoryBufferType supported_types[] = { +gfx::GpuMemoryBufferType GpuMemoryBufferFactory::GetNativeType() { #if defined(OS_MACOSX) - gfx::IO_SURFACE_BUFFER, + return gfx::IO_SURFACE_BUFFER; #endif #if defined(OS_ANDROID) - gfx::SURFACE_TEXTURE_BUFFER, + return gfx::SURFACE_TEXTURE_BUFFER; #endif #if defined(USE_OZONE) - gfx::OZONE_NATIVE_PIXMAP, + return gfx::OZONE_NATIVE_PIXMAP; #endif - gfx::SHARED_MEMORY_BUFFER - }; - types->assign(supported_types, supported_types + arraysize(supported_types)); + return gfx::EMPTY_BUFFER; } // static -scoped_ptr<GpuMemoryBufferFactory> GpuMemoryBufferFactory::Create( - gfx::GpuMemoryBufferType type) { - switch (type) { - case gfx::SHARED_MEMORY_BUFFER: - return make_scoped_ptr(new GpuMemoryBufferFactorySharedMemory); +scoped_ptr<GpuMemoryBufferFactory> GpuMemoryBufferFactory::CreateNativeType() { #if defined(OS_MACOSX) - case gfx::IO_SURFACE_BUFFER: - return make_scoped_ptr(new GpuMemoryBufferFactoryIOSurface); + return make_scoped_ptr(new GpuMemoryBufferFactoryIOSurface); #endif #if defined(OS_ANDROID) - case gfx::SURFACE_TEXTURE_BUFFER: - return make_scoped_ptr(new GpuMemoryBufferFactorySurfaceTexture); + return make_scoped_ptr(new GpuMemoryBufferFactorySurfaceTexture); #endif #if defined(USE_OZONE) - case gfx::OZONE_NATIVE_PIXMAP: - return make_scoped_ptr(new GpuMemoryBufferFactoryOzoneNativePixmap); + return make_scoped_ptr(new GpuMemoryBufferFactoryOzoneNativePixmap); #endif - default: - NOTREACHED(); - return scoped_ptr<GpuMemoryBufferFactory>(); - } + NOTREACHED(); + return nullptr; } } // namespace content
diff --git a/content/common/gpu/gpu_memory_buffer_factory.h b/content/common/gpu/gpu_memory_buffer_factory.h index 1269c96..7edb0e4 100644 --- a/content/common/gpu/gpu_memory_buffer_factory.h +++ b/content/common/gpu/gpu_memory_buffer_factory.h
@@ -26,24 +26,14 @@ class CONTENT_EXPORT GpuMemoryBufferFactory { public: - struct Configuration { - gfx::BufferFormat format; - gfx::BufferUsage usage; - }; - virtual ~GpuMemoryBufferFactory() {} - // Gets system supported GPU memory buffer factory types. Preferred type at - // the front of vector. - static void GetSupportedTypes(std::vector<gfx::GpuMemoryBufferType>* types); + // Returns the native GPU memory buffer factory type. Returns EMPTY_BUFFER + // type if native buffers are not supported. + static gfx::GpuMemoryBufferType GetNativeType(); - // Creates a new factory instance for |type|. - static scoped_ptr<GpuMemoryBufferFactory> Create( - gfx::GpuMemoryBufferType type); - - // Gets supported format/usage configurations. - virtual void GetSupportedGpuMemoryBufferConfigurations( - std::vector<Configuration>* configurations) = 0; + // Creates a new factory instance for native GPU memory buffers. + static scoped_ptr<GpuMemoryBufferFactory> CreateNativeType(); // Creates a new GPU memory buffer instance. A valid handle is returned on // success. It can be called on any thread.
diff --git a/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc b/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc index a6ce59f..a6b41f3 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc +++ b/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc
@@ -83,18 +83,6 @@ return 0; } -const GpuMemoryBufferFactory::Configuration kSupportedConfigurations[] = { - {gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::SCANOUT}, - {gfx::BufferFormat::R_8, gfx::BufferUsage::PERSISTENT_MAP}, - {gfx::BufferFormat::R_8, gfx::BufferUsage::MAP}, - {gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::PERSISTENT_MAP}, - {gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::MAP}, - {gfx::BufferFormat::UYVY_422, gfx::BufferUsage::MAP}, - {gfx::BufferFormat::UYVY_422, gfx::BufferUsage::PERSISTENT_MAP}, - {gfx::BufferFormat::YUV_420_BIPLANAR, gfx::BufferUsage::MAP}, - {gfx::BufferFormat::YUV_420_BIPLANAR, gfx::BufferUsage::PERSISTENT_MAP}, -}; - } // namespace GpuMemoryBufferFactoryIOSurface::GpuMemoryBufferFactoryIOSurface() { @@ -107,29 +95,24 @@ bool GpuMemoryBufferFactoryIOSurface::IsGpuMemoryBufferConfigurationSupported( gfx::BufferFormat format, gfx::BufferUsage usage) { - for (auto& configuration : kSupportedConfigurations) { - if (configuration.format == format && configuration.usage == usage) - return true; + switch (usage) { + case gfx::BufferUsage::SCANOUT: + return format == gfx::BufferFormat::BGRA_8888; + case gfx::BufferUsage::MAP: + case gfx::BufferUsage::PERSISTENT_MAP: + return format == gfx::BufferFormat::R_8 || + format == gfx::BufferFormat::BGRA_8888 || + format == gfx::BufferFormat::UYVY_422 || + format == gfx::BufferFormat::YUV_420_BIPLANAR; } - + NOTREACHED(); return false; } -void GpuMemoryBufferFactoryIOSurface::GetSupportedGpuMemoryBufferConfigurations( - std::vector<Configuration>* configurations) { - configurations->assign( - kSupportedConfigurations, - kSupportedConfigurations + arraysize(kSupportedConfigurations)); -} - -gfx::GpuMemoryBufferHandle -GpuMemoryBufferFactoryIOSurface::CreateGpuMemoryBuffer( - gfx::GpuMemoryBufferId id, +// static +IOSurfaceRef GpuMemoryBufferFactoryIOSurface::CreateIOSurface( const gfx::Size& size, - gfx::BufferFormat format, - gfx::BufferUsage usage, - int client_id, - gfx::PluginWindowHandle surface_handle) { + gfx::BufferFormat format) { size_t num_planes = gfx::NumberOfPlanesForBufferFormat(format); base::ScopedCFTypeRef<CFMutableArrayRef> planes(CFArrayCreateMutable( kCFAllocatorDefault, num_planes, &kCFTypeArrayCallBacks)); @@ -158,7 +141,18 @@ AddIntegerValue(properties, kIOSurfacePixelFormat, PixelFormat(format)); CFDictionaryAddValue(properties, kIOSurfacePlaneInfo, planes); - base::ScopedCFTypeRef<IOSurfaceRef> io_surface(IOSurfaceCreate(properties)); + return IOSurfaceCreate(properties); +} + +gfx::GpuMemoryBufferHandle +GpuMemoryBufferFactoryIOSurface::CreateGpuMemoryBuffer( + gfx::GpuMemoryBufferId id, + const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + int client_id, + gfx::PluginWindowHandle surface_handle) { + base::ScopedCFTypeRef<IOSurfaceRef> io_surface(CreateIOSurface(size, format)); if (!io_surface) return gfx::GpuMemoryBufferHandle();
diff --git a/content/common/gpu/gpu_memory_buffer_factory_io_surface.h b/content/common/gpu/gpu_memory_buffer_factory_io_surface.h index 77a2e7f..1cafa79 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_io_surface.h +++ b/content/common/gpu/gpu_memory_buffer_factory_io_surface.h
@@ -5,12 +5,15 @@ #ifndef CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_IO_SURFACE_H_ #define CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_IO_SURFACE_H_ +#include <utility> + #include <IOSurface/IOSurface.h> #include "base/containers/hash_tables.h" #include "base/mac/scoped_cftyperef.h" #include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" +#include "content/common/content_export.h" #include "content/common/gpu/gpu_memory_buffer_factory.h" #include "content/common/mac/io_surface_manager.h" #include "gpu/command_buffer/service/image_factory.h" @@ -23,8 +26,9 @@ namespace content { -class GpuMemoryBufferFactoryIOSurface : public GpuMemoryBufferFactory, - public gpu::ImageFactory { +class CONTENT_EXPORT GpuMemoryBufferFactoryIOSurface + : public GpuMemoryBufferFactory, + public gpu::ImageFactory { public: GpuMemoryBufferFactoryIOSurface(); ~GpuMemoryBufferFactoryIOSurface() override; @@ -32,9 +36,10 @@ static bool IsGpuMemoryBufferConfigurationSupported(gfx::BufferFormat format, gfx::BufferUsage usage); + static IOSurfaceRef CreateIOSurface(const gfx::Size& size, + gfx::BufferFormat format); + // Overridden from GpuMemoryBufferFactory: - void GetSupportedGpuMemoryBufferConfigurations( - std::vector<Configuration>* configurations) override; gfx::GpuMemoryBufferHandle CreateGpuMemoryBuffer( gfx::GpuMemoryBufferId id, const gfx::Size& size,
diff --git a/content/common/gpu/gpu_memory_buffer_factory_io_surface_unittest.cc b/content/common/gpu/gpu_memory_buffer_factory_io_surface_unittest.cc new file mode 100644 index 0000000..7f4a132 --- /dev/null +++ b/content/common/gpu/gpu_memory_buffer_factory_io_surface_unittest.cc
@@ -0,0 +1,16 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/common/gpu/gpu_memory_buffer_factory_io_surface.h" +#include "content/test/gpu_memory_buffer_factory_test_template.h" + +namespace content { +namespace { + +INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferFactoryIOSurface, + GpuMemoryBufferFactoryTest, + GpuMemoryBufferFactoryIOSurface); + +} // namespace +} // namespace content
diff --git a/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.cc b/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.cc index 0aea4b6b..952e6c50 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.cc +++ b/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.cc
@@ -11,25 +11,6 @@ #include "ui/ozone/public/surface_factory_ozone.h" namespace content { -namespace { - -void GetSupportedConfigurations( - std::vector<GpuMemoryBufferFactory::Configuration>* configurations) { - if (!ui::ClientNativePixmapFactory::GetInstance()) { - // unittests don't have to set ClientNativePixmapFactory. - return; - } - std::vector<ui::ClientNativePixmapFactory::Configuration> - native_pixmap_configurations = - ui::ClientNativePixmapFactory::GetInstance() - ->GetSupportedConfigurations(); - for (auto& native_pixmap_configuration : native_pixmap_configurations) { - configurations->push_back({native_pixmap_configuration.format, - native_pixmap_configuration.usage}); - } -} - -} // namespace GpuMemoryBufferFactoryOzoneNativePixmap:: GpuMemoryBufferFactoryOzoneNativePixmap() {} @@ -41,20 +22,12 @@ bool GpuMemoryBufferFactoryOzoneNativePixmap:: IsGpuMemoryBufferConfigurationSupported(gfx::BufferFormat format, gfx::BufferUsage usage) { - std::vector<Configuration> configurations; - GetSupportedConfigurations(&configurations); - for (auto& configuration : configurations) { - if (configuration.format == format && configuration.usage == usage) - return true; + if (!ui::ClientNativePixmapFactory::GetInstance()) { + // unittests don't have to set ClientNativePixmapFactory. + return false; } - - return false; -} - -void GpuMemoryBufferFactoryOzoneNativePixmap:: - GetSupportedGpuMemoryBufferConfigurations( - std::vector<Configuration>* configurations) { - GetSupportedConfigurations(configurations); + return ui::ClientNativePixmapFactory::GetInstance()->IsConfigurationSupported( + format, usage); } gfx::GpuMemoryBufferHandle
diff --git a/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h b/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h index 4a1ad65..19f35c1a 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h +++ b/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h
@@ -7,6 +7,7 @@ #include "base/containers/hash_tables.h" #include "base/synchronization/lock.h" +#include "content/common/content_export.h" #include "content/common/gpu/gpu_memory_buffer_factory.h" #include "gpu/command_buffer/service/image_factory.h" #include "ui/ozone/public/native_pixmap.h" @@ -17,8 +18,9 @@ namespace content { -class GpuMemoryBufferFactoryOzoneNativePixmap : public GpuMemoryBufferFactory, - public gpu::ImageFactory { +class CONTENT_EXPORT GpuMemoryBufferFactoryOzoneNativePixmap + : public GpuMemoryBufferFactory, + public gpu::ImageFactory { public: GpuMemoryBufferFactoryOzoneNativePixmap(); ~GpuMemoryBufferFactoryOzoneNativePixmap() override; @@ -27,8 +29,6 @@ gfx::BufferUsage usage); // Overridden from GpuMemoryBufferFactory: - void GetSupportedGpuMemoryBufferConfigurations( - std::vector<Configuration>* configurations) override; gfx::GpuMemoryBufferHandle CreateGpuMemoryBuffer( gfx::GpuMemoryBufferId id, const gfx::Size& size,
diff --git a/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap_unittest.cc b/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap_unittest.cc new file mode 100644 index 0000000..c6755161 --- /dev/null +++ b/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap_unittest.cc
@@ -0,0 +1,16 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h" +#include "content/test/gpu_memory_buffer_factory_test_template.h" + +namespace content { +namespace { + +INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferFactoryOzoneNativePixmap, + GpuMemoryBufferFactoryTest, + GpuMemoryBufferFactoryOzoneNativePixmap); + +} // namespace +} // namespace content
diff --git a/content/common/gpu/gpu_memory_buffer_factory_shared_memory.cc b/content/common/gpu/gpu_memory_buffer_factory_shared_memory.cc deleted file mode 100644 index 690b8047..0000000 --- a/content/common/gpu/gpu_memory_buffer_factory_shared_memory.cc +++ /dev/null
@@ -1,114 +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 "content/common/gpu/gpu_memory_buffer_factory_shared_memory.h" - -#include <vector> - -#include "base/logging.h" -#include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h" -#include "ui/gfx/buffer_format_util.h" -#include "ui/gl/gl_image.h" -#include "ui/gl/gl_image_shared_memory.h" - -namespace content { -namespace { - -const GpuMemoryBufferFactory::Configuration kSupportedConfigurations[] = { - {gfx::BufferFormat::R_8, gfx::BufferUsage::MAP}, - {gfx::BufferFormat::R_8, gfx::BufferUsage::PERSISTENT_MAP}, - {gfx::BufferFormat::RGBA_4444, gfx::BufferUsage::MAP}, - {gfx::BufferFormat::RGBA_4444, gfx::BufferUsage::PERSISTENT_MAP}, - {gfx::BufferFormat::RGBA_8888, gfx::BufferUsage::MAP}, - {gfx::BufferFormat::RGBA_8888, gfx::BufferUsage::PERSISTENT_MAP}, - {gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::MAP}, - {gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::PERSISTENT_MAP}, - {gfx::BufferFormat::YUV_420, gfx::BufferUsage::MAP}, - {gfx::BufferFormat::YUV_420, gfx::BufferUsage::PERSISTENT_MAP}}; - -} // namespace - -GpuMemoryBufferFactorySharedMemory::GpuMemoryBufferFactorySharedMemory() { -} - -GpuMemoryBufferFactorySharedMemory::~GpuMemoryBufferFactorySharedMemory() { -} - -// static -bool GpuMemoryBufferFactorySharedMemory:: - IsGpuMemoryBufferConfigurationSupported(gfx::BufferFormat format, - gfx::BufferUsage usage) { - for (auto& configuration : kSupportedConfigurations) { - if (configuration.format == format && configuration.usage == usage) - return true; - } - - return false; -} - -void GpuMemoryBufferFactorySharedMemory:: - GetSupportedGpuMemoryBufferConfigurations( - std::vector<Configuration>* configurations) { - configurations->assign( - kSupportedConfigurations, - kSupportedConfigurations + arraysize(kSupportedConfigurations)); -} - -gfx::GpuMemoryBufferHandle -GpuMemoryBufferFactorySharedMemory::CreateGpuMemoryBuffer( - gfx::GpuMemoryBufferId id, - const gfx::Size& size, - gfx::BufferFormat format, - gfx::BufferUsage usage, - int client_id, - gfx::PluginWindowHandle surface_handle) { - size_t buffer_size = 0u; - if (!gfx::BufferSizeForBufferFormatChecked(size, format, &buffer_size)) - return gfx::GpuMemoryBufferHandle(); - - base::SharedMemory shared_memory; - if (!shared_memory.CreateAnonymous(buffer_size)) - return gfx::GpuMemoryBufferHandle(); - -#if DCHECK_IS_ON() - DCHECK(buffers_.insert(id).second); -#endif - gfx::GpuMemoryBufferHandle handle; - handle.type = gfx::SHARED_MEMORY_BUFFER; - handle.id = id; - shared_memory.ShareToProcess(base::GetCurrentProcessHandle(), &handle.handle); - return handle; -} - -void GpuMemoryBufferFactorySharedMemory::DestroyGpuMemoryBuffer( - gfx::GpuMemoryBufferId id, - int client_id) { -#if DCHECK_IS_ON() - DCHECK_EQ(buffers_.erase(id), 1u); -#endif -} - -gpu::ImageFactory* GpuMemoryBufferFactorySharedMemory::AsImageFactory() { - return this; -} - -scoped_refptr<gfx::GLImage> -GpuMemoryBufferFactorySharedMemory::CreateImageForGpuMemoryBuffer( - const gfx::GpuMemoryBufferHandle& handle, - const gfx::Size& size, - gfx::BufferFormat format, - unsigned internalformat, - int client_id) { -#if DCHECK_IS_ON() - DCHECK_EQ(buffers_.count(handle.id), 1u); -#endif - scoped_refptr<gfx::GLImageSharedMemory> image( - new gfx::GLImageSharedMemory(size, internalformat)); - if (!image->Initialize(handle, format)) - return scoped_refptr<gfx::GLImage>(); - - return image; -} - -} // namespace content
diff --git a/content/common/gpu/gpu_memory_buffer_factory_shared_memory.h b/content/common/gpu/gpu_memory_buffer_factory_shared_memory.h deleted file mode 100644 index 0d3291d..0000000 --- a/content/common/gpu/gpu_memory_buffer_factory_shared_memory.h +++ /dev/null
@@ -1,65 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_SHARED_MEMORY_H_ -#define CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_SHARED_MEMORY_H_ - -#include "base/memory/ref_counted.h" -#include "content/common/gpu/gpu_memory_buffer_factory.h" -#include "gpu/command_buffer/service/image_factory.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gfx/gpu_memory_buffer.h" - -#if DCHECK_IS_ON() -#include <set> -#endif - -namespace gfx { -class GLImage; -} - -namespace content { - -class GpuMemoryBufferFactorySharedMemory : public GpuMemoryBufferFactory, - public gpu::ImageFactory { - public: - GpuMemoryBufferFactorySharedMemory(); - ~GpuMemoryBufferFactorySharedMemory() override; - - static bool IsGpuMemoryBufferConfigurationSupported(gfx::BufferFormat format, - gfx::BufferUsage usage); - - // Overridden from GpuMemoryBufferFactory: - void GetSupportedGpuMemoryBufferConfigurations( - std::vector<Configuration>* configurations) override; - gfx::GpuMemoryBufferHandle CreateGpuMemoryBuffer( - gfx::GpuMemoryBufferId id, - const gfx::Size& size, - gfx::BufferFormat format, - gfx::BufferUsage usage, - int client_id, - gfx::PluginWindowHandle surface_handle) override; - void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, - int client_id) override; - gpu::ImageFactory* AsImageFactory() override; - - // Overridden from gpu::ImageFactory: - scoped_refptr<gfx::GLImage> CreateImageForGpuMemoryBuffer( - const gfx::GpuMemoryBufferHandle& handle, - const gfx::Size& size, - gfx::BufferFormat format, - unsigned internalformat, - int client_id) override; - - private: -#if DCHECK_IS_ON() - std::set<gfx::GpuMemoryBufferId> buffers_; -#endif - - DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferFactorySharedMemory); -}; - -} // namespace content - -#endif // CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_SHARED_MEMORY_H_
diff --git a/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc b/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc index 490c45e..3648817d 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc +++ b/content/common/gpu/gpu_memory_buffer_factory_surface_texture.cc
@@ -9,12 +9,6 @@ #include "ui/gl/gl_image_surface_texture.h" namespace content { -namespace { - -const GpuMemoryBufferFactory::Configuration kSupportedConfigurations[] = { - {gfx::BufferFormat::RGBA_8888, gfx::BufferUsage::MAP}}; - -} // namespace GpuMemoryBufferFactorySurfaceTexture::GpuMemoryBufferFactorySurfaceTexture() { } @@ -26,22 +20,17 @@ bool GpuMemoryBufferFactorySurfaceTexture:: IsGpuMemoryBufferConfigurationSupported(gfx::BufferFormat format, gfx::BufferUsage usage) { - for (auto& configuration : kSupportedConfigurations) { - if (configuration.format == format && configuration.usage == usage) - return true; + switch (usage) { + case gfx::BufferUsage::SCANOUT: + case gfx::BufferUsage::PERSISTENT_MAP: + return false; + case gfx::BufferUsage::MAP: + return format == gfx::BufferFormat::RGBA_8888; } - + NOTREACHED(); return false; } -void GpuMemoryBufferFactorySurfaceTexture:: - GetSupportedGpuMemoryBufferConfigurations( - std::vector<Configuration>* configurations) { - configurations->assign( - kSupportedConfigurations, - kSupportedConfigurations + arraysize(kSupportedConfigurations)); -} - gfx::GpuMemoryBufferHandle GpuMemoryBufferFactorySurfaceTexture::CreateGpuMemoryBuffer( gfx::GpuMemoryBufferId id,
diff --git a/content/common/gpu/gpu_memory_buffer_factory_surface_texture.h b/content/common/gpu/gpu_memory_buffer_factory_surface_texture.h index 1b1ae4eb..57c3cd9a 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_surface_texture.h +++ b/content/common/gpu/gpu_memory_buffer_factory_surface_texture.h
@@ -5,9 +5,12 @@ #ifndef CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_SURFACE_TEXTURE_H_ #define CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_SURFACE_TEXTURE_H_ +#include <utility> + #include "base/containers/hash_tables.h" #include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" +#include "content/common/content_export.h" #include "content/common/gpu/gpu_memory_buffer_factory.h" #include "gpu/command_buffer/service/image_factory.h" #include "ui/gfx/geometry/size.h" @@ -20,8 +23,9 @@ namespace content { -class GpuMemoryBufferFactorySurfaceTexture : public GpuMemoryBufferFactory, - public gpu::ImageFactory { +class CONTENT_EXPORT GpuMemoryBufferFactorySurfaceTexture + : public GpuMemoryBufferFactory, + public gpu::ImageFactory { public: GpuMemoryBufferFactorySurfaceTexture(); ~GpuMemoryBufferFactorySurfaceTexture() override; @@ -30,8 +34,6 @@ gfx::BufferUsage usage); // Overridden from GpuMemoryBufferFactory: - void GetSupportedGpuMemoryBufferConfigurations( - std::vector<Configuration>* configurations) override; gfx::GpuMemoryBufferHandle CreateGpuMemoryBuffer( gfx::GpuMemoryBufferId id, const gfx::Size& size,
diff --git a/content/common/gpu/gpu_memory_buffer_factory_surface_texture_unittest.cc b/content/common/gpu/gpu_memory_buffer_factory_surface_texture_unittest.cc new file mode 100644 index 0000000..683860fe --- /dev/null +++ b/content/common/gpu/gpu_memory_buffer_factory_surface_texture_unittest.cc
@@ -0,0 +1,16 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/common/gpu/gpu_memory_buffer_factory_surface_texture.h" +#include "content/test/gpu_memory_buffer_factory_test_template.h" + +namespace content { +namespace { + +INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferFactorySurfaceTexture, + GpuMemoryBufferFactoryTest, + GpuMemoryBufferFactorySurfaceTexture); + +} // namespace +} // namespace content
diff --git a/content/common/gpu/gpu_memory_buffer_factory_unittest.cc b/content/common/gpu/gpu_memory_buffer_factory_unittest.cc deleted file mode 100644 index dbd9b76..0000000 --- a/content/common/gpu/gpu_memory_buffer_factory_unittest.cc +++ /dev/null
@@ -1,58 +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 "content/common/gpu/gpu_memory_buffer_factory.h" - -#include "testing/gtest/include/gtest/gtest.h" - -namespace content { -namespace { - -class GpuMemoryBufferFactoryTest - : public testing::TestWithParam<gfx::GpuMemoryBufferType> { - public: - GpuMemoryBufferFactoryTest() : factory_(nullptr) {} - - // Overridden from testing::Test: - void SetUp() override { - factory_ = GpuMemoryBufferFactory::Create(GetParam()); - factory_->GetSupportedGpuMemoryBufferConfigurations( - &supported_configurations_); - } - void TearDown() override { factory_.reset(); } - - protected: - scoped_ptr<GpuMemoryBufferFactory> factory_; - std::vector<GpuMemoryBufferFactory::Configuration> supported_configurations_; -}; - -TEST_P(GpuMemoryBufferFactoryTest, CreateAndDestroy) { - const gfx::GpuMemoryBufferId kBufferId(1); - const int kClientId = 1; - - gfx::Size buffer_size(2, 2); - - for (auto configuration : supported_configurations_) { - gfx::GpuMemoryBufferHandle handle = factory_->CreateGpuMemoryBuffer( - kBufferId, buffer_size, configuration.format, configuration.usage, - kClientId, gfx::kNullPluginWindow); - EXPECT_EQ(handle.type, GetParam()); - factory_->DestroyGpuMemoryBuffer(kBufferId, kClientId); - } -} - -std::vector<gfx::GpuMemoryBufferType> -GetSupportedGpuMemoryBufferFactoryTypes() { - std::vector<gfx::GpuMemoryBufferType> supported_types; - GpuMemoryBufferFactory::GetSupportedTypes(&supported_types); - return supported_types; -} - -INSTANTIATE_TEST_CASE_P( - GpuMemoryBufferFactoryTests, - GpuMemoryBufferFactoryTest, - ::testing::ValuesIn(GetSupportedGpuMemoryBufferFactoryTypes())); - -} // namespace -} // namespace content
diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h index b4f85e8..f0f62e34 100644 --- a/content/common/gpu/gpu_messages.h +++ b/content/common/gpu/gpu_messages.h
@@ -470,6 +470,10 @@ IPC_SYNC_MESSAGE_CONTROL1_0(GpuChannelMsg_DestroyCommandBuffer, int32 /* instance_id */) +// Simple NOP message which can be used as fence to ensure all previous sent +// messages have been received. +IPC_SYNC_MESSAGE_CONTROL0_0(GpuChannelMsg_Nop) + #if defined(OS_ANDROID) //------------------------------------------------------------------------------ // Stream Texture Messages
diff --git a/content/content_common.gypi b/content/content_common.gypi index c54f367..feea62c8 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi
@@ -321,8 +321,6 @@ 'common/gpu/gpu_memory_buffer_factory.h', 'common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.cc', 'common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h', - 'common/gpu/gpu_memory_buffer_factory_shared_memory.cc', - 'common/gpu/gpu_memory_buffer_factory_shared_memory.h', 'common/gpu/gpu_memory_manager.cc', 'common/gpu/gpu_memory_manager.h', 'common/gpu/gpu_memory_manager_client.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 5d088b6..f626594e 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi
@@ -118,6 +118,7 @@ 'test/fake_plugin_service.h', 'test/fake_renderer_scheduler.cc', 'test/fake_renderer_scheduler.h', + 'test/gpu_memory_buffer_factory_test_template.h', 'test/mock_google_streaming_server.cc', 'test/mock_google_streaming_server.h', 'test/mock_keyboard.cc', @@ -634,12 +635,11 @@ 'common/dwrite_font_platform_win_unittest.cc', 'common/fileapi/file_system_util_unittest.cc', 'common/font_warmup_win_unittest.cc', - 'common/gpu/client/gpu_memory_buffer_impl_unittest.cc', + 'common/gpu/client/gpu_memory_buffer_impl_shared_memory_unittest.cc', 'common/gpu/gpu_channel_test_common.cc', 'common/gpu/gpu_channel_test_common.h', 'common/gpu/gpu_channel_unittest.cc', 'common/gpu/gpu_channel_manager_unittest.cc', - 'common/gpu/gpu_memory_buffer_factory_unittest.cc', 'common/gpu/gpu_memory_manager_unittest.cc', 'common/host_discardable_shared_memory_manager_unittest.cc', 'common/host_shared_bitmap_manager_unittest.cc', @@ -788,8 +788,18 @@ 'browser/android/overscroll_refresh_unittest.cc', 'browser/android/url_request_content_job_unittest.cc', 'browser/renderer_host/input/motion_event_android_unittest.cc', + 'common/gpu/client/gpu_memory_buffer_impl_surface_texture_unittest.cc', + 'common/gpu/gpu_memory_buffer_factory_surface_texture_unittest.cc', 'renderer/java/gin_java_bridge_value_converter_unittest.cc', ], + 'content_unittests_mac_sources': [ + 'common/gpu/client/gpu_memory_buffer_impl_io_surface_unittest.cc', + 'common/gpu/gpu_memory_buffer_factory_io_surface_unittest.cc', + ], + 'content_unittests_ozone_sources': [ + 'common/gpu/client/gpu_memory_buffer_impl_ozone_native_pixmap_unittest.cc', + 'common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap_unittest.cc', + ], }, 'targets': [ { @@ -1217,12 +1227,14 @@ ], }], ['use_ozone==1', { + 'sources': [ '<@(content_unittests_ozone_sources)' ], 'dependencies': [ '../ui/ozone/ozone.gyp:ozone', '../ui/ozone/ozone.gyp:ozone_base', ], }], ['OS == "mac"', { + 'sources': [ '<@(content_unittests_mac_sources)' ], 'dependencies': [ '../third_party/boringssl/boringssl.gyp:boringssl', ],
diff --git a/content/gpu/gpu_child_thread.cc b/content/gpu/gpu_child_thread.cc index e40928c..40c808b 100644 --- a/content/gpu/gpu_child_thread.cc +++ b/content/gpu/gpu_child_thread.cc
@@ -81,6 +81,8 @@ const GpuMsg_CreateGpuMemoryBuffer_Params& params) { TRACE_EVENT2("gpu", "GpuMemoryBufferMessageFilter::OnCreateGpuMemoryBuffer", "id", params.id.id, "client_id", params.client_id); + + DCHECK(gpu_memory_buffer_factory_); sender_->Send(new GpuHostMsg_GpuMemoryBufferCreated( gpu_memory_buffer_factory_->CreateGpuMemoryBuffer( params.id, params.size, params.format, params.usage, @@ -166,15 +168,6 @@ } } -// static -gfx::GpuMemoryBufferType GpuChildThread::GetGpuMemoryBufferFactoryType() { - std::vector<gfx::GpuMemoryBufferType> supported_types; - GpuMemoryBufferFactory::GetSupportedTypes(&supported_types); - DCHECK(!supported_types.empty()); - // Note: We always use the preferred type. - return supported_types[0]; -} - void GpuChildThread::Shutdown() { ChildThreadImpl::Shutdown(); logging::SetLogMessageHandler(NULL);
diff --git a/content/gpu/gpu_child_thread.h b/content/gpu/gpu_child_thread.h index 11cd46d..b4ece634 100644 --- a/content/gpu/gpu_child_thread.h +++ b/content/gpu/gpu_child_thread.h
@@ -55,8 +55,6 @@ ~GpuChildThread() override; - static gfx::GpuMemoryBufferType GetGpuMemoryBufferFactoryType(); - void Shutdown() override; void Init(const base::Time& process_start_time);
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc index e7ce06e..d27ef2b9 100644 --- a/content/gpu/gpu_main.cc +++ b/content/gpu/gpu_main.cc
@@ -361,9 +361,10 @@ logging::SetLogMessageHandler(NULL); - scoped_ptr<GpuMemoryBufferFactory> gpu_memory_buffer_factory = - GpuMemoryBufferFactory::Create( - GpuChildThread::GetGpuMemoryBufferFactoryType()); + scoped_ptr<GpuMemoryBufferFactory> gpu_memory_buffer_factory; + if (GpuMemoryBufferFactory::GetNativeType() != gfx::EMPTY_BUFFER) + gpu_memory_buffer_factory = GpuMemoryBufferFactory::CreateNativeType(); + gpu::SyncPointManager sync_point_manager(false); GpuProcess gpu_process;
diff --git a/content/gpu/in_process_gpu_thread.cc b/content/gpu/in_process_gpu_thread.cc index e4149db..bd9ef94f 100644 --- a/content/gpu/in_process_gpu_thread.cc +++ b/content/gpu/in_process_gpu_thread.cc
@@ -18,8 +18,10 @@ params_(params), gpu_process_(NULL), sync_point_manager_override_(sync_point_manager_override), - gpu_memory_buffer_factory_(GpuMemoryBufferFactory::Create( - GpuChildThread::GetGpuMemoryBufferFactoryType())) { + gpu_memory_buffer_factory_( + GpuMemoryBufferFactory::GetNativeType() != gfx::EMPTY_BUFFER + ? GpuMemoryBufferFactory::CreateNativeType() + : nullptr) { if (!sync_point_manager_override_) { sync_point_manager_.reset(new gpu::SyncPointManager(false)); sync_point_manager_override_ = sync_point_manager_.get();
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index aa0cc6d9..374f228 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -83,6 +83,10 @@ // features. const char kDisableBlinkFeatures[] = "disable-blink-features"; +// Disables new cc/animation system (Project Heaviside). crbug.com/394772 +const char kDisableCompositorAnimationTimelines[] = + "disable-compositor-animation-timelines"; + // Disable the creation of compositing layers when it would prevent LCD text. const char kDisablePreferCompositingToLCDText[] = "disable-prefer-compositing-to-lcd-text"; @@ -289,10 +293,6 @@ const char kDisableAcceleratedJpegDecoding[] = "disable-accelerated-jpeg-decoding"; -// Enables new cc/animation system (Project Heaviside). crbug.com/394772 -const char kEnableCompositorAnimationTimelines[] = - "enable-compositor-animation-timelines"; - // Enables LCD text. const char kEnableLCDText[] = "enable-lcd-text";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index fe4a2fcd..fb2b2d6 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -28,12 +28,13 @@ CONTENT_EXPORT extern const char kDefaultTileHeight[]; CONTENT_EXPORT extern const char kDisable2dCanvasAntialiasing[]; CONTENT_EXPORT extern const char kDisable3DAPIs[]; -CONTENT_EXPORT extern const char kDisableBlinkFeatures[]; CONTENT_EXPORT extern const char kDisableAccelerated2dCanvas[]; CONTENT_EXPORT extern const char kDisableAcceleratedJpegDecoding[]; CONTENT_EXPORT extern const char kDisableAcceleratedMjpegDecode[]; CONTENT_EXPORT extern const char kDisableAcceleratedVideoDecode[]; extern const char kDisableBackingStoreLimit[]; +CONTENT_EXPORT extern const char kDisableBlinkFeatures[]; +CONTENT_EXPORT extern const char kDisableCompositorAnimationTimelines[]; CONTENT_EXPORT extern const char kDisablePreferCompositingToLCDText[]; CONTENT_EXPORT extern const char kDisableDatabases[]; CONTENT_EXPORT extern const char kDisableDelayAgnosticAec[]; @@ -95,7 +96,6 @@ CONTENT_EXPORT extern const char kDomAutomationController[]; extern const char kEnable2dCanvasClipAntialiasing[]; CONTENT_EXPORT extern const char kEnableAggressiveDOMStorageFlushing[]; -CONTENT_EXPORT extern const char kEnableCompositorAnimationTimelines[]; CONTENT_EXPORT extern const char kEnableCredentialManagerAPI[]; CONTENT_EXPORT extern const char kEnablePreferCompositingToLCDText[]; CONTENT_EXPORT extern const char kEnableBlinkFeatures[];
diff --git a/content/public/renderer/media_stream_api.cc b/content/public/renderer/media_stream_api.cc index da39c4b..d668695 100644 --- a/content/public/renderer/media_stream_api.cc +++ b/content/public/renderer/media_stream_api.cc
@@ -11,9 +11,6 @@ #include "content/renderer/media/media_stream_audio_source.h" #include "content/renderer/media/media_stream_video_capturer_source.h" #include "content/renderer/media/media_stream_video_track.h" -#include "media/base/audio_capturer_source.h" -#include "media/base/video_capturer_source.h" -#include "third_party/WebKit/public/platform/WebMediaDeviceInfo.h" #include "third_party/WebKit/public/platform/WebMediaStream.h" #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" #include "third_party/WebKit/public/platform/WebURL.h" @@ -37,61 +34,34 @@ bool is_remote, bool is_readonly, const std::string& media_stream_url) { - blink::WebMediaStream stream = + blink::WebMediaStream web_stream = blink::WebMediaStreamRegistry::lookupMediaStreamDescriptor( GURL(media_stream_url)); - - if (stream.isNull()) { - LOG(ERROR) << "Stream not found"; - return false; - } - blink::WebString track_id = MakeTrackId(); - blink::WebMediaStreamSource webkit_source; - scoped_ptr<MediaStreamVideoSource> media_stream_source( - new MediaStreamVideoCapturerSource( - MediaStreamSource::SourceStoppedCallback(), - source.Pass())); - webkit_source.initialize( - track_id, - blink::WebMediaStreamSource::TypeVideo, - track_id, - is_remote, - is_readonly); - webkit_source.setExtraData(media_stream_source.get()); - - blink::WebMediaConstraints constraints; - constraints.initialize(); - stream.addTrack(MediaStreamVideoTrack::CreateVideoTrack( - media_stream_source.release(), - constraints, - MediaStreamVideoSource::ConstraintsCallback(), - true)); - return true; + return AddVideoTrackToMediaStream(source.Pass(), is_remote, is_readonly, + &web_stream); } bool AddAudioTrackToMediaStream( - scoped_refptr<media::AudioCapturerSource> source, + const scoped_refptr<media::AudioCapturerSource>& source, const media::AudioParameters& params, bool is_remote, bool is_readonly, const std::string& media_stream_url) { DCHECK(params.IsValid()) << params.AsHumanReadableString(); - blink::WebMediaStream stream = + blink::WebMediaStream web_stream = blink::WebMediaStreamRegistry::lookupMediaStreamDescriptor( GURL(media_stream_url)); - - if (stream.isNull()) { - LOG(ERROR) << "Stream not found"; + if (web_stream.isNull()) { + DLOG(ERROR) << "Stream not found"; return false; } blink::WebMediaStreamSource webkit_source; - blink::WebString track_id = MakeTrackId(); - webkit_source.initialize( - track_id, - blink::WebMediaStreamSource::TypeAudio, - track_id, - is_remote, - is_readonly); + const blink::WebString track_id = MakeTrackId(); + webkit_source.initialize(track_id, + blink::WebMediaStreamSource::TypeAudio, + track_id, + is_remote, + is_readonly); MediaStreamAudioSource* audio_source( new MediaStreamAudioSource( @@ -114,7 +84,38 @@ RenderThreadImpl::current()->GetPeerConnectionDependencyFactory()-> CreateLocalAudioTrack(web_media_audio_track); - stream.addTrack(web_media_audio_track); + web_stream.addTrack(web_media_audio_track); + return true; +} + +bool AddVideoTrackToMediaStream(scoped_ptr<media::VideoCapturerSource> source, + bool is_remote, + bool is_readonly, + blink::WebMediaStream* web_stream) { + if (web_stream->isNull()) { + DLOG(ERROR) << "Stream not found"; + return false; + } + const blink::WebString track_id = MakeTrackId(); + blink::WebMediaStreamSource webkit_source; + scoped_ptr<MediaStreamVideoSource> media_stream_source( + new MediaStreamVideoCapturerSource( + MediaStreamSource::SourceStoppedCallback(), + source.Pass())); + webkit_source.initialize(track_id, + blink::WebMediaStreamSource::TypeVideo, + track_id, + is_remote, + is_readonly); + webkit_source.setExtraData(media_stream_source.get()); + + blink::WebMediaConstraints constraints; + constraints.initialize(); + web_stream->addTrack(MediaStreamVideoTrack::CreateVideoTrack( + media_stream_source.release(), + constraints, + MediaStreamVideoSource::ConstraintsCallback(), + true)); return true; }
diff --git a/content/public/renderer/media_stream_api.h b/content/public/renderer/media_stream_api.h index 71ce675..2e87ff3 100644 --- a/content/public/renderer/media_stream_api.h +++ b/content/public/renderer/media_stream_api.h
@@ -10,17 +10,19 @@ #include "media/base/video_capturer_source.h" namespace blink { -class WebMediaStreamSource; +class WebMediaStream; } -namespace Media { +namespace media { class AudioParameters; } namespace content { - -// These two methods will initialize a WebMediaStreamSource object to take -// data from the provided audio or video capturer source. +// These methods create a WebMediaStreamSource + MediaStreamSource pair with the +// provided audio or video capturer source. A new WebMediaStreamTrack + +// MediaStreamTrack pair is created, holding the previous MediaStreamSource, and +// is plugged into the stream identified by |media_stream_url| (or passed as +// |web_stream|). // |is_remote| should be true if the source of the data is not a local device. // |is_readonly| should be true if the format of the data cannot be changed by // MediaTrackConstraints. @@ -29,8 +31,14 @@ bool is_remote, bool is_readonly, const std::string& media_stream_url); +CONTENT_EXPORT bool AddVideoTrackToMediaStream( + scoped_ptr<media::VideoCapturerSource> source, + bool is_remote, + bool is_readonly, + blink::WebMediaStream* web_stream); + CONTENT_EXPORT bool AddAudioTrackToMediaStream( - scoped_refptr<media::AudioCapturerSource> source, + const scoped_refptr<media::AudioCapturerSource>& source, const media::AudioParameters& params, bool is_remote, bool is_readonly,
diff --git a/content/public/test/content_browser_test_utils_mac.mm b/content/public/test/content_browser_test_utils_mac.mm index 165a177..d2e879cf 100644 --- a/content/public/test/content_browser_test_utils_mac.mm +++ b/content/public/test/content_browser_test_utils_mac.mm
@@ -15,7 +15,7 @@ NSRect new_bounds = NSRectFromCGRect(bounds.ToCGRect()); if ([[NSScreen screens] count] > 0) { new_bounds.origin.y = - [[[NSScreen screens] objectAtIndex:0] frame].size.height - + [[[NSScreen screens] firstObject] frame].size.height - new_bounds.origin.y - new_bounds.size.height; }
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc index 2e97735..04df33c0 100644 --- a/content/renderer/gpu/render_widget_compositor.cc +++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -246,10 +246,10 @@ settings.accelerated_animation_enabled = compositor_deps_->IsThreadedAnimationEnabled(); - if (cmd->HasSwitch(switches::kEnableCompositorAnimationTimelines)) { - settings.use_compositor_animation_timelines = true; - blink::WebRuntimeFeatures::enableCompositorAnimationTimelines(true); - } + settings.use_compositor_animation_timelines = + !cmd->HasSwitch(switches::kDisableCompositorAnimationTimelines); + blink::WebRuntimeFeatures::enableCompositorAnimationTimelines( + settings.use_compositor_animation_timelines); settings.default_tile_size = CalculateDefaultTileSize(widget_); if (cmd->HasSwitch(switches::kDefaultTileWidth)) {
diff --git a/content/renderer/input/input_handler_proxy.cc b/content/renderer/input/input_handler_proxy.cc index b5dcb18..2c6234f3 100644 --- a/content/renderer/input/input_handler_proxy.cc +++ b/content/renderer/input/input_handler_proxy.cc
@@ -536,13 +536,9 @@ blink::WebSize())); disallow_horizontal_fling_scroll_ = !vx; disallow_vertical_fling_scroll_ = !vy; - TRACE_EVENT_ASYNC_BEGIN2("input", + TRACE_EVENT_ASYNC_BEGIN2("input,benchmark", "InputHandlerProxy::HandleGestureFling::started", - this, - "vx", - vx, - "vy", - vy); + this, "vx", vx, "vy", vy); // Note that the timestamp will only be used to kickstart the animation if // its sufficiently close to the timestamp of the first call |Animate()|. has_fling_animation_started_ = false;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 551545e..c783b8e 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -2610,8 +2610,9 @@ if (!ds) return; - TRACE_EVENT2("navigation", "RenderFrameImpl::didStartProvisionalLoad", - "id", routing_id_, "url", ds->request().url().string().utf8()); + TRACE_EVENT2("navigation,benchmark", + "RenderFrameImpl::didStartProvisionalLoad", "id", routing_id_, + "url", ds->request().url().string().utf8()); DocumentState* document_state = DocumentState::FromDataSource(ds); // We should only navigate to swappedout:// when is_swapped_out_ is true. @@ -2658,8 +2659,8 @@ blink::WebLocalFrame* frame, const blink::WebURLError& error, blink::WebHistoryCommitType commit_type) { - TRACE_EVENT1("navigation", "RenderFrameImpl::didFailProvisionalLoad", - "id", routing_id_); + TRACE_EVENT1("navigation,benchmark", + "RenderFrameImpl::didFailProvisionalLoad", "id", routing_id_); DCHECK(!frame_ || frame_ == frame); WebDataSource* ds = frame->provisionalDataSource(); DCHECK(ds); @@ -2930,7 +2931,7 @@ void RenderFrameImpl::didFinishDocumentLoad(blink::WebLocalFrame* frame, bool document_is_empty) { - TRACE_EVENT1("navigation", "RenderFrameImpl::didFinishDocumentLoad", + TRACE_EVENT1("navigation,benchmark", "RenderFrameImpl::didFinishDocumentLoad", "id", routing_id_); DCHECK(!frame_ || frame_ == frame); WebDataSource* ds = frame->dataSource(); @@ -3022,14 +3023,14 @@ } void RenderFrameImpl::didFinishLoad(blink::WebLocalFrame* frame) { - TRACE_EVENT1("navigation", "RenderFrameImpl::didFinishLoad", - "id", routing_id_); + TRACE_EVENT1("navigation,benchmark", "RenderFrameImpl::didFinishLoad", "id", + routing_id_); DCHECK(!frame_ || frame_ == frame); WebDataSource* ds = frame->dataSource(); DocumentState* document_state = DocumentState::FromDataSource(ds); if (document_state->finish_load_time().is_null()) { if (!frame->parent()) { - TRACE_EVENT_INSTANT0("WebCore", "LoadFinished", + TRACE_EVENT_INSTANT0("WebCore,benchmark", "LoadFinished", TRACE_EVENT_SCOPE_PROCESS); } document_state->set_finish_load_time(Time::Now());
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index c8ca4bdb..a72214d 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -653,8 +653,8 @@ *base::CommandLine::ForCurrentProcess(); cc::LayerSettings layer_settings; - if (command_line.HasSwitch(switches::kEnableCompositorAnimationTimelines)) - layer_settings.use_compositor_animation_timelines = true; + layer_settings.use_compositor_animation_timelines = + !command_line.HasSwitch(switches::kDisableCompositorAnimationTimelines); cc_blink::WebLayerImpl::SetLayerSettings(layer_settings); cc::SetClientNameForMetrics("Renderer");
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc index 2233563c..f5d6dcdf 100644 --- a/content/shell/renderer/layout_test/blink_test_runner.cc +++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -35,6 +35,7 @@ #include "content/public/common/content_switches.h" #include "content/public/common/url_constants.h" #include "content/public/common/web_preferences.h" +#include "content/public/renderer/media_stream_api.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/render_view_visitor.h" @@ -222,6 +223,23 @@ DISALLOW_COPY_AND_ASSIGN(MockGamepadProvider); }; +class MockVideoCapturerSource : public media::VideoCapturerSource { + public: + MockVideoCapturerSource() = default; + ~MockVideoCapturerSource() override {} + + void GetCurrentSupportedFormats( + int max_requested_width, + int max_requested_height, + double max_requested_frame_rate, + const VideoCaptureDeviceFormatsCB& callback) override {} + void StartCapture( + const media::VideoCaptureParams& params, + const VideoCaptureDeliverFrameCB& new_frame_callback, + const RunningCallback& running_callback) override {} + void StopCapture() override {} +}; + } // namespace BlinkTestRunner::BlinkTestRunner(RenderView* render_view) @@ -715,6 +733,20 @@ test_runner::WebTestProxyBase* proxy) { } +bool BlinkTestRunner::AddMediaStreamSourceAndTrack( + blink::WebMediaStream* stream) { + DCHECK(stream); +#if defined(ENABLE_WEBRTC) + return AddVideoTrackToMediaStream( + make_scoped_ptr(new MockVideoCapturerSource()), + false /* is_remote */, + false /* is_readonly */, + stream); +#else + return false; +#endif +} + // RenderViewObserver -------------------------------------------------------- void BlinkTestRunner::DidClearWindowObject(WebLocalFrame* frame) {
diff --git a/content/shell/renderer/layout_test/blink_test_runner.h b/content/shell/renderer/layout_test/blink_test_runner.h index 6739bed..8ff5a55 100644 --- a/content/shell/renderer/layout_test/blink_test_runner.h +++ b/content/shell/renderer/layout_test/blink_test_runner.h
@@ -132,6 +132,7 @@ const GURL& origin, const GURL& embedding_origin) override; void ResetPermissions() override; + bool AddMediaStreamSourceAndTrack(blink::WebMediaStream* stream) override; cc::SharedBitmapManager* GetSharedBitmapManager() override; void DispatchBeforeInstallPromptEvent( int request_id,
diff --git a/content/test/content_test_suite.cc b/content/test/content_test_suite.cc index 341a64ed..5439f03 100644 --- a/content/test/content_test_suite.cc +++ b/content/test/content_test_suite.cc
@@ -5,6 +5,7 @@ #include "content/test/content_test_suite.h" #include "base/base_paths.h" +#include "base/base_switches.h" #include "base/logging.h" #include "content/public/common/content_client.h" #include "content/public/common/content_paths.h"
diff --git a/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-win.txt b/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-win.txt index 184a9edf..eea73dd 100644 --- a/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-win.txt +++ b/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-win.txt
@@ -1,21 +1,21 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ia2_hypertext='<obj0>' caret_offset=1 n_selections=1 selection_start=0 selection_end=1 ++IA2_ROLE_SECTION FOCUSABLE IA2_STATE_EDITABLE ia2_hypertext='<obj0><obj1><obj2>' caret_offset=3 n_selections=1 selection_start=0 selection_end=3 -++++IA2_ROLE_PARAGRAPH IA2_STATE_EDITABLE ia2_hypertext='A contenteditable with a <obj1> and an <obj3> and a <obj5>.' caret_offset=44 n_selections=1 selection_start=0 selection_end=44 -++++++ROLE_SYSTEM_STATICTEXT name='A contenteditable with a ' IA2_STATE_EDITABLE ia2_hypertext='A contenteditable with a ' caret_offset=25 n_selections=1 selection_start=0 selection_end=25 -++++++ROLE_SYSTEM_LINK name='link' LINKED IA2_STATE_EDITABLE ia2_hypertext='link' caret_offset=4 n_selections=1 selection_start=0 selection_end=4 -++++++++ROLE_SYSTEM_STATICTEXT name='link' LINKED IA2_STATE_EDITABLE ia2_hypertext='link' caret_offset=4 n_selections=1 selection_start=0 selection_end=4 -++++++ROLE_SYSTEM_STATICTEXT name=' and an ' IA2_STATE_EDITABLE ia2_hypertext=' and an ' caret_offset=8 n_selections=1 selection_start=0 selection_end=8 -++++++ROLE_SYSTEM_GRAPHIC name='Image' IA2_STATE_EDITABLE ia2_hypertext='Image' caret_offset=5 n_selections=1 selection_start=0 selection_end=5 -++++++ROLE_SYSTEM_STATICTEXT name=' and a ' IA2_STATE_EDITABLE ia2_hypertext=' and a ' caret_offset=7 n_selections=1 selection_start=0 selection_end=7 -++++++ROLE_SYSTEM_PUSHBUTTON name='Button' FOCUSABLE IA2_STATE_EDITABLE ia2_hypertext='Button' caret_offset=6 n_selections=1 selection_start=0 selection_end=6 -++++++ROLE_SYSTEM_STATICTEXT name='.' IA2_STATE_EDITABLE ia2_hypertext='.' caret_offset=1 n_selections=1 selection_start=0 selection_end=1 -++++ROLE_SYSTEM_TABLE IA2_STATE_EDITABLE ia2_hypertext='<obj0><obj1><obj2>' caret_offset=3 n_selections=1 selection_start=0 selection_end=3 -++++++ROLE_SYSTEM_ROW IA2_STATE_EDITABLE ia2_hypertext='<obj0>' caret_offset=1 n_selections=1 selection_start=0 selection_end=1 -++++++++ROLE_SYSTEM_CELL IA2_STATE_EDITABLE ia2_hypertext='Always expose editable tables as tables.' caret_offset=40 n_selections=1 selection_start=0 selection_end=40 -++++++++++ROLE_SYSTEM_STATICTEXT name='Always expose editable tables as tables.' IA2_STATE_EDITABLE ia2_hypertext='Always expose editable tables as tables.' caret_offset=40 n_selections=1 selection_start=0 selection_end=40 +++++IA2_ROLE_PARAGRAPH IA2_STATE_EDITABLE ia2_hypertext='A contenteditable with a <obj1> and an <obj3> and a <obj5>.' n_selections=1 selection_start=0 selection_end=44 +++++++ROLE_SYSTEM_STATICTEXT name='A contenteditable with a ' IA2_STATE_EDITABLE ia2_hypertext='A contenteditable with a ' n_selections=1 selection_start=0 selection_end=25 +++++++ROLE_SYSTEM_LINK name='link' LINKED IA2_STATE_EDITABLE ia2_hypertext='link' n_selections=1 selection_start=0 selection_end=4 +++++++++ROLE_SYSTEM_STATICTEXT name='link' LINKED IA2_STATE_EDITABLE ia2_hypertext='link' n_selections=1 selection_start=0 selection_end=4 +++++++ROLE_SYSTEM_STATICTEXT name=' and an ' IA2_STATE_EDITABLE ia2_hypertext=' and an ' n_selections=1 selection_start=0 selection_end=8 +++++++ROLE_SYSTEM_GRAPHIC name='Image' IA2_STATE_EDITABLE ia2_hypertext='Image' n_selections=1 selection_start=0 selection_end=5 +++++++ROLE_SYSTEM_STATICTEXT name=' and a ' IA2_STATE_EDITABLE ia2_hypertext=' and a ' n_selections=1 selection_start=0 selection_end=7 +++++++ROLE_SYSTEM_PUSHBUTTON name='Button' FOCUSABLE IA2_STATE_EDITABLE ia2_hypertext='Button' n_selections=1 selection_start=0 selection_end=6 +++++++ROLE_SYSTEM_STATICTEXT name='.' IA2_STATE_EDITABLE ia2_hypertext='.' n_selections=1 selection_start=0 selection_end=1 +++++ROLE_SYSTEM_TABLE IA2_STATE_EDITABLE ia2_hypertext='<obj0><obj1><obj2>' n_selections=1 selection_start=0 selection_end=3 +++++++ROLE_SYSTEM_ROW IA2_STATE_EDITABLE ia2_hypertext='<obj0>' n_selections=1 selection_start=0 selection_end=1 +++++++++ROLE_SYSTEM_CELL IA2_STATE_EDITABLE ia2_hypertext='Always expose editable tables as tables.' n_selections=1 selection_start=0 selection_end=40 +++++++++++ROLE_SYSTEM_STATICTEXT name='Always expose editable tables as tables.' IA2_STATE_EDITABLE ia2_hypertext='Always expose editable tables as tables.' n_selections=1 selection_start=0 selection_end=40 ++++++ROLE_SYSTEM_COLUMN n_selections=0 ++++++IA2_ROLE_SECTION n_selections=0 ++++ROLE_SYSTEM_LIST IA2_STATE_EDITABLE ia2_hypertext='<obj0>' caret_offset=1 n_selections=1 selection_start=0 selection_end=1 ++++++ROLE_SYSTEM_LISTITEM name='Editable list item.' IA2_STATE_EDITABLE ia2_hypertext='<obj0>Editable list item.' caret_offset=20 n_selections=1 selection_start=0 selection_end=20 -++++++++ROLE_SYSTEM_STATICTEXT name='1' ia2_hypertext='1' caret_offset=1 n_selections=1 selection_start=0 selection_end=1 +++++++++ROLE_SYSTEM_STATICTEXT name='1' ia2_hypertext='1' n_selections=1 selection_start=0 selection_end=1 ++++++++ROLE_SYSTEM_STATICTEXT name='Editable list item.' IA2_STATE_EDITABLE ia2_hypertext='Editable list item.' caret_offset=19 n_selections=1 selection_start=0 selection_end=19
diff --git a/content/test/gpu/gpu_tests/webgl_conformance.py b/content/test/gpu/gpu_tests/webgl_conformance.py index d576894..a23311d3 100644 --- a/content/test/gpu/gpu_tests/webgl_conformance.py +++ b/content/test/gpu/gpu_tests/webgl_conformance.py
@@ -88,6 +88,7 @@ '--disable-gesture-requirement-for-media-playback', '--disable-domain-blocking-for-3d-apis', '--disable-gpu-process-crash-limit', + '--js-flags=--expose-gc', '--test-type=gpu' ]) browser = browser_finder.FindBrowser(options.finder_options) @@ -116,6 +117,7 @@ '--disable-gesture-requirement-for-media-playback', '--disable-domain-blocking-for-3d-apis', '--disable-gpu-process-crash-limit', + '--js-flags=--expose-gc', '--enable-unsafe-es3-apis', '--test-type=gpu' ])
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py index e7b4ff9..282925e3 100644 --- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -36,10 +36,14 @@ bug=478572) self.Fail('deqp/data/gles2/shaders/scoping.html', bug=478572) + self.Fail('conformance/extensions/ext-sRGB.html', + bug=540900) + self.Fail('conformance/extensions/oes-standard-derivatives.html', + bug=5400916) + self.Fail('conformance/extensions/ext-frag-depth.html', + bug=5400916) self.Fail('conformance/misc/expando-loss.html', bug=485634) - self.Fail('conformance/buffers/buffer-data-array-buffer.html', - bug=535077) # Win failures self.Fail('conformance/glsl/bugs/' + @@ -109,6 +113,16 @@ self.Fail('deqp/data/gles2/shaders/swizzles.html', ['win', 'amd', 'opengl'], bug=1007) # angle bug ID + # Win / OpenGL / Intel failures + self.Fail('conformance/extensions/webgl-draw-buffers.html', + ['win', 'intel', 'opengl'], bug=1007) # angle bug ID + self.Fail('conformance/glsl/functions/glsl-function-normalize.html', + ['win', 'intel', 'opengl'], bug=1007) # angle bug ID + self.Fail('conformance/glsl/misc/shader-struct-scope.html', + ['win', 'intel', 'opengl'], bug=1007) # angle bug ID + self.Fail('conformance/uniforms/uniform-default-values.html', + ['win', 'intel', 'opengl'], bug=1007) # angle bug ID + # Mac failures self.Fail('conformance/glsl/misc/shaders-with-invariance.html', ['mac'], bug=421710)
diff --git a/content/test/gpu_memory_buffer_factory_test_template.h b/content/test/gpu_memory_buffer_factory_test_template.h new file mode 100644 index 0000000..e4240128 --- /dev/null +++ b/content/test/gpu_memory_buffer_factory_test_template.h
@@ -0,0 +1,55 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file defines tests that implementations of GpuMemoryBufferFactory should +// pass in order to be conformant. + +#ifndef CONTENT_TEST_GPU_MEMORY_BUFFER_FACTORY_TEST_TEMPLATE_H_ +#define CONTENT_TEST_GPU_MEMORY_BUFFER_FACTORY_TEST_TEMPLATE_H_ + +#include "content/common/gpu/gpu_memory_buffer_factory.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/buffer_format_util.h" + +namespace content { + +template <typename GpuMemoryBufferFactoryType> +class GpuMemoryBufferFactoryTest : public testing::Test { + protected: + GpuMemoryBufferFactoryType factory_; +}; + +TYPED_TEST_CASE_P(GpuMemoryBufferFactoryTest); + +TYPED_TEST_P(GpuMemoryBufferFactoryTest, CreateGpuMemoryBuffer) { + const gfx::GpuMemoryBufferId kBufferId(1); + const int kClientId = 1; + + gfx::Size buffer_size(2, 2); + + for (auto format : gfx::GetBufferFormats()) { + gfx::BufferUsage usages[] = {gfx::BufferUsage::MAP, + gfx::BufferUsage::PERSISTENT_MAP, + gfx::BufferUsage::SCANOUT}; + for (auto usage : usages) { + if (!TypeParam::IsGpuMemoryBufferConfigurationSupported(format, usage)) + continue; + + gfx::GpuMemoryBufferHandle handle = + TestFixture::factory_.CreateGpuMemoryBuffer(kBufferId, buffer_size, + format, usage, kClientId, + gfx::kNullPluginWindow); + EXPECT_NE(handle.type, gfx::EMPTY_BUFFER); + TestFixture::factory_.DestroyGpuMemoryBuffer(kBufferId, kClientId); + } + } +} + +// The GpuMemoryBufferFactoryTest test case verifies behavior that is expected +// from a GpuMemoryBuffer factory in order to be conformant. +REGISTER_TYPED_TEST_CASE_P(GpuMemoryBufferFactoryTest, CreateGpuMemoryBuffer); + +} // namespace content + +#endif // CONTENT_TEST_GPU_MEMORY_BUFFER_FACTORY_TEST_TEMPLATE_H_
diff --git a/content/test/gpu_memory_buffer_impl_test_template.h b/content/test/gpu_memory_buffer_impl_test_template.h new file mode 100644 index 0000000..bb3d82c6 --- /dev/null +++ b/content/test/gpu_memory_buffer_impl_test_template.h
@@ -0,0 +1,225 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file defines tests that implementations of GpuMemoryBufferFactory should +// pass in order to be conformant. + +#ifndef CONTENT_TEST_GPU_MEMORY_BUFFER_IMPL_TEST_TEMPLATE_H_ +#define CONTENT_TEST_GPU_MEMORY_BUFFER_IMPL_TEST_TEMPLATE_H_ + +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/buffer_format_util.h" + +namespace content { + +template <typename GpuMemoryBufferImplType> +class GpuMemoryBufferImplTest : public testing::Test { + public: + GpuMemoryBufferImpl::DestructionCallback AllocateGpuMemoryBuffer( + const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + gfx::GpuMemoryBufferHandle* handle, + bool* destroyed) { + return base::Bind(&GpuMemoryBufferImplTest::FreeGpuMemoryBuffer, + base::Unretained(this), + GpuMemoryBufferImplType::AllocateForTesting( + size, format, usage, handle), + base::Unretained(destroyed)); + } + + private: + void FreeGpuMemoryBuffer(const base::Closure& free_callback, + bool* destroyed, + uint32 sync_point) { + free_callback.Run(); + if (destroyed) + *destroyed = true; + } +}; + +TYPED_TEST_CASE_P(GpuMemoryBufferImplTest); + +TYPED_TEST_P(GpuMemoryBufferImplTest, CreateFromHandle) { + gfx::Size buffer_size(8, 8); + + for (auto format : gfx::GetBufferFormats()) { + gfx::BufferUsage usages[] = {gfx::BufferUsage::MAP, + gfx::BufferUsage::PERSISTENT_MAP, + gfx::BufferUsage::SCANOUT}; + for (auto usage : usages) { + if (!TypeParam::IsConfigurationSupported(format, usage)) + continue; + + bool destroyed = false; + gfx::GpuMemoryBufferHandle handle; + GpuMemoryBufferImpl::DestructionCallback destroy_callback = + TestFixture::AllocateGpuMemoryBuffer( + buffer_size, format, gfx::BufferUsage::MAP, &handle, &destroyed); + scoped_ptr<TypeParam> buffer(TypeParam::CreateFromHandle( + handle, buffer_size, format, usage, destroy_callback)); + ASSERT_TRUE(buffer); + EXPECT_EQ(buffer->GetFormat(), format); + + // Check if destruction callback is executed when deleting the buffer. + buffer.reset(); + ASSERT_TRUE(destroyed); + } + } +} + +TYPED_TEST_P(GpuMemoryBufferImplTest, Map) { + // Use a multiple of 4 for both dimensions to support compressed formats. + gfx::Size buffer_size(4, 4); + + for (auto format : gfx::GetBufferFormats()) { + if (!TypeParam::IsConfigurationSupported(format, gfx::BufferUsage::MAP)) + continue; + + gfx::GpuMemoryBufferHandle handle; + GpuMemoryBufferImpl::DestructionCallback destroy_callback = + TestFixture::AllocateGpuMemoryBuffer( + buffer_size, format, gfx::BufferUsage::MAP, &handle, nullptr); + scoped_ptr<TypeParam> buffer(TypeParam::CreateFromHandle( + handle, buffer_size, format, gfx::BufferUsage::MAP, destroy_callback)); + ASSERT_TRUE(buffer); + EXPECT_FALSE(buffer->IsMapped()); + + size_t num_planes = gfx::NumberOfPlanesForBufferFormat(format); + + // Map buffer into user space. + scoped_ptr<void* []> mapped_buffers(new void*[num_planes]); + bool rv = buffer->Map(mapped_buffers.get()); + ASSERT_TRUE(rv); + EXPECT_TRUE(buffer->IsMapped()); + + // Get strides. + scoped_ptr<int[]> strides(new int[num_planes]); + buffer->GetStride(strides.get()); + + // Copy and compare mapped buffers. + for (size_t plane = 0; plane < num_planes; ++plane) { + size_t row_size_in_bytes = 0; + EXPECT_TRUE(gfx::RowSizeForBufferFormatChecked( + buffer_size.width(), format, plane, &row_size_in_bytes)); + EXPECT_GT(row_size_in_bytes, 0u); + + scoped_ptr<char[]> data(new char[row_size_in_bytes]); + memset(data.get(), 0x2a + plane, row_size_in_bytes); + + size_t height = buffer_size.height() / + gfx::SubsamplingFactorForBufferFormat(format, plane); + for (size_t y = 0; y < height; ++y) { + memcpy(static_cast<char*>(mapped_buffers[plane]) + y * strides[plane], + data.get(), row_size_in_bytes); + EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers[plane]) + + y * strides[plane], + data.get(), row_size_in_bytes), + 0); + } + } + + buffer->Unmap(); + EXPECT_FALSE(buffer->IsMapped()); + } +} + +TYPED_TEST_P(GpuMemoryBufferImplTest, PersistentMap) { + // Use a multiple of 4 for both dimensions to support compressed formats. + gfx::Size buffer_size(4, 4); + + for (auto format : gfx::GetBufferFormats()) { + if (!TypeParam::IsConfigurationSupported( + format, gfx::BufferUsage::PERSISTENT_MAP)) { + continue; + } + + gfx::GpuMemoryBufferHandle handle; + GpuMemoryBufferImpl::DestructionCallback destroy_callback = + TestFixture::AllocateGpuMemoryBuffer(buffer_size, format, + gfx::BufferUsage::PERSISTENT_MAP, + &handle, nullptr); + scoped_ptr<TypeParam> buffer(TypeParam::CreateFromHandle( + handle, buffer_size, format, gfx::BufferUsage::PERSISTENT_MAP, + destroy_callback)); + ASSERT_TRUE(buffer); + EXPECT_FALSE(buffer->IsMapped()); + + size_t num_planes = gfx::NumberOfPlanesForBufferFormat(format); + + // Map buffer into user space. + scoped_ptr<void* []> mapped_buffers(new void*[num_planes]); + bool rv = buffer->Map(mapped_buffers.get()); + ASSERT_TRUE(rv); + EXPECT_TRUE(buffer->IsMapped()); + + // Get strides. + scoped_ptr<int[]> strides(new int[num_planes]); + buffer->GetStride(strides.get()); + + // Copy and compare mapped buffers. + for (size_t plane = 0; plane < num_planes; ++plane) { + size_t row_size_in_bytes; + EXPECT_TRUE(gfx::RowSizeForBufferFormatChecked( + buffer_size.width(), format, plane, &row_size_in_bytes)); + EXPECT_GT(row_size_in_bytes, 0u); + + scoped_ptr<char[]> data(new char[row_size_in_bytes]); + memset(data.get(), 0x2a + plane, row_size_in_bytes); + + size_t height = buffer_size.height() / + gfx::SubsamplingFactorForBufferFormat(format, plane); + for (size_t y = 0; y < height; ++y) { + memcpy(static_cast<char*>(mapped_buffers[plane]) + y * strides[plane], + data.get(), row_size_in_bytes); + EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers[plane]) + + y * strides[plane], + data.get(), row_size_in_bytes), + 0); + } + } + + buffer->Unmap(); + EXPECT_FALSE(buffer->IsMapped()); + + // Remap the buffer, and compare again. It should contain the same data. + rv = buffer->Map(mapped_buffers.get()); + ASSERT_TRUE(rv); + EXPECT_TRUE(buffer->IsMapped()); + + buffer->GetStride(strides.get()); + + for (size_t plane = 0; plane < num_planes; ++plane) { + size_t row_size_in_bytes; + EXPECT_TRUE(gfx::RowSizeForBufferFormatChecked( + buffer_size.width(), format, plane, &row_size_in_bytes)); + + scoped_ptr<char[]> data(new char[row_size_in_bytes]); + memset(data.get(), 0x2a + plane, row_size_in_bytes); + + size_t height = buffer_size.height() / + gfx::SubsamplingFactorForBufferFormat(format, plane); + for (size_t y = 0; y < height; ++y) { + EXPECT_EQ(memcmp(static_cast<char*>(mapped_buffers[plane]) + + y * strides[plane], + data.get(), row_size_in_bytes), + 0); + } + } + + buffer->Unmap(); + EXPECT_FALSE(buffer->IsMapped()); + } +} + +// The GpuMemoryBufferImplTest test case verifies behavior that is expected +// from a GpuMemoryBuffer implementation in order to be conformant. +REGISTER_TYPED_TEST_CASE_P(GpuMemoryBufferImplTest, + CreateFromHandle, + Map, + PersistentMap); + +} // namespace content + +#endif // CONTENT_TEST_GPU_MEMORY_BUFFER_IMPL_TEST_TEMPLATE_H_
diff --git a/content/test/web_layer_tree_view_impl_for_testing.cc b/content/test/web_layer_tree_view_impl_for_testing.cc index 45a4a288..e2d5275 100644 --- a/content/test/web_layer_tree_view_impl_for_testing.cc +++ b/content/test/web_layer_tree_view_impl_for_testing.cc
@@ -13,18 +13,14 @@ #include "cc/input/input_handler.h" #include "cc/layers/layer.h" #include "cc/scheduler/begin_frame_source.h" -#include "cc/test/pixel_test_output_surface.h" -#include "cc/test/test_context_provider.h" #include "cc/trees/layer_tree_host.h" #include "content/test/test_blink_web_unit_test_support.h" #include "third_party/WebKit/public/platform/Platform.h" -#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" #include "third_party/WebKit/public/platform/WebLayer.h" #include "third_party/WebKit/public/platform/WebLayerTreeView.h" #include "third_party/WebKit/public/platform/WebSize.h" using blink::WebColor; -using blink::WebGraphicsContext3D; using blink::WebRect; using blink::WebSize; @@ -127,15 +123,11 @@ } void WebLayerTreeViewImplForTesting::RequestNewOutputSurface() { - // TODO(crbug.com/540026): Fix crashes with real OutputSurface - // bool flipped_output_surface = false; - // layer_tree_host_->SetOutputSurface( - // make_scoped_ptr(new cc::PixelTestOutputSurface( - // cc::TestContextProvider::Create(), flipped_output_surface))); + // Intentionally do not create and set an OutputSurface. } void WebLayerTreeViewImplForTesting::DidFailToInitializeOutputSurface() { - RequestNewOutputSurface(); + NOTREACHED(); } void WebLayerTreeViewImplForTesting::registerForAnimations(
diff --git a/content/test/web_layer_tree_view_impl_for_testing.h b/content/test/web_layer_tree_view_impl_for_testing.h index 01192f442..70ffc0f 100644 --- a/content/test/web_layer_tree_view_impl_for_testing.h +++ b/content/test/web_layer_tree_view_impl_for_testing.h
@@ -19,6 +19,7 @@ namespace content { +// Dummy WeblayerTeeView that does not support any actual compositing. class WebLayerTreeViewImplForTesting : public blink::WebLayerTreeView, public cc::LayerTreeHostClient,
diff --git a/extensions/common/api/networking_private.idl b/extensions/common/api/networking_private.idl index ea77c3c6..2cf52fd 100644 --- a/extensions/common/api/networking_private.idl +++ b/extensions/common/api/networking_private.idl
@@ -77,10 +77,10 @@ // SharedSetting: The value set for all users of the device. Only provided if // DeviceEditiable is true (i.e. no policy affects the property or the // policy provided value is recommened only). - // UserEditable: True if the UserPolicy allows the property to be edited - // (i.e. is a recommended value). Defaults to True. - // DeviceEditable: True if the DevicePolicy allows the property to be - // edited (i.e. is a recommended value). Defaults to True. + // UserEditable: True if a UserPolicy exists and allows the property to be + // edited (i.e. is a recommended value). Defaults to False. + // DeviceEditable: True if a DevicePolicy exists and allows the property to be + // edited (i.e. is a recommended value). Defaults to False. dictionary ManagedBoolean { boolean? Active; @@ -555,11 +555,13 @@ }; dictionary EthernetProperties { + boolean? AutoConnect; DOMString? Authentication; EAPProperties? EAP; }; dictionary ManagedEthernetProperties { + ManagedBoolean? AutoConnect; ManagedDOMString? Authentication; ManagedEAPProperties? EAP; };
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index 34ca8cba..94eb30e7 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn
@@ -127,6 +127,7 @@ "command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc", "command_buffer/tests/gl_cube_map_texture_unittest.cc", "command_buffer/tests/gl_depth_texture_unittest.cc", + "command_buffer/tests/gl_fence_sync_unittest.cc", "command_buffer/tests/gl_gpu_memory_buffer_unittest.cc", "command_buffer/tests/gl_lose_context_chromium_unittest.cc", "command_buffer/tests/gl_manager.cc", @@ -262,6 +263,7 @@ "command_buffer/service/shader_manager_unittest.cc", "command_buffer/service/shader_translator_cache_unittest.cc", "command_buffer/service/shader_translator_unittest.cc", + "command_buffer/service/sync_point_manager_unittest.cc", "command_buffer/service/test_helper.cc", "command_buffer/service/test_helper.h", "command_buffer/service/texture_manager_unittest.cc",
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_sync_point.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_sync_point.txt index 9f1863c..80df38e 100644 --- a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_sync_point.txt +++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_sync_point.txt
@@ -41,7 +41,7 @@ The command - uint InsertFenceSyncCHROMIUM() + uint64 InsertFenceSyncCHROMIUM() inserts a fence sync in the current command stream. The fence sync is signaled when previous commands have been submitted to the server, or when @@ -53,7 +53,7 @@ The command - void GenSyncTokenCHROMIUM(uint fence_sync, GLbyte *sync_token) + void GenSyncTokenCHROMIUM(uint64 fence_sync, GLbyte *sync_token) converts <fence_sync> which is only visible to the current context to a sync token which may be waited upon by any contexts on the same server. @@ -67,7 +67,7 @@ The command - void WaitSyncTokenCHROMIUM(GLbyte *sync_token) + void WaitSyncTokenCHROMIUM(const GLbyte *sync_token) causes the current context to stop submitting commands until the specified fence sync becomes signaled. This is implemented as a server-side wait. @@ -79,7 +79,7 @@ The size of a sync token name in bytes. - GL_SYNC_TOKEN_SIZE_CHROMIUM 12 + GL_SYNC_TOKEN_SIZE_CHROMIUM 24 Errors
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index 2e6ed9b..3b30b9b 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -327,6 +327,9 @@ #define glLoseContextCHROMIUM GLES2_GET_FUN(LoseContextCHROMIUM) #define glInsertSyncPointCHROMIUM GLES2_GET_FUN(InsertSyncPointCHROMIUM) #define glWaitSyncPointCHROMIUM GLES2_GET_FUN(WaitSyncPointCHROMIUM) +#define glInsertFenceSyncCHROMIUM GLES2_GET_FUN(InsertFenceSyncCHROMIUM) +#define glGenSyncTokenCHROMIUM GLES2_GET_FUN(GenSyncTokenCHROMIUM) +#define glWaitSyncTokenCHROMIUM GLES2_GET_FUN(WaitSyncTokenCHROMIUM) #define glDrawBuffersEXT GLES2_GET_FUN(DrawBuffersEXT) #define glDiscardBackbufferCHROMIUM GLES2_GET_FUN(DiscardBackbufferCHROMIUM) #define glScheduleOverlayPlaneCHROMIUM \
diff --git a/gpu/GLES2/gl2extchromium.h b/gpu/GLES2/gl2extchromium.h index 74988dc68..51928a3 100644 --- a/gpu/GLES2/gl2extchromium.h +++ b/gpu/GLES2/gl2extchromium.h
@@ -695,12 +695,26 @@ /* GL_CHROMIUM_sync_point */ #ifndef GL_CHROMIUM_sync_point #define GL_CHROMIUM_sync_point 1 + +#ifndef GL_SYNC_TOKEN_SIZE_CHROMIUM +#define GL_SYNC_TOKEN_SIZE_CHROMIUM 24 +#endif + #ifdef GL_GLEXT_PROTOTYPES GL_APICALL GLuint GL_APIENTRY glInsertSyncPointCHROMIUM(); GL_APICALL void GL_APIENTRY glWaitSyncPointCHROMIUM(GLuint sync_point); +GL_APICALL GLuint64 GL_APIENTRY glInsertFenceSyncCHROMIUM(); +GL_APICALL void GL_APIENTRY glGenSyncTokenCHROMIUM(GLuint64 fence_sync, + GLbyte* sync_token); +GL_APICALL void GL_APIENTRY glWaitSyncTokenCHROMIUM(const GLbyte* sync_token); #endif typedef GLuint (GL_APIENTRYP PFNGLINSERTSYNCPOINTCHROMIUMPROC) (); typedef void (GL_APIENTRYP PFNGLWAITSYNCPOINTCHROMIUMPROC) (GLuint sync_point); +typedef GLuint64 (GL_APIENTRYP PFNGLINSERTFENCESYNCCHROMIUMPROC) (); +typedef void (GL_APIENTRYP PFNGLGENSYNCTOKENCHROMIUMPROC) (GLuint64 fence_sync, + GLbyte* sync_token); +typedef void (GL_APIENTRYP PFNGLWAITSYNCTOKENCHROMIUM) ( + const GLbyte* sync_tokens); #endif /* GL_CHROMIUM_sync_point */ #ifndef GL_CHROMIUM_color_buffer_float_rgba
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 597f5259..e726958 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -4090,6 +4090,30 @@ 'chromium': True, 'trace_level': 1, }, + 'InsertFenceSyncCHROMIUM': { + 'type': 'Custom', + 'impl_func': False, + 'cmd_args': 'GLuint64 release_count', + 'extension': "CHROMIUM_sync_point", + 'chromium': True, + 'trace_level': 1, + }, + 'GenSyncTokenCHROMIUM': { + 'type': 'Custom', + 'impl_func': False, + 'extension': "CHROMIUM_sync_point", + 'chromium': True, + }, + 'WaitSyncTokenCHROMIUM': { + 'type': 'Custom', + 'impl_func': False, + 'cmd_args': 'GLuint namespace_id, ' + 'GLuint64 command_buffer_id, ' + 'GLuint64 release_count', + 'client_test': False, + 'extension': "CHROMIUM_sync_point", + 'chromium': True, + }, 'DiscardBackbufferCHROMIUM': { 'type': 'Custom', 'impl_func': True, @@ -4605,9 +4629,7 @@ def WriteHandlerExtensionCheck(self, func, f): if func.GetInfo('extension_flag'): f.write(" if (!features().%s) {\n" % func.GetInfo('extension_flag')) - f.write(" LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, \"gl%s\"," - " \"function not available\");\n" % func.original_name) - f.write(" return error::kNoError;") + f.write(" return error::kUnknownCommand;") f.write(" }\n\n") def WriteHandlerDeferReadWrite(self, func, f):
diff --git a/gpu/command_buffer/client/client_test_helper.h b/gpu/command_buffer/client/client_test_helper.h index e16e089..a0733b5 100644 --- a/gpu/command_buffer/client/client_test_helper.h +++ b/gpu/command_buffer/client/client_test_helper.h
@@ -114,6 +114,9 @@ MOCK_METHOD0(IsGpuChannelLost, bool()); MOCK_CONST_METHOD0(GetNamespaceID, CommandBufferNamespace()); MOCK_CONST_METHOD0(GetCommandBufferID, uint64_t()); + MOCK_METHOD0(GenerateFenceSyncRelease, uint64_t()); + MOCK_METHOD1(IsFenceSyncRelease, bool(uint64_t release)); + MOCK_METHOD1(IsFenceSyncFlushed, bool(uint64_t release)); private: DISALLOW_COPY_AND_ASSIGN(MockClientGpuControl);
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index e1ce501..4b2ee2b 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1481,6 +1481,16 @@ void GL_APIENTRY GLES2WaitSyncPointCHROMIUM(GLuint sync_point) { gles2::GetGLContext()->WaitSyncPointCHROMIUM(sync_point); } +GLuint64 GL_APIENTRY GLES2InsertFenceSyncCHROMIUM() { + return gles2::GetGLContext()->InsertFenceSyncCHROMIUM(); +} +void GL_APIENTRY GLES2GenSyncTokenCHROMIUM(GLuint64 fence_sync, + GLbyte* sync_token) { + gles2::GetGLContext()->GenSyncTokenCHROMIUM(fence_sync, sync_token); +} +void GL_APIENTRY GLES2WaitSyncTokenCHROMIUM(const GLbyte* sync_token) { + gles2::GetGLContext()->WaitSyncTokenCHROMIUM(sync_token); +} void GL_APIENTRY GLES2DrawBuffersEXT(GLsizei count, const GLenum* bufs) { gles2::GetGLContext()->DrawBuffersEXT(count, bufs); } @@ -2720,6 +2730,18 @@ reinterpret_cast<GLES2FunctionPointer>(glWaitSyncPointCHROMIUM), }, { + "glInsertFenceSyncCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glInsertFenceSyncCHROMIUM), + }, + { + "glGenSyncTokenCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glGenSyncTokenCHROMIUM), + }, + { + "glWaitSyncTokenCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glWaitSyncTokenCHROMIUM), + }, + { "glDrawBuffersEXT", reinterpret_cast<GLES2FunctionPointer>(glDrawBuffersEXT), },
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index fb77fa2..b722d6e 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -2757,6 +2757,34 @@ } } +void InsertFenceSyncCHROMIUM(GLuint64 release_count) { + gles2::cmds::InsertFenceSyncCHROMIUM* c = + GetCmdSpace<gles2::cmds::InsertFenceSyncCHROMIUM>(); + if (c) { + c->Init(release_count); + } +} + +void GenSyncTokenCHROMIUMImmediate(GLuint64 fence_sync) { + const uint32_t s = 0; // TODO(gman): compute correct size + gles2::cmds::GenSyncTokenCHROMIUMImmediate* c = + GetImmediateCmdSpaceTotalSize<gles2::cmds::GenSyncTokenCHROMIUMImmediate>( + s); + if (c) { + c->Init(fence_sync); + } +} + +void WaitSyncTokenCHROMIUM(GLuint namespace_id, + GLuint64 command_buffer_id, + GLuint64 release_count) { + gles2::cmds::WaitSyncTokenCHROMIUM* c = + GetCmdSpace<gles2::cmds::WaitSyncTokenCHROMIUM>(); + if (c) { + c->Init(namespace_id, command_buffer_id, release_count); + } +} + void DrawBuffersEXTImmediate(GLsizei count, const GLenum* bufs) { const uint32_t size = gles2::cmds::DrawBuffersEXTImmediate::ComputeSize(count);
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 2b186a4..27bdd8a 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -5364,6 +5364,48 @@ return share_group_->TracingGUID(); } +GLuint64 GLES2Implementation::InsertFenceSyncCHROMIUM() { + const uint64_t release = gpu_control_->GenerateFenceSyncRelease(); + helper_->InsertFenceSyncCHROMIUM(release); + return release; +} + +void GLES2Implementation::GenSyncTokenCHROMIUM(GLuint64 fence_sync, + GLbyte* sync_token) { + if (!sync_token) { + SetGLError(GL_INVALID_VALUE, "glGenSyncTokenCHROMIUM", "empty sync_token"); + return; + } else if (!gpu_control_->IsFenceSyncRelease(fence_sync)) { + SetGLError(GL_INVALID_VALUE, "glGenSyncTokenCHROMIUM", + "invalid fence sync"); + return; + } else if (!gpu_control_->IsFenceSyncFlushed(fence_sync)) { + SetGLError(GL_INVALID_OPERATION, "glGenSyncTokenCHROMIUM", + "fence sync must be flushed before generating sync token"); + return; + } + + SyncToken* sync_token_data = reinterpret_cast<SyncToken*>(sync_token); + memset(sync_token_data, 0, sizeof(SyncToken)); + + sync_token_data->namespace_id = gpu_control_->GetNamespaceID(); + sync_token_data->command_buffer_id = gpu_control_->GetCommandBufferID(); + sync_token_data->release_count = fence_sync; +} + +void GLES2Implementation::WaitSyncTokenCHROMIUM(const GLbyte* sync_token) { + if (!sync_token) { + SetGLError(GL_INVALID_VALUE, "glWaitSyncTokenCHROMIUM", "empty sync_token"); + return; + }; + + const SyncToken* sync_token_data = + reinterpret_cast<const SyncToken*>(sync_token); + helper_->WaitSyncTokenCHROMIUM(sync_token_data->namespace_id, + sync_token_data->command_buffer_id, + sync_token_data->release_count); +} + namespace { bool ValidImageFormat(GLenum internalformat,
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index 305f971..3d551a9 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1027,6 +1027,12 @@ void WaitSyncPointCHROMIUM(GLuint sync_point) override; +GLuint64 InsertFenceSyncCHROMIUM() override; + +void GenSyncTokenCHROMIUM(GLuint64 fence_sync, GLbyte* sync_token) override; + +void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) override; + void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override; void DiscardBackbufferCHROMIUM() override;
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index 35218c3..d53e647 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -3741,6 +3741,84 @@ EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); } +TEST_F(GLES2ImplementationTest, InsertFenceSyncCHROMIUM) { + const GLuint64 kFenceSync = 123u; + EXPECT_CALL(*gpu_control_, GenerateFenceSyncRelease()) + .WillOnce(testing::Return(kFenceSync)); + + struct Cmds { + cmds::InsertFenceSyncCHROMIUM insert_fence_sync; + }; + Cmds expected; + expected.insert_fence_sync.Init(kFenceSync); + + const GLuint64 fence_sync = gl_->InsertFenceSyncCHROMIUM(); + EXPECT_EQ(kFenceSync, fence_sync); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, GenSyncTokenCHROMIUM) { + const CommandBufferNamespace kNamespaceId = CommandBufferNamespace::GPU_IO; + const GLuint64 kCommandBufferId = 234u; + const GLuint64 kFenceSync = 123u; + GLbyte sync_token[GL_SYNC_TOKEN_SIZE_CHROMIUM]; + + EXPECT_CALL(*gpu_control_, GetNamespaceID()) + .WillRepeatedly(testing::Return(kNamespaceId)); + EXPECT_CALL(*gpu_control_, GetCommandBufferID()) + .WillRepeatedly(testing::Return(kCommandBufferId)); + + gl_->GenSyncTokenCHROMIUM(kFenceSync, nullptr); + EXPECT_EQ(GL_INVALID_VALUE, CheckError()); + + EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync)) + .WillOnce(testing::Return(false)); + gl_->GenSyncTokenCHROMIUM(kFenceSync, sync_token); + EXPECT_EQ(GL_INVALID_VALUE, CheckError()); + + EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync)) + .WillOnce(testing::Return(true)); + EXPECT_CALL(*gpu_control_, IsFenceSyncFlushed(kFenceSync)) + .WillOnce(testing::Return(false)); + gl_->GenSyncTokenCHROMIUM(kFenceSync, sync_token); + EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); + + EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync)) + .WillOnce(testing::Return(true)); + EXPECT_CALL(*gpu_control_, IsFenceSyncFlushed(kFenceSync)) + .WillOnce(testing::Return(true)); + ClearCommands(); + gl_->GenSyncTokenCHROMIUM(kFenceSync, sync_token); + EXPECT_TRUE(NoCommandsWritten()); + EXPECT_EQ(GL_NO_ERROR, CheckError()); +} + +TEST_F(GLES2ImplementationTest, WaitSyncTokenCHROMIUM) { + const CommandBufferNamespace kNamespaceId = CommandBufferNamespace::GPU_IO; + const GLuint64 kCommandBufferId = 234u; + const GLuint64 kFenceSync = 456u; + GLbyte sync_token[GL_SYNC_TOKEN_SIZE_CHROMIUM]; + + EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync)) + .WillOnce(testing::Return(true)); + EXPECT_CALL(*gpu_control_, IsFenceSyncFlushed(kFenceSync)) + .WillOnce(testing::Return(true)); + EXPECT_CALL(*gpu_control_, GetNamespaceID()) + .WillOnce(testing::Return(kNamespaceId)); + EXPECT_CALL(*gpu_control_, GetCommandBufferID()) + .WillOnce(testing::Return(kCommandBufferId)); + gl_->GenSyncTokenCHROMIUM(kFenceSync, sync_token); + + struct Cmds { + cmds::WaitSyncTokenCHROMIUM wait_sync_token; + }; + Cmds expected; + expected.wait_sync_token.Init(kNamespaceId, kCommandBufferId, kFenceSync); + + gl_->WaitSyncTokenCHROMIUM(sync_token); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, IsEnabled) { // If we use a valid enum, its state is cached on client side, so no command // is actually generated, and this test will fail.
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index 949ec7e..3f96294 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -3093,6 +3093,8 @@ gl_->WaitSyncPointCHROMIUM(1); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +// TODO(zmo): Implement unit test for InsertFenceSyncCHROMIUM +// TODO(zmo): Implement unit test for GenSyncTokenCHROMIUM TEST_F(GLES2ImplementationTest, DrawBuffersEXT) { GLenum data[1][1] = {{0}};
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index 43e3b905..9b97beb 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -762,6 +762,9 @@ virtual void LoseContextCHROMIUM(GLenum current, GLenum other) = 0; virtual GLuint InsertSyncPointCHROMIUM() = 0; virtual void WaitSyncPointCHROMIUM(GLuint sync_point) = 0; +virtual GLuint64 InsertFenceSyncCHROMIUM() = 0; +virtual void GenSyncTokenCHROMIUM(GLuint64 fence_sync, GLbyte* sync_token) = 0; +virtual void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) = 0; virtual void DrawBuffersEXT(GLsizei count, const GLenum* bufs) = 0; virtual void DiscardBackbufferCHROMIUM() = 0; virtual void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 0d08d67..e795738b 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -738,6 +738,9 @@ void LoseContextCHROMIUM(GLenum current, GLenum other) override; GLuint InsertSyncPointCHROMIUM() override; void WaitSyncPointCHROMIUM(GLuint sync_point) override; +GLuint64 InsertFenceSyncCHROMIUM() override; +void GenSyncTokenCHROMIUM(GLuint64 fence_sync, GLbyte* sync_token) override; +void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) override; void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override; void DiscardBackbufferCHROMIUM() override; void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index 6e30251..e7511e4 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -1011,6 +1011,13 @@ return 0; } void GLES2InterfaceStub::WaitSyncPointCHROMIUM(GLuint /* sync_point */) {} +GLuint64 GLES2InterfaceStub::InsertFenceSyncCHROMIUM() { + return 0; +} +void GLES2InterfaceStub::GenSyncTokenCHROMIUM(GLuint64 /* fence_sync */, + GLbyte* /* sync_token */) {} +void GLES2InterfaceStub::WaitSyncTokenCHROMIUM(const GLbyte* /* sync_token */) { +} void GLES2InterfaceStub::DrawBuffersEXT(GLsizei /* count */, const GLenum* /* bufs */) {} void GLES2InterfaceStub::DiscardBackbufferCHROMIUM() {}
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 41140beb..f9580d0c 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -738,6 +738,9 @@ void LoseContextCHROMIUM(GLenum current, GLenum other) override; GLuint InsertSyncPointCHROMIUM() override; void WaitSyncPointCHROMIUM(GLuint sync_point) override; +GLuint64 InsertFenceSyncCHROMIUM() override; +void GenSyncTokenCHROMIUM(GLuint64 fence_sync, GLbyte* sync_token) override; +void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) override; void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override; void DiscardBackbufferCHROMIUM() override; void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 11d76df9..86c547d 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -2160,6 +2160,22 @@ gl_->WaitSyncPointCHROMIUM(sync_point); } +GLuint64 GLES2TraceImplementation::InsertFenceSyncCHROMIUM() { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::InsertFenceSyncCHROMIUM"); + return gl_->InsertFenceSyncCHROMIUM(); +} + +void GLES2TraceImplementation::GenSyncTokenCHROMIUM(GLuint64 fence_sync, + GLbyte* sync_token) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GenSyncTokenCHROMIUM"); + gl_->GenSyncTokenCHROMIUM(fence_sync, sync_token); +} + +void GLES2TraceImplementation::WaitSyncTokenCHROMIUM(const GLbyte* sync_token) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::WaitSyncTokenCHROMIUM"); + gl_->WaitSyncTokenCHROMIUM(sync_token); +} + void GLES2TraceImplementation::DrawBuffersEXT(GLsizei count, const GLenum* bufs) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DrawBuffersEXT");
diff --git a/gpu/command_buffer/client/gpu_control.h b/gpu/command_buffer/client/gpu_control.h index 7065d1ed..7000152 100644 --- a/gpu/command_buffer/client/gpu_control.h +++ b/gpu/command_buffer/client/gpu_control.h
@@ -96,6 +96,14 @@ virtual CommandBufferNamespace GetNamespaceID() const = 0; virtual uint64_t GetCommandBufferID() const = 0; + // Fence Syncs use release counters at a context level, these fence syncs + // need to be flushed before they can be shared with other contexts across + // channels. Subclasses should implement these functions and take care of + // figuring out when a fence sync has been flushed. + virtual uint64_t GenerateFenceSyncRelease() = 0; + virtual bool IsFenceSyncRelease(uint64_t release) = 0; + virtual bool IsFenceSyncFlushed(uint64_t release) = 0; + private: DISALLOW_COPY_AND_ASSIGN(GpuControl); };
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index 9eda893e..9e97d6e 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -307,6 +307,9 @@ GL_APICALL void GL_APIENTRY glLoseContextCHROMIUM (GLenumResetStatus current, GLenumResetStatus other); GL_APICALL GLuint GL_APIENTRY glInsertSyncPointCHROMIUM (void); GL_APICALL void GL_APIENTRY glWaitSyncPointCHROMIUM (GLuint sync_point); +GL_APICALL GLuint64 GL_APIENTRY glInsertFenceSyncCHROMIUM (void); +GL_APICALL void GL_APIENTRY glGenSyncTokenCHROMIUM (GLuint64 fence_sync, GLbyte* sync_token); +GL_APICALL void GL_APIENTRY glWaitSyncTokenCHROMIUM (const GLbyte* sync_token); GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei count, const GLenum* bufs); GL_APICALL void GL_APIENTRY glDiscardBackbufferCHROMIUM (void); GL_APICALL void GL_APIENTRY glScheduleOverlayPlaneCHROMIUM (GLint plane_z_order, GLenum plane_transform, GLuint overlay_texture_id, GLint bounds_x, GLint bounds_y, GLint bounds_width, GLint bounds_height, GLfloat uv_x, GLfloat uv_y, GLfloat uv_width, GLfloat uv_height);
diff --git a/gpu/command_buffer/common/constants.h b/gpu/command_buffer/common/constants.h index e14c06d..0d3180140 100644 --- a/gpu/command_buffer/common/constants.h +++ b/gpu/command_buffer/common/constants.h
@@ -8,6 +8,11 @@ #include <stddef.h> #include <stdint.h> +// From glextchromium.h. +#ifndef GL_SYNC_TOKEN_SIZE_CHROMIUM +#define GL_SYNC_TOKEN_SIZE_CHROMIUM 24 +#endif + namespace gpu { typedef int32_t CommandBufferOffset;
diff --git a/gpu/command_buffer/common/gles2_cmd_format.h b/gpu/command_buffer/common/gles2_cmd_format.h index e4d00dd4..09b87a9 100644 --- a/gpu/command_buffer/common/gles2_cmd_format.h +++ b/gpu/command_buffer/common/gles2_cmd_format.h
@@ -18,6 +18,7 @@ #include "base/macros.h" #include "gpu/command_buffer/common/bitfield_helpers.h" #include "gpu/command_buffer/common/cmd_buffer_common.h" +#include "gpu/command_buffer/common/constants.h" #include "gpu/command_buffer/common/gles2_cmd_ids.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" @@ -202,6 +203,23 @@ // UniformES3Info uniforms[num_uniforms]; }; +// The format of fence sync tokens. +struct SyncToken { + CommandBufferNamespace namespace_id; + uint64_t command_buffer_id; + uint64_t release_count; + + bool operator<(const SyncToken& other) const { + // TODO(dyen): Once all our compilers support c++11, we can replace this + // long list of comparisons with std::tie(). + return (namespace_id < other.namespace_id) || + ((namespace_id == other.namespace_id) && + ((command_buffer_id < other.command_buffer_id) || + ((command_buffer_id == other.command_buffer_id) && + (release_count < other.release_count)))); + } +}; + // The format of QuerySync used by EXT_occlusion_query_boolean struct QuerySync { void Reset() { @@ -296,6 +314,9 @@ static_assert(offsetof(UniformBlocksHeader, num_uniform_blocks) == 0, "offset of UniformBlocksHeader.num_uniform_blocks should be 0"); +static_assert(sizeof(SyncToken) <= GL_SYNC_TOKEN_SIZE_CHROMIUM, + "size of SyncToken must not exceed GL_SYNC_TOKEN_SIZE_CHROMIUM"); + namespace cmds { #include "../common/gles2_cmd_format_autogen.h"
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 3f288cb3..7dea6b5 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -13468,6 +13468,124 @@ static_assert(offsetof(WaitSyncPointCHROMIUM, sync_point) == 4, "offset of WaitSyncPointCHROMIUM sync_point should be 4"); +struct InsertFenceSyncCHROMIUM { + typedef InsertFenceSyncCHROMIUM ValueType; + static const CommandId kCmdId = kInsertFenceSyncCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint64 _release_count) { + SetHeader(); + release_count = _release_count; + } + + void* Set(void* cmd, GLuint64 _release_count) { + static_cast<ValueType*>(cmd)->Init(_release_count); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t release_count; +}; + +static_assert(sizeof(InsertFenceSyncCHROMIUM) == 8, + "size of InsertFenceSyncCHROMIUM should be 8"); +static_assert(offsetof(InsertFenceSyncCHROMIUM, header) == 0, + "offset of InsertFenceSyncCHROMIUM header should be 0"); +static_assert(offsetof(InsertFenceSyncCHROMIUM, release_count) == 4, + "offset of InsertFenceSyncCHROMIUM release_count should be 4"); + +struct GenSyncTokenCHROMIUMImmediate { + typedef GenSyncTokenCHROMIUMImmediate ValueType; + static const CommandId kCmdId = kGenSyncTokenCHROMIUMImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize(uint32_t size_in_bytes) { + return static_cast<uint32_t>(sizeof(ValueType) + // NOLINT + RoundSizeToMultipleOfEntries(size_in_bytes)); + } + + void SetHeader(uint32_t size_in_bytes) { + header.SetCmdByTotalSize<ValueType>(size_in_bytes); + } + + void Init(GLuint64 _fence_sync) { + uint32_t total_size = 0; // TODO(gman): get correct size. + SetHeader(total_size); + fence_sync = _fence_sync; + } + + void* Set(void* cmd, GLuint64 _fence_sync) { + uint32_t total_size = 0; // TODO(gman): get correct size. + static_cast<ValueType*>(cmd)->Init(_fence_sync); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); + } + + gpu::CommandHeader header; + uint32_t fence_sync; +}; + +static_assert(sizeof(GenSyncTokenCHROMIUMImmediate) == 8, + "size of GenSyncTokenCHROMIUMImmediate should be 8"); +static_assert(offsetof(GenSyncTokenCHROMIUMImmediate, header) == 0, + "offset of GenSyncTokenCHROMIUMImmediate header should be 0"); +static_assert(offsetof(GenSyncTokenCHROMIUMImmediate, fence_sync) == 4, + "offset of GenSyncTokenCHROMIUMImmediate fence_sync should be 4"); + +struct WaitSyncTokenCHROMIUM { + typedef WaitSyncTokenCHROMIUM ValueType; + static const CommandId kCmdId = kWaitSyncTokenCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _namespace_id, + GLuint64 _command_buffer_id, + GLuint64 _release_count) { + SetHeader(); + namespace_id = _namespace_id; + command_buffer_id = _command_buffer_id; + release_count = _release_count; + } + + void* Set(void* cmd, + GLuint _namespace_id, + GLuint64 _command_buffer_id, + GLuint64 _release_count) { + static_cast<ValueType*>(cmd) + ->Init(_namespace_id, _command_buffer_id, _release_count); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t namespace_id; + uint32_t command_buffer_id; + uint32_t release_count; +}; + +static_assert(sizeof(WaitSyncTokenCHROMIUM) == 16, + "size of WaitSyncTokenCHROMIUM should be 16"); +static_assert(offsetof(WaitSyncTokenCHROMIUM, header) == 0, + "offset of WaitSyncTokenCHROMIUM header should be 0"); +static_assert(offsetof(WaitSyncTokenCHROMIUM, namespace_id) == 4, + "offset of WaitSyncTokenCHROMIUM namespace_id should be 4"); +static_assert(offsetof(WaitSyncTokenCHROMIUM, command_buffer_id) == 8, + "offset of WaitSyncTokenCHROMIUM command_buffer_id should be 8"); +static_assert(offsetof(WaitSyncTokenCHROMIUM, release_count) == 12, + "offset of WaitSyncTokenCHROMIUM release_count should be 12"); + struct DrawBuffersEXTImmediate { typedef DrawBuffersEXTImmediate ValueType; static const CommandId kCmdId = kDrawBuffersEXTImmediate;
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index 62bff78..e1321cf 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -4768,6 +4768,32 @@ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, InsertFenceSyncCHROMIUM) { + cmds::InsertFenceSyncCHROMIUM& cmd = + *GetBufferAs<cmds::InsertFenceSyncCHROMIUM>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint64>(11)); + EXPECT_EQ(static_cast<uint32_t>(cmds::InsertFenceSyncCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint64>(11), cmd.release_count); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, WaitSyncTokenCHROMIUM) { + cmds::WaitSyncTokenCHROMIUM& cmd = + *GetBufferAs<cmds::WaitSyncTokenCHROMIUM>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint64>(12), + static_cast<GLuint64>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::WaitSyncTokenCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.namespace_id); + EXPECT_EQ(static_cast<GLuint64>(12), cmd.command_buffer_id); + EXPECT_EQ(static_cast<GLuint64>(13), cmd.release_count); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, DrawBuffersEXTImmediate) { const int kSomeBaseValueToTestWith = 51; static GLenum data[] = {
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 89514409..39e1705 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -296,28 +296,31 @@ OP(LoseContextCHROMIUM) /* 537 */ \ OP(InsertSyncPointCHROMIUM) /* 538 */ \ OP(WaitSyncPointCHROMIUM) /* 539 */ \ - OP(DrawBuffersEXTImmediate) /* 540 */ \ - OP(DiscardBackbufferCHROMIUM) /* 541 */ \ - OP(ScheduleOverlayPlaneCHROMIUM) /* 542 */ \ - OP(SwapInterval) /* 543 */ \ - OP(FlushDriverCachesCHROMIUM) /* 544 */ \ - OP(MatrixLoadfCHROMIUMImmediate) /* 545 */ \ - OP(MatrixLoadIdentityCHROMIUM) /* 546 */ \ - OP(GenPathsCHROMIUM) /* 547 */ \ - OP(DeletePathsCHROMIUM) /* 548 */ \ - OP(IsPathCHROMIUM) /* 549 */ \ - OP(PathCommandsCHROMIUM) /* 550 */ \ - OP(PathParameterfCHROMIUM) /* 551 */ \ - OP(PathParameteriCHROMIUM) /* 552 */ \ - OP(PathStencilFuncCHROMIUM) /* 553 */ \ - OP(StencilFillPathCHROMIUM) /* 554 */ \ - OP(StencilStrokePathCHROMIUM) /* 555 */ \ - OP(CoverFillPathCHROMIUM) /* 556 */ \ - OP(CoverStrokePathCHROMIUM) /* 557 */ \ - OP(StencilThenCoverFillPathCHROMIUM) /* 558 */ \ - OP(StencilThenCoverStrokePathCHROMIUM) /* 559 */ \ - OP(BlendBarrierKHR) /* 560 */ \ - OP(ApplyScreenSpaceAntialiasingCHROMIUM) /* 561 */ + OP(InsertFenceSyncCHROMIUM) /* 540 */ \ + OP(GenSyncTokenCHROMIUMImmediate) /* 541 */ \ + OP(WaitSyncTokenCHROMIUM) /* 542 */ \ + OP(DrawBuffersEXTImmediate) /* 543 */ \ + OP(DiscardBackbufferCHROMIUM) /* 544 */ \ + OP(ScheduleOverlayPlaneCHROMIUM) /* 545 */ \ + OP(SwapInterval) /* 546 */ \ + OP(FlushDriverCachesCHROMIUM) /* 547 */ \ + OP(MatrixLoadfCHROMIUMImmediate) /* 548 */ \ + OP(MatrixLoadIdentityCHROMIUM) /* 549 */ \ + OP(GenPathsCHROMIUM) /* 550 */ \ + OP(DeletePathsCHROMIUM) /* 551 */ \ + OP(IsPathCHROMIUM) /* 552 */ \ + OP(PathCommandsCHROMIUM) /* 553 */ \ + OP(PathParameterfCHROMIUM) /* 554 */ \ + OP(PathParameteriCHROMIUM) /* 555 */ \ + OP(PathStencilFuncCHROMIUM) /* 556 */ \ + OP(StencilFillPathCHROMIUM) /* 557 */ \ + OP(StencilStrokePathCHROMIUM) /* 558 */ \ + OP(CoverFillPathCHROMIUM) /* 559 */ \ + OP(CoverStrokePathCHROMIUM) /* 560 */ \ + OP(StencilThenCoverFillPathCHROMIUM) /* 561 */ \ + OP(StencilThenCoverStrokePathCHROMIUM) /* 562 */ \ + OP(BlendBarrierKHR) /* 563 */ \ + OP(ApplyScreenSpaceAntialiasingCHROMIUM) /* 564 */ enum CommandId { kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this.
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index 99f7837..af2b10e 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -1900,6 +1900,9 @@ 0x8CD9, "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS", }, { + 24, "GL_SYNC_TOKEN_SIZE_CHROMIUM", + }, + { 0x84CC, "GL_TEXTURE12", }, {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index fc12bfe..a76f7938 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -688,6 +688,9 @@ void SetShaderCacheCallback(const ShaderCacheCallback& callback) override; void SetWaitSyncPointCallback(const WaitSyncPointCallback& callback) override; + void SetFenceSyncReleaseCallback( + const FenceSyncReleaseCallback& callback) override; + void SetWaitFenceSyncCallback(const WaitFenceSyncCallback& callback) override; void SetIgnoreCachedStateForTest(bool ignore) override; void ProcessFinishedAsyncTransfers(); @@ -1989,6 +1992,8 @@ base::Callback<void(gfx::Size, float)> resize_callback_; WaitSyncPointCallback wait_sync_point_callback_; + FenceSyncReleaseCallback fence_sync_release_callback_; + WaitFenceSyncCallback wait_fence_sync_callback_; ShaderCacheCallback shader_cache_callback_; @@ -3948,6 +3953,16 @@ wait_sync_point_callback_ = callback; } +void GLES2DecoderImpl::SetFenceSyncReleaseCallback( + const FenceSyncReleaseCallback& callback) { + fence_sync_release_callback_ = callback; +} + +void GLES2DecoderImpl::SetWaitFenceSyncCallback( + const WaitFenceSyncCallback& callback) { + wait_fence_sync_callback_ = callback; +} + bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, uint32* service_texture_id) { TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id); @@ -7886,12 +7901,9 @@ const void* cmd_data) { const gles2::cmds::DrawArraysInstancedANGLE& c = *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data); - if (!features().angle_instanced_arrays) { - LOCAL_SET_GL_ERROR( - GL_INVALID_OPERATION, - "glDrawArraysInstancedANGLE", "function not available"); - return error::kNoError; - } + if (!features().angle_instanced_arrays) + return error::kUnknownCommand; + return DoDrawArrays("glDrawArraysIntancedANGLE", true, static_cast<GLenum>(c.mode), @@ -8034,12 +8046,9 @@ const void* cmd_data) { const gles2::cmds::DrawElementsInstancedANGLE& c = *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data); - if (!features().angle_instanced_arrays) { - LOCAL_SET_GL_ERROR( - GL_INVALID_OPERATION, - "glDrawElementsInstancedANGLE", "function not available"); - return error::kNoError; - } + if (!features().angle_instanced_arrays) + return error::kUnknownCommand; + return DoDrawElements("glDrawElementsInstancedANGLE", true, static_cast<GLenum>(c.mode), @@ -8732,12 +8741,9 @@ const void* cmd_data) { const gles2::cmds::VertexAttribDivisorANGLE& c = *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data); - if (!features().angle_instanced_arrays) { - LOCAL_SET_GL_ERROR( - GL_INVALID_OPERATION, - "glVertexAttribDivisorANGLE", "function not available"); - return error::kNoError; - } + if (!features().angle_instanced_arrays) + return error::kUnknownCommand; + GLuint index = c.index; GLuint divisor = c.divisor; if (index >= group_->max_vertex_attribs()) { @@ -9271,10 +9277,9 @@ if (!location) { return error::kOutOfBounds; } - // Require the client to init this incase the context is lost and we are no - // longer executing commands. + // Check that the client initialized the result. if (*location != -1) { - return error::kGenericError; + return error::kInvalidArguments; } *location = program->GetAttribLocation(name_str); return error::kNoError; @@ -9320,10 +9325,9 @@ if (!location) { return error::kOutOfBounds; } - // Require the client to init this incase the context is lost an we are no - // longer executing commands. + // Check that the client initialized the result. if (*location != -1) { - return error::kGenericError; + return error::kInvalidArguments; } *location = program->GetUniformFakeLocation(name_str); return error::kNoError; @@ -9406,10 +9410,9 @@ if (!location) { return error::kOutOfBounds; } - // Require the client to init this incase the context is lost and we are no - // longer executing commands. + // Check that the client initialized the result. if (*location != -1) { - return error::kGenericError; + return error::kInvalidArguments; } Program* program = GetProgramInfoNotShader( client_id, "glGetFragDataLocation"); @@ -9458,10 +9461,9 @@ if (!index) { return error::kOutOfBounds; } - // Require the client to init this in case the context is lost and we are no - // longer executing commands. + // Check that the client initialized the result. if (*index != GL_INVALID_INDEX) { - return error::kGenericError; + return error::kInvalidArguments; } Program* program = GetProgramInfoNotShader( c.program, "glGetUniformBlockIndex"); @@ -12242,6 +12244,42 @@ error::kNoError : error::kDeferCommandUntilLater; } +error::Error GLES2DecoderImpl::HandleInsertFenceSyncCHROMIUM( + uint32 immediate_data_size, + const void* cmd_data) { + const gles2::cmds::InsertFenceSyncCHROMIUM& c = + *static_cast<const gles2::cmds::InsertFenceSyncCHROMIUM*>(cmd_data); + + const uint64_t release_count = c.release_count; + if (!fence_sync_release_callback_.is_null()) + fence_sync_release_callback_.Run(release_count); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleGenSyncTokenCHROMIUMImmediate( + uint32 immediate_data_size, + const void* cmd_data) { + return error::kUnknownCommand; +} + +error::Error GLES2DecoderImpl::HandleWaitSyncTokenCHROMIUM( + uint32 immediate_data_size, + const void* cmd_data) { + const gles2::cmds::WaitSyncTokenCHROMIUM& c = + *static_cast<const gles2::cmds::WaitSyncTokenCHROMIUM*>(cmd_data); + + const gpu::CommandBufferNamespace namespace_id = + static_cast<gpu::CommandBufferNamespace>(c.namespace_id); + const uint64_t command_buffer_id = c.command_buffer_id; + const uint64_t release = c.release_count; + if (wait_fence_sync_callback_.is_null()) + return error::kNoError; + + return wait_fence_sync_callback_.Run(namespace_id, command_buffer_id, release) + ? error::kNoError + : error::kDeferCommandUntilLater; +} + error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM( uint32 immediate_data_size, const void* cmd_data) { @@ -14610,11 +14648,8 @@ static const char kFunctionName[] = "glGenPathsCHROMIUM"; const gles2::cmds::GenPathsCHROMIUM& c = *static_cast<const gles2::cmds::GenPathsCHROMIUM*>(cmd_data); - if (!features().chromium_path_rendering) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, - "function not available"); - return error::kNoError; - } + if (!features().chromium_path_rendering) + return error::kUnknownCommand; GLsizei range = static_cast<GLsizei>(c.range); if (range < 0) { @@ -14640,11 +14675,8 @@ static const char kFunctionName[] = "glDeletePathsCHROMIUM"; const gles2::cmds::DeletePathsCHROMIUM& c = *static_cast<const gles2::cmds::DeletePathsCHROMIUM*>(cmd_data); - if (!features().chromium_path_rendering) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, - "function not available"); - return error::kNoError; - } + if (!features().chromium_path_rendering) + return error::kUnknownCommand; GLsizei range = static_cast<GLsizei>(c.range); if (range < 0) { @@ -14670,11 +14702,8 @@ static const char kFunctionName[] = "glPathCommandsCHROMIUM"; const gles2::cmds::PathCommandsCHROMIUM& c = *static_cast<const gles2::cmds::PathCommandsCHROMIUM*>(cmd_data); - if (!features().chromium_path_rendering) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, - "function not available"); - return error::kNoError; - } + if (!features().chromium_path_rendering) + return error::kUnknownCommand; GLuint service_id = 0; if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { @@ -14778,11 +14807,9 @@ static const char kFunctionName[] = "glPathParameterfCHROMIUM"; const gles2::cmds::PathParameterfCHROMIUM& c = *static_cast<const gles2::cmds::PathParameterfCHROMIUM*>(cmd_data); - if (!features().chromium_path_rendering) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, - "function not available"); - return error::kNoError; - } + if (!features().chromium_path_rendering) + return error::kUnknownCommand; + GLuint service_id = 0; if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, @@ -14832,11 +14859,9 @@ static const char kFunctionName[] = "glPathParameteriCHROMIUM"; const gles2::cmds::PathParameteriCHROMIUM& c = *static_cast<const gles2::cmds::PathParameteriCHROMIUM*>(cmd_data); - if (!features().chromium_path_rendering) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, - "function not available"); - return error::kNoError; - } + if (!features().chromium_path_rendering) + return error::kUnknownCommand; + GLuint service_id = 0; if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, @@ -14884,11 +14909,9 @@ static const char kFunctionName[] = "glStencilFillPathCHROMIUM"; const gles2::cmds::StencilFillPathCHROMIUM& c = *static_cast<const gles2::cmds::StencilFillPathCHROMIUM*>(cmd_data); - if (!features().chromium_path_rendering) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, - "function not available"); - return error::kNoError; - } + if (!features().chromium_path_rendering) + return error::kUnknownCommand; + GLenum fill_mode = static_cast<GLenum>(c.fillMode); if (!validators_->path_fill_mode.IsValid(fill_mode)) { LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, fill_mode, "fillMode"); @@ -14917,14 +14940,11 @@ error::Error GLES2DecoderImpl::HandleStencilStrokePathCHROMIUM( uint32 immediate_data_size, const void* cmd_data) { - static const char kFunctionName[] = "glStencilStrokePathCHROMIUM"; const gles2::cmds::StencilStrokePathCHROMIUM& c = *static_cast<const gles2::cmds::StencilStrokePathCHROMIUM*>(cmd_data); - if (!features().chromium_path_rendering) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, - "function not available"); - return error::kNoError; - } + if (!features().chromium_path_rendering) + return error::kUnknownCommand; + GLuint service_id = 0; if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { return error::kNoError; @@ -14942,11 +14962,9 @@ static const char kFunctionName[] = "glCoverFillPathCHROMIUM"; const gles2::cmds::CoverFillPathCHROMIUM& c = *static_cast<const gles2::cmds::CoverFillPathCHROMIUM*>(cmd_data); - if (!features().chromium_path_rendering) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, - "function not available"); - return error::kNoError; - } + if (!features().chromium_path_rendering) + return error::kUnknownCommand; + GLenum cover_mode = static_cast<GLenum>(c.coverMode); if (!validators_->path_cover_mode.IsValid(cover_mode)) { LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, cover_mode, "coverMode"); @@ -14967,11 +14985,9 @@ static const char kFunctionName[] = "glCoverStrokePathCHROMIUM"; const gles2::cmds::CoverStrokePathCHROMIUM& c = *static_cast<const gles2::cmds::CoverStrokePathCHROMIUM*>(cmd_data); - if (!features().chromium_path_rendering) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, - "function not available"); - return error::kNoError; - } + if (!features().chromium_path_rendering) + return error::kUnknownCommand; + GLenum cover_mode = static_cast<GLenum>(c.coverMode); if (!validators_->path_cover_mode.IsValid(cover_mode)) { LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, cover_mode, "coverMode"); @@ -14993,11 +15009,9 @@ const gles2::cmds::StencilThenCoverFillPathCHROMIUM& c = *static_cast<const gles2::cmds::StencilThenCoverFillPathCHROMIUM*>( cmd_data); - if (!features().chromium_path_rendering) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, - "function not available"); - return error::kNoError; - } + if (!features().chromium_path_rendering) + return error::kUnknownCommand; + GLenum fill_mode = static_cast<GLenum>(c.fillMode); if (!validators_->path_fill_mode.IsValid(fill_mode)) { LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, fill_mode, "fillMode"); @@ -15032,11 +15046,9 @@ const gles2::cmds::StencilThenCoverStrokePathCHROMIUM& c = *static_cast<const gles2::cmds::StencilThenCoverStrokePathCHROMIUM*>( cmd_data); - if (!features().chromium_path_rendering) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, - "function not available"); - return error::kNoError; - } + if (!features().chromium_path_rendering) + return error::kUnknownCommand; + GLenum cover_mode = static_cast<GLenum>(c.coverMode); if (!validators_->path_cover_mode.IsValid(cover_mode)) { LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, cover_mode, "coverMode");
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h index 0fb4882..60ca384 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -65,6 +65,10 @@ public: typedef error::Error Error; typedef base::Callback<bool(uint32 id)> WaitSyncPointCallback; + typedef base::Callback<void(uint64_t release)> FenceSyncReleaseCallback; + typedef base::Callback<bool(gpu::CommandBufferNamespace namespace_id, + uint64_t command_buffer_id, + uint64_t release)> WaitFenceSyncCallback; // The default stencil mask, which has all bits set. This really should be a // GLuint, but we can't #include gl_bindings.h in this file without causing @@ -234,6 +238,13 @@ virtual void SetWaitSyncPointCallback( const WaitSyncPointCallback& callback) = 0; + // Sets the callback for fence sync release and wait calls. The wait call + // returns true if the channel is still scheduled. + virtual void SetFenceSyncReleaseCallback( + const FenceSyncReleaseCallback& callback) = 0; + virtual void SetWaitFenceSyncCallback( + const WaitFenceSyncCallback& callback) = 0; + virtual void WaitForReadPixels(base::Closure callback) = 0; virtual uint32 GetTextureUploadCount() = 0; virtual base::TimeDelta GetTotalTextureUploadTime() = 0;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 303b7021..de3b3443 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -3984,9 +3984,7 @@ *static_cast<const gles2::cmds::BlitFramebufferCHROMIUM*>(cmd_data); (void)c; if (!features().chromium_framebuffer_multisample) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBlitFramebufferCHROMIUM", - "function not available"); - return error::kNoError; + return error::kUnknownCommand; } error::Error error; @@ -4024,10 +4022,7 @@ cmd_data); (void)c; if (!features().chromium_framebuffer_multisample) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, - "glRenderbufferStorageMultisampleCHROMIUM", - "function not available"); - return error::kNoError; + return error::kUnknownCommand; } GLenum target = static_cast<GLenum>(c.target); @@ -4075,10 +4070,7 @@ cmd_data); (void)c; if (!features().multisampled_render_to_texture) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, - "glRenderbufferStorageMultisampleEXT", - "function not available"); - return error::kNoError; + return error::kUnknownCommand; } GLenum target = static_cast<GLenum>(c.target); @@ -4124,10 +4116,7 @@ cmd_data); (void)c; if (!features().multisampled_render_to_texture) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, - "glFramebufferTexture2DMultisampleEXT", - "function not available"); - return error::kNoError; + return error::kUnknownCommand; } GLenum target = static_cast<GLenum>(c.target); @@ -4846,9 +4835,7 @@ cmd_data); (void)c; if (!features().ext_discard_framebuffer) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glDiscardFramebufferEXT", - "function not available"); - return error::kNoError; + return error::kUnknownCommand; } GLenum target = static_cast<GLenum>(c.target); @@ -4949,9 +4936,7 @@ *static_cast<const gles2::cmds::MatrixLoadfCHROMIUMImmediate*>(cmd_data); (void)c; if (!features().chromium_path_rendering) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glMatrixLoadfCHROMIUM", - "function not available"); - return error::kNoError; + return error::kUnknownCommand; } GLenum matrixMode = static_cast<GLenum>(c.matrixMode); @@ -4983,9 +4968,7 @@ *static_cast<const gles2::cmds::MatrixLoadIdentityCHROMIUM*>(cmd_data); (void)c; if (!features().chromium_path_rendering) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glMatrixLoadIdentityCHROMIUM", - "function not available"); - return error::kNoError; + return error::kUnknownCommand; } GLenum matrixMode = static_cast<GLenum>(c.matrixMode); @@ -5005,9 +4988,7 @@ *static_cast<const gles2::cmds::IsPathCHROMIUM*>(cmd_data); (void)c; if (!features().chromium_path_rendering) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glIsPathCHROMIUM", - "function not available"); - return error::kNoError; + return error::kUnknownCommand; } GLuint path = c.path; @@ -5028,9 +5009,7 @@ *static_cast<const gles2::cmds::PathStencilFuncCHROMIUM*>(cmd_data); (void)c; if (!features().chromium_path_rendering) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glPathStencilFuncCHROMIUM", - "function not available"); - return error::kNoError; + return error::kUnknownCommand; } GLenum func = static_cast<GLenum>(c.func); @@ -5057,9 +5036,7 @@ *static_cast<const gles2::cmds::BlendBarrierKHR*>(cmd_data); (void)c; if (!features().blend_equation_advanced) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBlendBarrierKHR", - "function not available"); - return error::kNoError; + return error::kUnknownCommand; } glBlendBarrierKHR(); @@ -5074,10 +5051,7 @@ cmd_data); (void)c; if (!features().chromium_screen_space_antialiasing) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, - "glApplyScreenSpaceAntialiasingCHROMIUM", - "function not available"); - return error::kNoError; + return error::kUnknownCommand; } DoApplyScreenSpaceAntialiasingCHROMIUM();
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h index 62e1c9d4..590c27a5f 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
@@ -115,6 +115,10 @@ void(const ShaderCacheCallback& callback)); MOCK_METHOD1(SetWaitSyncPointCallback, void(const WaitSyncPointCallback& callback)); + MOCK_METHOD1(SetFenceSyncReleaseCallback, + void(const FenceSyncReleaseCallback& callback)); + MOCK_METHOD1(SetWaitFenceSyncCallback, + void(const WaitFenceSyncCallback& callback)); MOCK_METHOD1(WaitForReadPixels, void(base::Closure callback)); MOCK_METHOD0(GetTextureUploadCount, uint32());
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h index 4c7afcc..691c9dcc 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
@@ -461,6 +461,12 @@ // TODO(gman): WaitSyncPointCHROMIUM +// TODO(gman): InsertFenceSyncCHROMIUM + +// TODO(gman): GenSyncTokenCHROMIUMImmediate + +// TODO(gman): WaitSyncTokenCHROMIUM + // TODO(gman): DrawBuffersEXTImmediate // TODO(gman): DiscardBackbufferCHROMIUM
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc index b2147cc..fefc36b 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc
@@ -938,8 +938,7 @@ .RetiresOnSaturation(); DrawArraysInstancedANGLE cmd; cmd.Init(GL_TRIANGLES, 0, kNumVertices, 1); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } TEST_P(GLES2DecoderWithShaderTest, VertexAttribDivisorANGLEFails) { @@ -954,8 +953,7 @@ VertexAttribDivisorANGLE cmd; cmd.Init(0, 1); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } TEST_P(GLES2DecoderGeometryInstancingTest, @@ -1428,8 +1426,7 @@ GL_UNSIGNED_SHORT, kValidIndexRangeStart * 2, 1); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } TEST_P(GLES2DecoderGeometryInstancingTest,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc index 916f2aa..dbb9100f 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc
@@ -39,92 +39,77 @@ 0, }; cmd.Init(GL_PATH_MODELVIEW_CHROMIUM, temp); - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp))); } { cmds::MatrixLoadIdentityCHROMIUM cmd; cmd.Init(GL_PATH_PROJECTION_CHROMIUM); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } { cmds::GenPathsCHROMIUM cmd; cmd.Init(0, 0); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } { cmds::DeletePathsCHROMIUM cmd; cmd.Init(0, 0); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } { cmds::IsPathCHROMIUM cmd; cmd.Init(kClientPathId, shared_memory_id_, shared_memory_offset_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } { cmds::PathCommandsCHROMIUM cmd; cmd.Init(kClientPathId, 0, 0, 0, 0, GL_FLOAT, 0, 0); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } { cmds::PathParameterfCHROMIUM cmd; cmd.Init(kClientPathId, GL_PATH_STROKE_WIDTH_CHROMIUM, 1.0f); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } { cmds::PathParameteriCHROMIUM cmd; cmd.Init(kClientPathId, GL_PATH_STROKE_WIDTH_CHROMIUM, 1); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } { cmds::PathStencilFuncCHROMIUM cmd; cmd.Init(GL_NEVER, 2, 3); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } { cmds::StencilFillPathCHROMIUM cmd; cmd.Init(kClientPathId, GL_COUNT_UP_CHROMIUM, 1); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } { cmds::StencilStrokePathCHROMIUM cmd; cmd.Init(kClientPathId, 1, 2); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } { cmds::CoverFillPathCHROMIUM cmd; cmd.Init(kClientPathId, GL_BOUNDING_BOX_CHROMIUM); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } { cmds::CoverStrokePathCHROMIUM cmd; cmd.Init(kClientPathId, GL_BOUNDING_BOX_CHROMIUM); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } { cmds::StencilThenCoverFillPathCHROMIUM cmd; cmd.Init(kClientPathId, GL_COUNT_UP_CHROMIUM, 1, GL_BOUNDING_BOX_CHROMIUM); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } { cmds::StencilThenCoverStrokePathCHROMIUM cmd; cmd.Init(kClientPathId, 1, 2, GL_BOUNDING_BOX_CHROMIUM); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc index 7e086fd..5c256709 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc
@@ -1604,8 +1604,7 @@ GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } class GLES2DecoderMultisampledRenderToTextureTest @@ -1620,8 +1619,7 @@ GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); } void TestRenderbufferStorageMultisampleEXT(const char* extension, @@ -2271,8 +2269,8 @@ cmd.Init(target, count, attachments); // Should not result into a call into GL. - EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(attachments))); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(error::kUnknownCommand, + ExecuteImmediateCmd(cmd, sizeof(attachments))); } TEST_P(GLES2DecoderManualInitTest,
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc index 19e36161..13fc8ad 100644 --- a/gpu/command_buffer/service/in_process_command_buffer.cc +++ b/gpu/command_buffer/service/in_process_command_buffer.cc
@@ -19,6 +19,7 @@ #include "base/single_thread_task_runner.h" #include "base/thread_task_runner_handle.h" #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" +#include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/value_state.h" #include "gpu/command_buffer/service/command_buffer_service.h" #include "gpu/command_buffer/service/context_group.h" @@ -182,8 +183,11 @@ image_factory_(nullptr), last_put_offset_(-1), gpu_memory_buffer_manager_(nullptr), + next_fence_sync_release_(1), + flushed_fence_sync_release_(0), flush_event_(false, false), service_(GetInitialService(service)), + fence_sync_wait_event_(false, false), gpu_thread_weak_ptr_factory_(this) { DCHECK(service_.get()); next_image_id_.GetNext(); @@ -344,10 +348,9 @@ return false; } - sync_point_client_state_ = SyncPointClientState::Create(); + sync_point_order_data_ = SyncPointOrderData::Create(); sync_point_client_ = service_->sync_point_manager()->CreateSyncPointClient( - sync_point_client_state_, - GetNamespaceID(), GetCommandBufferID()); + sync_point_order_data_, GetNamespaceID(), GetCommandBufferID()); if (service_->UseVirtualizedGLContexts() || decoder_->GetContextGroup() @@ -414,6 +417,12 @@ decoder_->SetWaitSyncPointCallback( base::Bind(&InProcessCommandBuffer::WaitSyncPointOnGpuThread, base::Unretained(this))); + decoder_->SetFenceSyncReleaseCallback( + base::Bind(&InProcessCommandBuffer::FenceSyncReleaseOnGpuThread, + base::Unretained(this))); + decoder_->SetWaitFenceSyncCallback( + base::Bind(&InProcessCommandBuffer::WaitFenceSyncOnGpuThread, + base::Unretained(this))); image_factory_ = params.image_factory; @@ -445,7 +454,10 @@ context_ = NULL; surface_ = NULL; sync_point_client_ = NULL; - sync_point_client_state_ = NULL; + if (sync_point_order_data_) { + sync_point_order_data_->Destroy(); + sync_point_order_data_ = nullptr; + } gl_share_group_ = NULL; #if defined(OS_ANDROID) stream_texture_manager_.reset(); @@ -494,7 +506,7 @@ ScopedEvent handle_flush(&flush_event_); base::AutoLock lock(command_buffer_lock_); - sync_point_client_state_->BeginProcessingOrderNumber(order_num); + sync_point_order_data_->BeginProcessingOrderNumber(order_num); command_buffer_->Flush(put_offset); { // Update state before signaling the flush event. @@ -509,7 +521,7 @@ // order number function until the message is rescheduled and finished // processing. This DCHECK is to enforce this. DCHECK(context_lost_ || put_offset == state_after_last_flush_.get_offset); - sync_point_client_state_->FinishProcessingOrderNumber(order_num); + sync_point_order_data_->FinishProcessingOrderNumber(order_num); // If we've processed all pending commands but still have pending queries, // pump idle work until the query is passed. @@ -553,13 +565,15 @@ SyncPointManager* sync_manager = service_->sync_point_manager(); const uint32_t order_num = - sync_point_client_state_->GenerateUnprocessedOrderNumber(sync_manager); + sync_point_order_data_->GenerateUnprocessedOrderNumber(sync_manager); last_put_offset_ = put_offset; base::Closure task = base::Bind(&InProcessCommandBuffer::FlushOnGpuThread, gpu_thread_weak_ptr_, put_offset, order_num); QueueTask(task); + + flushed_fence_sync_release_ = next_fence_sync_release_ - 1; } void InProcessCommandBuffer::OrderingBarrier(int32 put_offset) { @@ -798,8 +812,15 @@ base::AutoLock lock(command_buffer_lock_); make_current_success = MakeCurrent(); } - if (make_current_success) - mailbox_manager->PushTextureUpdates(sync_point); + if (make_current_success) { + // Old sync points are global and do not have a command buffer ID, + // We can simply use the GPUIO namespace with 0 for the command buffer ID + // (under normal circumstances 0 is invalid so will not be used) until + // the old sync points are replaced. + gles2::SyncToken sync_token = {gpu::CommandBufferNamespace::GPU_IO, 0, + sync_point}; + mailbox_manager->PushTextureUpdates(sync_token); + } } service_->sync_point_manager()->RetireSyncPoint(sync_point); } @@ -817,7 +838,63 @@ service_->sync_point_manager()->WaitSyncPoint(sync_point); gles2::MailboxManager* mailbox_manager = decoder_->GetContextGroup()->mailbox_manager(); - mailbox_manager->PullTextureUpdates(sync_point); + // Old sync points are global and do not have a command buffer ID, + // We can simply use the GPUIO namespace with 0 for the command buffer ID + // (under normal circumstances 0 is invalid so will not be used) until + // the old sync points are replaced. + gles2::SyncToken sync_token = {gpu::CommandBufferNamespace::GPU_IO, 0, + sync_point}; + mailbox_manager->PullTextureUpdates(sync_token); + return true; +} + +void InProcessCommandBuffer::FenceSyncReleaseOnGpuThread(uint64_t release) { + DCHECK(!sync_point_client_->client_state()->IsFenceSyncReleased(release)); + gles2::MailboxManager* mailbox_manager = + decoder_->GetContextGroup()->mailbox_manager(); + if (mailbox_manager->UsesSync()) { + bool make_current_success = false; + { + base::AutoLock lock(command_buffer_lock_); + make_current_success = MakeCurrent(); + } + if (make_current_success) { + gles2::SyncToken sync_token = {GetNamespaceID(), GetCommandBufferID(), + release}; + mailbox_manager->PushTextureUpdates(sync_token); + } + } + + sync_point_client_->ReleaseFenceSync(release); +} + +bool InProcessCommandBuffer::WaitFenceSyncOnGpuThread( + gpu::CommandBufferNamespace namespace_id, + uint64_t command_buffer_id, + uint64_t release) { + gpu::SyncPointManager* sync_point_manager = service_->sync_point_manager(); + DCHECK(sync_point_manager); + + scoped_refptr<gpu::SyncPointClientState> release_state = + sync_point_manager->GetSyncPointClientState(namespace_id, + command_buffer_id); + + if (!release_state) + return true; + + if (!release_state->IsFenceSyncReleased(release)) { + // Use waitable event which is signalled when the release fence is released. + sync_point_client_->Wait( + release_state.get(), release, + base::Bind(&base::WaitableEvent::Signal, + base::Unretained(&fence_sync_wait_event_))); + fence_sync_wait_event_.Wait(); + } + + gles2::MailboxManager* mailbox_manager = + decoder_->GetContextGroup()->mailbox_manager(); + gles2::SyncToken sync_token = {namespace_id, command_buffer_id, release}; + mailbox_manager->PullTextureUpdates(sync_token); return true; } @@ -881,6 +958,18 @@ return command_buffer_id_; } +uint64_t InProcessCommandBuffer::GenerateFenceSyncRelease() { + return next_fence_sync_release_++; +} + +bool InProcessCommandBuffer::IsFenceSyncRelease(uint64_t release) { + return release != 0 && release < next_fence_sync_release_; +} + +bool InProcessCommandBuffer::IsFenceSyncFlushed(uint64_t release) { + return release <= flushed_fence_sync_release_; +} + uint32 InProcessCommandBuffer::CreateStreamTextureOnGpuThread( uint32 client_texture_id) { #if defined(OS_ANDROID)
diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h index f4f91f81..7843aa3a 100644 --- a/gpu/command_buffer/service/in_process_command_buffer.h +++ b/gpu/command_buffer/service/in_process_command_buffer.h
@@ -48,7 +48,7 @@ namespace gpu { class SyncPointClient; -class SyncPointClientState; +class SyncPointOrderData; class SyncPointManager; class ValueStateMap; @@ -130,6 +130,9 @@ bool IsGpuChannelLost() override; CommandBufferNamespace GetNamespaceID() const override; uint64_t GetCommandBufferID() const override; + uint64_t GenerateFenceSyncRelease() override; + bool IsFenceSyncRelease(uint64_t release) override; + bool IsFenceSyncFlushed(uint64_t release) override; // The serializer interface to the GPU service (i.e. thread). class Service { @@ -215,6 +218,10 @@ void SignalSyncPointOnGpuThread(uint32 sync_point, const base::Closure& callback); bool WaitSyncPointOnGpuThread(uint32 sync_point); + void FenceSyncReleaseOnGpuThread(uint64_t release); + bool WaitFenceSyncOnGpuThread(gpu::CommandBufferNamespace namespace_id, + uint64_t command_buffer_id, + uint64_t release); void SignalQueryOnGpuThread(unsigned query_id, const base::Closure& callback); void DestroyTransferBufferOnGpuThread(int32 id); void CreateImageOnGpuThread(int32 id, @@ -242,7 +249,7 @@ scoped_ptr<gles2::GLES2Decoder> decoder_; scoped_refptr<gfx::GLContext> context_; scoped_refptr<gfx::GLSurface> surface_; - scoped_refptr<SyncPointClientState> sync_point_client_state_; + scoped_refptr<SyncPointOrderData> sync_point_order_data_; scoped_ptr<SyncPointClient> sync_point_client_; base::Closure context_lost_callback_; bool delayed_work_pending_; // Used to throttle PerformDelayedWork. @@ -254,6 +261,8 @@ gpu::Capabilities capabilities_; GpuMemoryBufferManager* gpu_memory_buffer_manager_; base::AtomicSequenceNumber next_image_id_; + uint64_t next_fence_sync_release_; + uint64_t flushed_fence_sync_release_; // Accessed on both threads: scoped_ptr<CommandBufferServiceBase> command_buffer_; @@ -263,6 +272,7 @@ State state_after_last_flush_; base::Lock state_after_last_flush_lock_; scoped_refptr<gfx::GLShareGroup> gl_share_group_; + base::WaitableEvent fence_sync_wait_event_; #if defined(OS_ANDROID) scoped_ptr<StreamTextureManagerInProcess> stream_texture_manager_;
diff --git a/gpu/command_buffer/service/mailbox_manager.h b/gpu/command_buffer/service/mailbox_manager.h index 2bfdb89..78fb8f8 100644 --- a/gpu/command_buffer/service/mailbox_manager.h +++ b/gpu/command_buffer/service/mailbox_manager.h
@@ -13,6 +13,7 @@ namespace gles2 { class Texture; +struct SyncToken; // Manages resources scoped beyond the context or context group level. class GPU_EXPORT MailboxManager : public base::RefCounted<MailboxManager> { @@ -29,8 +30,8 @@ virtual bool UsesSync() = 0; // Used to synchronize texture state across share groups. - virtual void PushTextureUpdates(uint32 sync_point) = 0; - virtual void PullTextureUpdates(uint32 sync_point) = 0; + virtual void PushTextureUpdates(const SyncToken& token) = 0; + virtual void PullTextureUpdates(const SyncToken& token) = 0; // Destroy any mailbox that reference the given texture. virtual void TextureDeleted(Texture* texture) = 0;
diff --git a/gpu/command_buffer/service/mailbox_manager_impl.h b/gpu/command_buffer/service/mailbox_manager_impl.h index 5ea906e8..135b826 100644 --- a/gpu/command_buffer/service/mailbox_manager_impl.h +++ b/gpu/command_buffer/service/mailbox_manager_impl.h
@@ -30,8 +30,8 @@ Texture* ConsumeTexture(const Mailbox& mailbox) override; void ProduceTexture(const Mailbox& mailbox, Texture* texture) override; bool UsesSync() override; - void PushTextureUpdates(uint32 sync_point) override {} - void PullTextureUpdates(uint32 sync_point) override {} + void PushTextureUpdates(const SyncToken& token) override {} + void PullTextureUpdates(const SyncToken& token) override {} void TextureDeleted(Texture* texture) override; protected:
diff --git a/gpu/command_buffer/service/mailbox_manager_sync.cc b/gpu/command_buffer/service/mailbox_manager_sync.cc index 09d0d52..383cbb5c 100644 --- a/gpu/command_buffer/service/mailbox_manager_sync.cc +++ b/gpu/command_buffer/service/mailbox_manager_sync.cc
@@ -9,6 +9,7 @@ #include "base/memory/linked_ptr.h" #include "base/synchronization/lock.h" +#include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/service/texture_manager.h" #include "ui/gl/gl_fence.h" #include "ui/gl/gl_implementation.h" @@ -24,23 +25,23 @@ base::LazyInstance<base::Lock> g_lock = LAZY_INSTANCE_INITIALIZER; -typedef std::map<uint32, linked_ptr<gfx::GLFence>> SyncPointToFenceMap; -base::LazyInstance<SyncPointToFenceMap> g_sync_point_to_fence = - LAZY_INSTANCE_INITIALIZER; #if !defined(OS_MACOSX) -base::LazyInstance<std::queue<SyncPointToFenceMap::iterator>> g_sync_points = +typedef std::map<SyncToken, linked_ptr<gfx::GLFence>> SyncTokenToFenceMap; +base::LazyInstance<SyncTokenToFenceMap> g_sync_point_to_fence = + LAZY_INSTANCE_INITIALIZER; +base::LazyInstance<std::queue<SyncTokenToFenceMap::iterator>> g_sync_points = LAZY_INSTANCE_INITIALIZER; #endif -void CreateFenceLocked(uint32 sync_point) { +void CreateFenceLocked(const SyncToken& sync_token) { +#if !defined(OS_MACOSX) g_lock.Get().AssertAcquired(); if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL) return; -#if !defined(OS_MACOSX) - std::queue<SyncPointToFenceMap::iterator>& sync_points = g_sync_points.Get(); - SyncPointToFenceMap& sync_point_to_fence = g_sync_point_to_fence.Get(); - if (sync_point) { + std::queue<SyncTokenToFenceMap::iterator>& sync_points = g_sync_points.Get(); + SyncTokenToFenceMap& sync_point_to_fence = g_sync_point_to_fence.Get(); + if (sync_token.release_count) { while (!sync_points.empty() && sync_points.front()->second->HasCompleted()) { sync_point_to_fence.erase(sync_points.front()); @@ -49,8 +50,8 @@ // Need to use EGL fences since we are likely not in a single share group. linked_ptr<gfx::GLFence> fence(make_linked_ptr(new gfx::GLFenceEGL)); if (fence.get()) { - std::pair<SyncPointToFenceMap::iterator, bool> result = - sync_point_to_fence.insert(std::make_pair(sync_point, fence)); + std::pair<SyncTokenToFenceMap::iterator, bool> result = + sync_point_to_fence.insert(std::make_pair(sync_token, fence)); DCHECK(result.second); sync_points.push(result.first); } @@ -59,13 +60,15 @@ #endif } -void AcquireFenceLocked(uint32 sync_point) { +void AcquireFenceLocked(const SyncToken& sync_token) { +#if !defined(OS_MACOSX) g_lock.Get().AssertAcquired(); - SyncPointToFenceMap::iterator fence_it = - g_sync_point_to_fence.Get().find(sync_point); + SyncTokenToFenceMap::iterator fence_it = + g_sync_point_to_fence.Get().find(sync_token); if (fence_it != g_sync_point_to_fence.Get().end()) { fence_it->second->ServerWait(); } +#endif } static const unsigned kNewTextureVersion = 1; @@ -294,22 +297,22 @@ gl_image ? image_buffer : NULL)); } -void MailboxManagerSync::PushTextureUpdates(uint32 sync_point) { +void MailboxManagerSync::PushTextureUpdates(const SyncToken& token) { base::AutoLock lock(g_lock.Get()); for (TextureToGroupMap::iterator it = texture_to_group_.begin(); it != texture_to_group_.end(); it++) { UpdateDefinitionLocked(it->first, &it->second); } - CreateFenceLocked(sync_point); + CreateFenceLocked(token); } -void MailboxManagerSync::PullTextureUpdates(uint32 sync_point) { +void MailboxManagerSync::PullTextureUpdates(const SyncToken& token) { using TextureUpdatePair = std::pair<Texture*, TextureDefinition>; std::vector<TextureUpdatePair> needs_update; { base::AutoLock lock(g_lock.Get()); - AcquireFenceLocked(sync_point); + AcquireFenceLocked(token); for (TextureToGroupMap::iterator it = texture_to_group_.begin(); it != texture_to_group_.end(); it++) {
diff --git a/gpu/command_buffer/service/mailbox_manager_sync.h b/gpu/command_buffer/service/mailbox_manager_sync.h index 481948e..ff16dd7 100644 --- a/gpu/command_buffer/service/mailbox_manager_sync.h +++ b/gpu/command_buffer/service/mailbox_manager_sync.h
@@ -33,8 +33,8 @@ Texture* ConsumeTexture(const Mailbox& mailbox) override; void ProduceTexture(const Mailbox& mailbox, Texture* texture) override; bool UsesSync() override; - void PushTextureUpdates(uint32 sync_point) override; - void PullTextureUpdates(uint32 sync_point) override; + void PushTextureUpdates(const SyncToken& token) override; + void PullTextureUpdates(const SyncToken& token) override; void TextureDeleted(Texture* texture) override; private:
diff --git a/gpu/command_buffer/service/mailbox_manager_unittest.cc b/gpu/command_buffer/service/mailbox_manager_unittest.cc index d715a398..5101604 100644 --- a/gpu/command_buffer/service/mailbox_manager_unittest.cc +++ b/gpu/command_buffer/service/mailbox_manager_unittest.cc
@@ -17,6 +17,9 @@ using namespace ::testing; +static const SyncToken g_sync_token = {gpu::CommandBufferNamespace::GPU_IO, 123, + 0}; + class MailboxManagerTest : public GpuServiceTest { public: MailboxManagerTest() {} @@ -276,8 +279,8 @@ EXPECT_EQ(texture, manager_->ConsumeTexture(name)); // Synchronize - manager_->PushTextureUpdates(0); - manager2_->PullTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); + manager2_->PullTextureUpdates(g_sync_token); DestroyTexture(texture); EXPECT_EQ(NULL, manager_->ConsumeTexture(name)); @@ -291,7 +294,7 @@ Mailbox name = Mailbox::Generate(); manager_->ProduceTexture(name, texture); - manager_->PushTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); // Clobber Texture* old_texture = texture; @@ -317,8 +320,8 @@ EXPECT_EQ(texture, manager_->ConsumeTexture(name)); // Synchronize - manager_->PushTextureUpdates(0); - manager2_->PullTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); + manager2_->PullTextureUpdates(g_sync_token); EXPECT_CALL(*gl_, GenTextures(1, _)) .WillOnce(SetArgPointee<1>(kNewTextureId)); @@ -336,10 +339,10 @@ EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL); // Synchronize again - manager_->PushTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); SetupUpdateTexParamExpectations( kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); - manager2_->PullTextureUpdates(0); + manager2_->PullTextureUpdates(g_sync_token); GLsizei width, height; new_texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr); EXPECT_EQ(16, width); @@ -360,7 +363,7 @@ // The last change to the texture should be visible without a sync point (i.e. // push). - manager2_->PullTextureUpdates(0); + manager2_->PullTextureUpdates(g_sync_token); new_texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, nullptr); EXPECT_EQ(64, width); EXPECT_EQ(64, height); @@ -388,8 +391,8 @@ manager2_->ProduceTexture(name2, texture2); // Make visible. - manager_->PushTextureUpdates(0); - manager2_->PushTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); + manager2_->PushTextureUpdates(g_sync_token); // Create textures in the other manager instances for texture1 and texture2, // respectively to create a real sharing scenario. Otherwise, there would @@ -416,7 +419,7 @@ SetParameter(texture1, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); // Make sure this does not clobber it with the previous version we pushed. - manager_->PullTextureUpdates(0); + manager_->PullTextureUpdates(g_sync_token); // Make a change to texture2 DCHECK_EQ(static_cast<GLuint>(GL_LINEAR), texture2->mag_filter()); @@ -426,16 +429,16 @@ Mock::VerifyAndClearExpectations(gl_.get()); // Synchronize in both directions - manager_->PushTextureUpdates(0); - manager2_->PushTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); + manager2_->PushTextureUpdates(g_sync_token); // manager1 should see the change to texture2 mag_filter being applied. SetupUpdateTexParamExpectations( new_texture2->service_id(), GL_LINEAR, GL_NEAREST, GL_REPEAT, GL_REPEAT); - manager_->PullTextureUpdates(0); + manager_->PullTextureUpdates(g_sync_token); // manager2 should see the change to texture1 min_filter being applied. SetupUpdateTexParamExpectations( new_texture1->service_id(), GL_NEAREST, GL_LINEAR, GL_REPEAT, GL_REPEAT); - manager2_->PullTextureUpdates(0); + manager2_->PullTextureUpdates(g_sync_token); DestroyTexture(texture1); DestroyTexture(texture2); @@ -457,8 +460,8 @@ EXPECT_EQ(texture, manager_->ConsumeTexture(name)); // Synchronize - manager_->PushTextureUpdates(0); - manager2_->PullTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); + manager2_->PullTextureUpdates(g_sync_token); EXPECT_CALL(*gl_, GenTextures(1, _)) .WillOnce(SetArgPointee<1>(kNewTextureId)); @@ -479,8 +482,8 @@ SetParameter(texture, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); // Synchronize in both directions - no changes, since it's not shared - manager_->PushTextureUpdates(0); - manager2_->PullTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); + manager2_->PullTextureUpdates(g_sync_token); EXPECT_EQ(static_cast<GLuint>(GL_LINEAR), new_texture->min_filter()); // Make a change to the previously shared texture @@ -489,10 +492,10 @@ SetParameter(old_texture, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); // Synchronize and expect update - manager_->PushTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); SetupUpdateTexParamExpectations( new_texture->service_id(), GL_LINEAR, GL_NEAREST, GL_REPEAT, GL_REPEAT); - manager2_->PullTextureUpdates(0); + manager2_->PullTextureUpdates(g_sync_token); EXPECT_CALL(*gl_, GenTextures(1, _)) .WillOnce(SetArgPointee<1>(kNewTextureId)); @@ -522,8 +525,8 @@ EXPECT_EQ(texture, manager_->ConsumeTexture(name)); // Synchronize - manager_->PushTextureUpdates(0); - manager2_->PullTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); + manager2_->PullTextureUpdates(g_sync_token); EXPECT_CALL(*gl_, GenTextures(1, _)) .WillOnce(SetArgPointee<1>(kNewTextureId)); @@ -540,10 +543,10 @@ EXPECT_FALSE(texture->SafeToRenderFrom()); // Synchronize - manager_->PushTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); SetupUpdateTexParamExpectations( kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); - manager2_->PullTextureUpdates(0); + manager2_->PullTextureUpdates(g_sync_token); // Cleared state should be synced. EXPECT_FALSE(new_texture->SafeToRenderFrom()); @@ -568,8 +571,8 @@ EXPECT_EQ(texture, manager_->ConsumeTexture(name)); // Synchronize - manager_->PushTextureUpdates(0); - manager2_->PullTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); + manager2_->PullTextureUpdates(g_sync_token); // Should sync to new texture which is not defined. EXPECT_CALL(*gl_, GenTextures(1, _)) @@ -591,10 +594,10 @@ EXPECT_TRUE(texture->IsDefined()); // Synchronize - manager_->PushTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); SetupUpdateTexParamExpectations( kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); - manager2_->PullTextureUpdates(0); + manager2_->PullTextureUpdates(g_sync_token); // Cleared state should be synced. EXPECT_TRUE(new_texture->IsDefined()); @@ -619,10 +622,10 @@ manager_->ProduceTexture(name1, texture); // Share - manager_->PushTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); EXPECT_CALL(*gl_, GenTextures(1, _)) .WillOnce(SetArgPointee<1>(kNewTextureId)); - manager2_->PullTextureUpdates(0); + manager2_->PullTextureUpdates(g_sync_token); SetupUpdateTexParamExpectations( kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT); Texture* new_texture = manager2_->ConsumeTexture(name1); @@ -631,8 +634,8 @@ manager_->ProduceTexture(name2, texture); // Synchronize - manager_->PushTextureUpdates(0); - manager2_->PullTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); + manager2_->PullTextureUpdates(g_sync_token); // name2 should return the same texture EXPECT_EQ(new_texture, manager2_->ConsumeTexture(name2)); @@ -658,7 +661,7 @@ manager_->ProduceTexture(name, texture1); // Share - manager_->PushTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); EXPECT_CALL(*gl_, GenTextures(1, _)) .WillOnce(SetArgPointee<1>(kNewTextureId)); SetupUpdateTexParamExpectations( @@ -671,8 +674,8 @@ manager_->ProduceTexture(name, texture1); // Synchronize manager -> manager2 - manager_->PushTextureUpdates(0); - manager2_->PullTextureUpdates(0); + manager_->PushTextureUpdates(g_sync_token); + manager2_->PullTextureUpdates(g_sync_token); // name should return the original texture, and not texture2 or a new one. EXPECT_EQ(new_texture, manager2_->ConsumeTexture(name));
diff --git a/gpu/command_buffer/service/sync_point_manager.cc b/gpu/command_buffer/service/sync_point_manager.cc index 039e494d..bc73adb 100644 --- a/gpu/command_buffer/service/sync_point_manager.cc +++ b/gpu/command_buffer/service/sync_point_manager.cc
@@ -6,47 +6,281 @@ #include <climits> +#include "base/bind.h" +#include "base/containers/hash_tables.h" +#include "base/location.h" #include "base/logging.h" #include "base/rand_util.h" #include "base/sequence_checker.h" +#include "base/single_thread_task_runner.h" namespace gpu { static const int kMaxSyncBase = INT_MAX; -scoped_refptr<SyncPointClientState> SyncPointClientState::Create() { - return new SyncPointClientState; +namespace { + +void RunOnThread(scoped_refptr<base::SingleThreadTaskRunner> task_runner, + const base::Closure& callback) { + if (task_runner->BelongsToCurrentThread()) { + callback.Run(); + } else { + task_runner->PostTask(FROM_HERE, callback); + } } -uint32_t SyncPointClientState::GenerateUnprocessedOrderNumber( +} // namespace + +scoped_refptr<SyncPointOrderData> SyncPointOrderData::Create() { + return new SyncPointOrderData; +} + +void SyncPointOrderData::Destroy() { + // Because of circular references between the SyncPointOrderData and + // SyncPointClientState, we must remove the references on destroy. Releasing + // the fence syncs in the order fence queue would be redundant at this point + // because they are assumed to be released on the destruction of the + // SyncPointClient. + base::AutoLock auto_lock(lock_); + destroyed_ = true; + while (!order_fence_queue_.empty()) { + order_fence_queue_.pop(); + } +} + +uint32_t SyncPointOrderData::GenerateUnprocessedOrderNumber( SyncPointManager* sync_point_manager) { const uint32_t order_num = sync_point_manager->GenerateOrderNumber(); - base::subtle::Release_Store(&unprocessed_order_num_, order_num); + base::AutoLock auto_lock(lock_); + unprocessed_order_num_ = order_num; return order_num; } -SyncPointClientState::SyncPointClientState() - : processed_order_num_(0), - unprocessed_order_num_(0), - current_order_num_(0) { +void SyncPointOrderData::BeginProcessingOrderNumber(uint32_t order_num) { + DCHECK(processing_thread_checker_.CalledOnValidThread()); + DCHECK_GE(order_num, current_order_num_); + current_order_num_ = order_num; + + // Catch invalid waits which were waiting on fence syncs that do not exist. + // When we begin processing an order number, we should release any fence + // syncs which were enqueued but the order number never existed. + // Release without the lock to avoid possible deadlocks. + std::vector<OrderFence> ensure_releases; + { + base::AutoLock auto_lock(lock_); + while (!order_fence_queue_.empty()) { + const OrderFence& order_fence = order_fence_queue_.top(); + if (order_fence_queue_.top().order_num < order_num) { + ensure_releases.push_back(order_fence); + order_fence_queue_.pop(); + continue; + } + break; + } + } + + for (OrderFence& order_fence : ensure_releases) { + order_fence.client_state->EnsureReleased(order_fence.fence_release); + } } +void SyncPointOrderData::FinishProcessingOrderNumber(uint32_t order_num) { + DCHECK(processing_thread_checker_.CalledOnValidThread()); + DCHECK_EQ(current_order_num_, order_num); + + // Catch invalid waits which were waiting on fence syncs that do not exist. + // When we end processing an order number, we should release any fence syncs + // which were suppose to be released during this order number. + // Release without the lock to avoid possible deadlocks. + std::vector<OrderFence> ensure_releases; + { + base::AutoLock auto_lock(lock_); + DCHECK_GT(order_num, processed_order_num_); + processed_order_num_ = order_num; + + while (!order_fence_queue_.empty()) { + const OrderFence& order_fence = order_fence_queue_.top(); + if (order_fence_queue_.top().order_num <= order_num) { + ensure_releases.push_back(order_fence); + order_fence_queue_.pop(); + continue; + } + break; + } + } + + for (OrderFence& order_fence : ensure_releases) { + order_fence.client_state->EnsureReleased(order_fence.fence_release); + } +} + +SyncPointOrderData::OrderFence::OrderFence( + uint32_t order, + uint64_t release, + scoped_refptr<SyncPointClientState> state) + : order_num(order), fence_release(release), client_state(state) {} + +SyncPointOrderData::OrderFence::~OrderFence() {} + +SyncPointOrderData::SyncPointOrderData() + : current_order_num_(0), + destroyed_(false), + processed_order_num_(0), + unprocessed_order_num_(0) {} + +SyncPointOrderData::~SyncPointOrderData() {} + +bool SyncPointOrderData::ValidateReleaseOrderNumber( + scoped_refptr<SyncPointClientState> client_state, + uint32_t wait_order_num, + uint64_t fence_release) { + base::AutoLock auto_lock(lock_); + if (destroyed_) + return false; + + // Release should have a possible unprocessed order number lower + // than the wait order number. + if ((processed_order_num_ + 1) >= wait_order_num) + return false; + + // Release should have more unprocessed numbers if we are waiting. + if (unprocessed_order_num_ <= processed_order_num_) + return false; + + // So far it could be valid, but add an order fence guard to be sure it + // gets released eventually. + const uint32_t expected_order_num = + std::min(unprocessed_order_num_, wait_order_num); + order_fence_queue_.push( + OrderFence(expected_order_num, fence_release, client_state)); + return true; +} + +SyncPointClientState::ReleaseCallback::ReleaseCallback( + uint64_t release, + const base::Closure& callback) + : release_count(release), callback_closure(callback) {} + +SyncPointClientState::ReleaseCallback::~ReleaseCallback() {} + +SyncPointClientState::SyncPointClientState( + scoped_refptr<SyncPointOrderData> order_data) + : order_data_(order_data), fence_sync_release_(0) {} + SyncPointClientState::~SyncPointClientState() { } +bool SyncPointClientState::WaitForRelease(uint32_t wait_order_num, + uint64_t release, + const base::Closure& callback) { + // Lock must be held the whole time while we validate otherwise it could be + // released while we are checking. + { + base::AutoLock auto_lock(fence_sync_lock_); + if (release > fence_sync_release_) { + if (!order_data_->ValidateReleaseOrderNumber(this, wait_order_num, + release)) { + return false; + } else { + // Add the callback which will be called upon release. + release_callback_queue_.push(ReleaseCallback(release, callback)); + return true; + } + } + } + + // Already released, run the callback now. + callback.Run(); + return true; +} + +void SyncPointClientState::ReleaseFenceSync(uint64_t release) { + // Call callbacks without the lock to avoid possible deadlocks. + std::vector<base::Closure> callback_list; + { + base::AutoLock auto_lock(fence_sync_lock_); + ReleaseFenceSyncLocked(release, &callback_list); + } + + for (const base::Closure& closure : callback_list) { + closure.Run(); + } +} + +void SyncPointClientState::EnsureReleased(uint64_t release) { + // Call callbacks without the lock to avoid possible deadlocks. + std::vector<base::Closure> callback_list; + { + base::AutoLock auto_lock(fence_sync_lock_); + if (release <= fence_sync_release_) + return; + + ReleaseFenceSyncLocked(release, &callback_list); + } + + for (const base::Closure& closure : callback_list) { + closure.Run(); + } +} + +void SyncPointClientState::ReleaseFenceSyncLocked( + uint64_t release, + std::vector<base::Closure>* callback_list) { + fence_sync_lock_.AssertAcquired(); + DCHECK_GT(release, fence_sync_release_); + + fence_sync_release_ = release; + while (!release_callback_queue_.empty() && + release_callback_queue_.top().release_count <= release) { + callback_list->push_back(release_callback_queue_.top().callback_closure); + release_callback_queue_.pop(); + } +} + SyncPointClient::~SyncPointClient() { + // Release all fences on destruction. + ReleaseFenceSync(UINT64_MAX); + sync_point_manager_->DestroySyncPointClient(namespace_id_, client_id_); } +bool SyncPointClient::Wait(SyncPointClientState* release_state, + uint64_t release_count, + const base::Closure& wait_complete_callback) { + const uint32_t wait_order_number = + client_state_->order_data()->current_order_num(); + + // If waiting on self or wait was invalid, call the callback and return false. + if (client_state_ == release_state || + !release_state->WaitForRelease(wait_order_number, release_count, + wait_complete_callback)) { + wait_complete_callback.Run(); + return false; + } + return true; +} + +bool SyncPointClient::WaitNonThreadSafe( + SyncPointClientState* release_state, + uint64_t release_count, + scoped_refptr<base::SingleThreadTaskRunner> runner, + const base::Closure& wait_complete_callback) { + return Wait(release_state, release_count, + base::Bind(&RunOnThread, runner, wait_complete_callback)); +} + +void SyncPointClient::ReleaseFenceSync(uint64_t release) { + client_state_->ReleaseFenceSync(release); +} + SyncPointClient::SyncPointClient(SyncPointManager* sync_point_manager, - scoped_refptr<SyncPointClientState> state, + scoped_refptr<SyncPointOrderData> order_data, CommandBufferNamespace namespace_id, uint64_t client_id) - : sync_point_manager_(sync_point_manager), - client_state_(state), - namespace_id_(namespace_id), - client_id_(client_id) { -} + : sync_point_manager_(sync_point_manager), + client_state_(new SyncPointClientState(order_data)), + namespace_id_(namespace_id), + client_id_(client_id) {} SyncPointManager::SyncPointManager(bool allow_threaded_wait) : allow_threaded_wait_(allow_threaded_wait), @@ -65,18 +299,17 @@ } scoped_ptr<SyncPointClient> SyncPointManager::CreateSyncPointClient( - scoped_refptr<SyncPointClientState> client_state, - CommandBufferNamespace namespace_id, uint64_t client_id) { + scoped_refptr<SyncPointOrderData> order_data, + CommandBufferNamespace namespace_id, + uint64_t client_id) { DCHECK_GE(namespace_id, 0); DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_)); base::AutoLock auto_lock(client_maps_lock_); ClientMap& client_map = client_maps_[namespace_id]; std::pair<ClientMap::iterator, bool> result = client_map.insert( - std::make_pair(client_id, new SyncPointClient(this, - client_state, - namespace_id, - client_id))); + std::make_pair(client_id, new SyncPointClient(this, order_data, + namespace_id, client_id))); DCHECK(result.second); return make_scoped_ptr(result.first->second);
diff --git a/gpu/command_buffer/service/sync_point_manager.h b/gpu/command_buffer/service/sync_point_manager.h index 3f11e05..a72566b0d 100644 --- a/gpu/command_buffer/service/sync_point_manager.h +++ b/gpu/command_buffer/service/sync_point_manager.h
@@ -5,6 +5,8 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_SYNC_POINT_MANAGER_H_ #define GPU_COMMAND_BUFFER_SERVICE_SYNC_POINT_MANAGER_H_ +#include <functional> +#include <queue> #include <vector> #include "base/atomic_sequence_num.h" @@ -19,36 +21,34 @@ #include "gpu/command_buffer/common/constants.h" #include "gpu/gpu_export.h" +namespace base { +class SingleThreadTaskRunner; +} // namespace base + namespace gpu { class SyncPointClient; +class SyncPointClientState; class SyncPointManager; -class GPU_EXPORT SyncPointClientState - : public base::RefCountedThreadSafe<SyncPointClientState> { +class GPU_EXPORT SyncPointOrderData + : public base::RefCountedThreadSafe<SyncPointOrderData> { public: - static scoped_refptr<SyncPointClientState> Create(); + static scoped_refptr<SyncPointOrderData> Create(); + void Destroy(); + uint32_t GenerateUnprocessedOrderNumber(SyncPointManager* sync_point_manager); - - void BeginProcessingOrderNumber(uint32_t order_num) { - DCHECK(processing_thread_checker_.CalledOnValidThread()); - DCHECK_GE(order_num, current_order_num_); - current_order_num_ = order_num; - } - - void FinishProcessingOrderNumber(uint32_t order_num) { - DCHECK(processing_thread_checker_.CalledOnValidThread()); - DCHECK_EQ(current_order_num_, order_num); - DCHECK_GT(order_num, processed_order_num()); - base::subtle::Release_Store(&processed_order_num_, order_num); - } + void BeginProcessingOrderNumber(uint32_t order_num); + void FinishProcessingOrderNumber(uint32_t order_num); uint32_t processed_order_num() const { - return base::subtle::Acquire_Load(&processed_order_num_); + base::AutoLock auto_lock(lock_); + return processed_order_num_; } uint32_t unprocessed_order_num() const { - return base::subtle::Acquire_Load(&unprocessed_order_num_); + base::AutoLock auto_lock(lock_); + return unprocessed_order_num_; } uint32_t current_order_num() const { @@ -56,18 +56,37 @@ return current_order_num_; } - protected: - friend class base::RefCountedThreadSafe<SyncPointClientState>; - friend class SyncPointClient; + private: + friend class base::RefCountedThreadSafe<SyncPointOrderData>; + friend class SyncPointClientState; - SyncPointClientState(); - virtual ~SyncPointClientState(); + struct OrderFence { + uint32_t order_num; + uint64_t fence_release; + scoped_refptr<SyncPointClientState> client_state; - // Last finished IPC order number. - base::subtle::Atomic32 processed_order_num_; + OrderFence(uint32_t order, + uint64_t release, + scoped_refptr<SyncPointClientState> state); + ~OrderFence(); - // Unprocessed order number expected to be processed under normal execution. - base::subtle::Atomic32 unprocessed_order_num_; + bool operator>(const OrderFence& rhs) const { + return (order_num > rhs.order_num) || + ((order_num == rhs.order_num) && + (fence_release > rhs.fence_release)); + } + }; + typedef std::priority_queue<OrderFence, + std::vector<OrderFence>, + std::greater<OrderFence>> OrderFenceQueue; + + SyncPointOrderData(); + ~SyncPointOrderData(); + + bool ValidateReleaseOrderNumber( + scoped_refptr<SyncPointClientState> client_state, + uint32_t wait_order_num, + uint64_t fence_release); // Non thread-safe functions need to be called from a single thread. base::ThreadChecker processing_thread_checker_; @@ -75,6 +94,95 @@ // Current IPC order number being processed (only used on processing thread). uint32_t current_order_num_; + // This lock protects destroyed_, processed_order_num_, + // unprocessed_order_num_, and order_fence_queue_. All order numbers (n) in + // order_fence_queue_ must follow the invariant: + // processed_order_num_ < n <= unprocessed_order_num_. + mutable base::Lock lock_; + + bool destroyed_; + + // Last finished IPC order number. + uint32_t processed_order_num_; + + // Unprocessed order number expected to be processed under normal execution. + uint32_t unprocessed_order_num_; + + // In situations where we are waiting on fence syncs that do not exist, we + // validate by making sure the order number does not pass the order number + // which the wait command was issued. If the order number reaches the + // wait command's, we should automatically release up to the expected + // release count. Note that this also releases other lower release counts, + // so a single misbehaved fence sync is enough to invalidate/signal all + // previous fence syncs. + OrderFenceQueue order_fence_queue_; + + DISALLOW_COPY_AND_ASSIGN(SyncPointOrderData); +}; + +class GPU_EXPORT SyncPointClientState + : public base::RefCountedThreadSafe<SyncPointClientState> { + public: + scoped_refptr<SyncPointOrderData> order_data() { return order_data_; } + + bool IsFenceSyncReleased(uint64_t release) { + return release <= fence_sync_release(); + } + + uint64_t fence_sync_release() { + base::AutoLock auto_lock(fence_sync_lock_); + return fence_sync_release_; + } + + private: + friend class base::RefCountedThreadSafe<SyncPointClientState>; + friend class SyncPointClient; + friend class SyncPointOrderData; + + struct ReleaseCallback { + uint64_t release_count; + base::Closure callback_closure; + + ReleaseCallback(uint64_t release, const base::Closure& callback); + ~ReleaseCallback(); + + bool operator>(const ReleaseCallback& rhs) const { + return release_count > rhs.release_count; + } + }; + typedef std::priority_queue<ReleaseCallback, + std::vector<ReleaseCallback>, + std::greater<ReleaseCallback>> + ReleaseCallbackQueue; + + SyncPointClientState(scoped_refptr<SyncPointOrderData> order_data); + ~SyncPointClientState(); + + // Queues the callback to be called if the release is valid. If the release + // is invalid this function will return False and the callback will never + // be called. + bool WaitForRelease(uint32_t wait_order_num, + uint64_t release, + const base::Closure& callback); + + void ReleaseFenceSync(uint64_t release); + void EnsureReleased(uint64_t release); + void ReleaseFenceSyncLocked(uint64_t release, + std::vector<base::Closure>* callback_list); + + // Global order data where releases will originate from. + scoped_refptr<SyncPointOrderData> order_data_; + + // Protects fence_sync_release_, fence_callback_queue_. + base::Lock fence_sync_lock_; + + // Current fence sync release that has been signaled. + uint64_t fence_sync_release_; + + // In well defined fence sync operations, fence syncs are released in order + // so simply having a priority queue for callbacks is enough. + ReleaseCallbackQueue release_callback_queue_; + DISALLOW_COPY_AND_ASSIGN(SyncPointClientState); }; @@ -84,12 +192,32 @@ scoped_refptr<SyncPointClientState> client_state() { return client_state_; } + // Wait for a release count to be reached on a SyncPointClientState. If this + // function returns false, that means the wait was invalid. Otherwise if it + // returns True it means the release was valid. In the case where the release + // is valid but has happened already, it will still return true. In all cases + // wait_complete_callback will be called eventually. The callback function + // may be called on another thread so it should be thread-safe. For + // convenience, another non-threadsafe version is defined below where you + // can supply a task runner. + bool Wait(SyncPointClientState* release_state, + uint64_t release_count, + const base::Closure& wait_complete_callback); + + bool WaitNonThreadSafe(SyncPointClientState* release_state, + uint64_t release_count, + scoped_refptr<base::SingleThreadTaskRunner> runner, + const base::Closure& wait_complete_callback); + + void ReleaseFenceSync(uint64_t release); + private: friend class SyncPointManager; SyncPointClient(SyncPointManager* sync_point_manager, - scoped_refptr<SyncPointClientState> state, - CommandBufferNamespace namespace_id, uint64_t client_id); + scoped_refptr<SyncPointOrderData> order_data, + CommandBufferNamespace namespace_id, + uint64_t client_id); // Sync point manager is guaranteed to exist in the lifetime of the client. SyncPointManager* sync_point_manager_; @@ -98,8 +226,8 @@ scoped_refptr<SyncPointClientState> client_state_; // Unique namespace/client id pair for this sync point client. - CommandBufferNamespace namespace_id_; - uint64_t client_id_; + const CommandBufferNamespace namespace_id_; + const uint64_t client_id_; DISALLOW_COPY_AND_ASSIGN(SyncPointClient); }; @@ -113,8 +241,9 @@ // Creates/Destroy a sync point client which message processors should hold. scoped_ptr<SyncPointClient> CreateSyncPointClient( - scoped_refptr<SyncPointClientState> client_state, - CommandBufferNamespace namespace_id, uint64_t client_id); + scoped_refptr<SyncPointOrderData> order_data, + CommandBufferNamespace namespace_id, + uint64_t client_id); // Finds the state of an already created sync point client. scoped_refptr<SyncPointClientState> GetSyncPointClientState( @@ -142,7 +271,7 @@ private: friend class SyncPointClient; - friend class SyncPointClientState; + friend class SyncPointOrderData; typedef std::vector<base::Closure> ClosureList; typedef base::hash_map<uint32, ClosureList> SyncPointMap;
diff --git a/gpu/command_buffer/service/sync_point_manager_unittest.cc b/gpu/command_buffer/service/sync_point_manager_unittest.cc new file mode 100644 index 0000000..0b42505 --- /dev/null +++ b/gpu/command_buffer/service/sync_point_manager_unittest.cc
@@ -0,0 +1,415 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <queue> + +#include "base/bind.h" +#include "gpu/command_buffer/service/sync_point_manager.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace gpu { + +class SyncPointManagerTest : public testing::Test { + public: + SyncPointManagerTest() {} + + ~SyncPointManagerTest() override {} + + protected: + void SetUp() override { + sync_point_manager_.reset(new SyncPointManager(false)); + } + + void TearDown() override { sync_point_manager_.reset(); } + + // Simple static function which can be used to test callbacks. + static void SetIntegerFunction(int* test, int value) { *test = value; } + + scoped_ptr<SyncPointManager> sync_point_manager_; +}; + +struct SyncPointStream { + scoped_refptr<SyncPointOrderData> order_data; + scoped_ptr<SyncPointClient> client; + std::queue<uint32_t> order_numbers; + + SyncPointStream(SyncPointManager* sync_point_manager, + CommandBufferNamespace namespace_id, + uint64_t command_buffer_id) + : order_data(SyncPointOrderData::Create()), + client(sync_point_manager->CreateSyncPointClient(order_data, + namespace_id, + command_buffer_id)) {} + + ~SyncPointStream() { + order_data->Destroy(); + order_data = nullptr; + } + + void AllocateOrderNum(SyncPointManager* sync_point_manager) { + order_numbers.push( + order_data->GenerateUnprocessedOrderNumber(sync_point_manager)); + } + + void BeginProcessing() { + ASSERT_FALSE(order_numbers.empty()); + order_data->BeginProcessingOrderNumber(order_numbers.front()); + } + + void EndProcessing() { + ASSERT_FALSE(order_numbers.empty()); + order_data->FinishProcessingOrderNumber(order_numbers.front()); + order_numbers.pop(); + } +}; + +TEST_F(SyncPointManagerTest, BasicSyncPointOrderDataTest) { + scoped_refptr<SyncPointOrderData> order_data = SyncPointOrderData::Create(); + + EXPECT_EQ(0u, order_data->current_order_num()); + EXPECT_EQ(0u, order_data->processed_order_num()); + EXPECT_EQ(0u, order_data->unprocessed_order_num()); + + const uint32_t order_num = + order_data->GenerateUnprocessedOrderNumber(sync_point_manager_.get()); + EXPECT_EQ(1u, order_num); + + EXPECT_EQ(0u, order_data->current_order_num()); + EXPECT_EQ(0u, order_data->processed_order_num()); + EXPECT_EQ(order_num, order_data->unprocessed_order_num()); + + order_data->BeginProcessingOrderNumber(order_num); + EXPECT_EQ(order_num, order_data->current_order_num()); + EXPECT_EQ(0u, order_data->processed_order_num()); + EXPECT_EQ(order_num, order_data->unprocessed_order_num()); + + order_data->FinishProcessingOrderNumber(order_num); + EXPECT_EQ(order_num, order_data->current_order_num()); + EXPECT_EQ(order_num, order_data->processed_order_num()); + EXPECT_EQ(order_num, order_data->unprocessed_order_num()); +} + +TEST_F(SyncPointManagerTest, SyncPointClientRegistration) { + const CommandBufferNamespace kNamespaceId = + gpu::CommandBufferNamespace::GPU_IO; + const uint64_t kBufferId = 0x123; + + scoped_refptr<SyncPointClientState> empty_state = + sync_point_manager_->GetSyncPointClientState(kNamespaceId, kBufferId); + EXPECT_FALSE(empty_state); + + scoped_refptr<SyncPointOrderData> order_data = SyncPointOrderData::Create(); + + scoped_ptr<SyncPointClient> client = + sync_point_manager_->CreateSyncPointClient(order_data, kNamespaceId, + kBufferId); + + EXPECT_EQ(order_data, client->client_state()->order_data()); + EXPECT_EQ( + client->client_state(), + sync_point_manager_->GetSyncPointClientState(kNamespaceId, kBufferId)); +} + +TEST_F(SyncPointManagerTest, BasicFenceSyncRelease) { + const CommandBufferNamespace kNamespaceId = + gpu::CommandBufferNamespace::GPU_IO; + const uint64_t kBufferId = 0x123; + + scoped_refptr<SyncPointOrderData> order_data = SyncPointOrderData::Create(); + scoped_ptr<SyncPointClient> client = + sync_point_manager_->CreateSyncPointClient(order_data, kNamespaceId, + kBufferId); + scoped_refptr<SyncPointClientState> client_state = client->client_state(); + + EXPECT_EQ(0u, client_state->fence_sync_release()); + EXPECT_FALSE(client_state->IsFenceSyncReleased(1)); + + client->ReleaseFenceSync(1); + + EXPECT_EQ(1u, client_state->fence_sync_release()); + EXPECT_TRUE(client_state->IsFenceSyncReleased(1)); +} + +TEST_F(SyncPointManagerTest, MultipleClientsPerOrderData) { + const CommandBufferNamespace kNamespaceId = + gpu::CommandBufferNamespace::GPU_IO; + const uint64_t kBufferId1 = 0x123; + const uint64_t kBufferId2 = 0x234; + + scoped_refptr<SyncPointOrderData> order_data = SyncPointOrderData::Create(); + scoped_ptr<SyncPointClient> client1 = + sync_point_manager_->CreateSyncPointClient(order_data, kNamespaceId, + kBufferId1); + scoped_ptr<SyncPointClient> client2 = + sync_point_manager_->CreateSyncPointClient(order_data, kNamespaceId, + kBufferId2); + + scoped_refptr<SyncPointClientState> client_state1 = client1->client_state(); + scoped_refptr<SyncPointClientState> client_state2 = client2->client_state(); + + client1->ReleaseFenceSync(1); + + EXPECT_TRUE(client_state1->IsFenceSyncReleased(1)); + EXPECT_FALSE(client_state2->IsFenceSyncReleased(1)); +} + +TEST_F(SyncPointManagerTest, BasicFenceSyncWaitRelease) { + const CommandBufferNamespace kNamespaceId = + gpu::CommandBufferNamespace::GPU_IO; + const uint64_t kBufferId1 = 0x123; + const uint64_t kBufferId2 = 0x234; + + SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, + kBufferId1); + SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, + kBufferId2); + + release_stream.AllocateOrderNum(sync_point_manager_.get()); + wait_stream.AllocateOrderNum(sync_point_manager_.get()); + + wait_stream.BeginProcessing(); + int test_num = 10; + const bool valid_wait = wait_stream.client->Wait( + release_stream.client->client_state().get(), 1, + base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); + ASSERT_TRUE(valid_wait); + EXPECT_EQ(10, test_num); + + release_stream.BeginProcessing(); + release_stream.client->ReleaseFenceSync(1); + EXPECT_EQ(123, test_num); +} + +TEST_F(SyncPointManagerTest, WaitOnSelfFails) { + const CommandBufferNamespace kNamespaceId = + gpu::CommandBufferNamespace::GPU_IO; + const uint64_t kBufferId1 = 0x123; + const uint64_t kBufferId2 = 0x234; + + SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, + kBufferId1); + SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, + kBufferId2); + + // Generate wait order number first. + release_stream.AllocateOrderNum(sync_point_manager_.get()); + wait_stream.AllocateOrderNum(sync_point_manager_.get()); + + wait_stream.BeginProcessing(); + int test_num = 10; + const bool valid_wait = wait_stream.client->Wait( + wait_stream.client->client_state().get(), 1, + base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); + EXPECT_FALSE(valid_wait); + EXPECT_EQ(123, test_num); +} + +TEST_F(SyncPointManagerTest, OutOfOrderRelease) { + const CommandBufferNamespace kNamespaceId = + gpu::CommandBufferNamespace::GPU_IO; + const uint64_t kBufferId1 = 0x123; + const uint64_t kBufferId2 = 0x234; + + SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, + kBufferId1); + SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, + kBufferId2); + + // Generate wait order number first. + wait_stream.AllocateOrderNum(sync_point_manager_.get()); + release_stream.AllocateOrderNum(sync_point_manager_.get()); + + wait_stream.BeginProcessing(); + int test_num = 10; + const bool valid_wait = wait_stream.client->Wait( + release_stream.client->client_state().get(), 1, + base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); + EXPECT_FALSE(valid_wait); + EXPECT_EQ(123, test_num); +} + +TEST_F(SyncPointManagerTest, HigherOrderNumberRelease) { + const CommandBufferNamespace kNamespaceId = + gpu::CommandBufferNamespace::GPU_IO; + const uint64_t kBufferId1 = 0x123; + const uint64_t kBufferId2 = 0x234; + + SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, + kBufferId1); + SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, + kBufferId2); + + // Generate wait order number first. + wait_stream.AllocateOrderNum(sync_point_manager_.get()); + release_stream.AllocateOrderNum(sync_point_manager_.get()); + + // Order number was higher but it was actually released. + release_stream.BeginProcessing(); + release_stream.client->ReleaseFenceSync(1); + release_stream.EndProcessing(); + + wait_stream.BeginProcessing(); + int test_num = 10; + const bool valid_wait = wait_stream.client->Wait( + release_stream.client->client_state().get(), 1, + base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); + EXPECT_TRUE(valid_wait); + EXPECT_EQ(123, test_num); +} + +TEST_F(SyncPointManagerTest, DestroyedClientRelease) { + const CommandBufferNamespace kNamespaceId = + gpu::CommandBufferNamespace::GPU_IO; + const uint64_t kBufferId1 = 0x123; + const uint64_t kBufferId2 = 0x234; + + SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, + kBufferId1); + SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, + kBufferId2); + + release_stream.AllocateOrderNum(sync_point_manager_.get()); + wait_stream.AllocateOrderNum(sync_point_manager_.get()); + + wait_stream.BeginProcessing(); + int test_num = 10; + const bool valid_wait = wait_stream.client->Wait( + release_stream.client->client_state().get(), 1, + base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); + EXPECT_TRUE(valid_wait); + EXPECT_EQ(10, test_num); + + // Destroying the client should release the wait. + release_stream.client.reset(); + EXPECT_EQ(123, test_num); +} + +TEST_F(SyncPointManagerTest, NonExistentRelease) { + const CommandBufferNamespace kNamespaceId = + gpu::CommandBufferNamespace::GPU_IO; + const uint64_t kBufferId1 = 0x123; + const uint64_t kBufferId2 = 0x234; + + SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, + kBufferId1); + SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, + kBufferId2); + + // Assign release stream order [1] and wait stream order [2]. + // This test simply tests that a wait stream of order [2] waiting on + // release stream of order [1] will still release the fence sync even + // though nothing was released. + release_stream.AllocateOrderNum(sync_point_manager_.get()); + wait_stream.AllocateOrderNum(sync_point_manager_.get()); + + wait_stream.BeginProcessing(); + int test_num = 10; + const bool valid_wait = wait_stream.client->Wait( + release_stream.client->client_state().get(), 1, + base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); + EXPECT_TRUE(valid_wait); + EXPECT_EQ(10, test_num); + + // No release but finishing the order number should automatically release. + release_stream.BeginProcessing(); + EXPECT_EQ(10, test_num); + release_stream.EndProcessing(); + EXPECT_EQ(123, test_num); +} + +TEST_F(SyncPointManagerTest, NonExistentRelease2) { + const CommandBufferNamespace kNamespaceId = + gpu::CommandBufferNamespace::GPU_IO; + const uint64_t kBufferId1 = 0x123; + const uint64_t kBufferId2 = 0x234; + + SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, + kBufferId1); + SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, + kBufferId2); + + // Assign Release stream order [1] and assign Wait stream orders [2, 3]. + // This test is similar to the NonExistentRelease case except + // we place an extra order number in between the release and wait. + // The wait stream [3] is waiting on release stream [1] even though + // order [2] was also generated. Although order [2] only exists on the + // wait stream so the release stream should only know about order [1]. + release_stream.AllocateOrderNum(sync_point_manager_.get()); + wait_stream.AllocateOrderNum(sync_point_manager_.get()); + wait_stream.AllocateOrderNum(sync_point_manager_.get()); + + // Have wait with order [3] to wait on release. + wait_stream.BeginProcessing(); + ASSERT_EQ(2u, wait_stream.order_data->current_order_num()); + wait_stream.EndProcessing(); + wait_stream.BeginProcessing(); + ASSERT_EQ(3u, wait_stream.order_data->current_order_num()); + int test_num = 10; + const bool valid_wait = wait_stream.client->Wait( + release_stream.client->client_state().get(), 1, + base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); + EXPECT_TRUE(valid_wait); + EXPECT_EQ(10, test_num); + + // Even though release stream order [1] did not have a release, it + // should still release the fence when finish processing since the wait + // stream had expected on to exist there. + release_stream.BeginProcessing(); + ASSERT_EQ(1u, release_stream.order_data->current_order_num()); + release_stream.EndProcessing(); + EXPECT_TRUE(release_stream.client->client_state()->IsFenceSyncReleased(1)); + EXPECT_EQ(123, test_num); +} + +TEST_F(SyncPointManagerTest, NonExistentOrderNumRelease) { + const CommandBufferNamespace kNamespaceId = + gpu::CommandBufferNamespace::GPU_IO; + const uint64_t kBufferId1 = 0x123; + const uint64_t kBufferId2 = 0x234; + + SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, + kBufferId1); + SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, + kBufferId2); + + // Assign Release stream orders [1, 4] and assign Wait stream orders [2, 3]. + // Here we are testing that wait order [3] will wait on a fence sync + // in either order [1] or order [2]. Order [2] was not actually assigned + // to the release stream so it is essentially non-existent to the release + // stream's point of view. Once the release stream begins processing the next + // order [3], it should realize order [2] didn't exist and release the fence. + release_stream.AllocateOrderNum(sync_point_manager_.get()); + wait_stream.AllocateOrderNum(sync_point_manager_.get()); + wait_stream.AllocateOrderNum(sync_point_manager_.get()); + release_stream.AllocateOrderNum(sync_point_manager_.get()); + + // Have wait with order [3] to wait on release order [1] or [2]. + wait_stream.BeginProcessing(); + ASSERT_EQ(2u, wait_stream.order_data->current_order_num()); + wait_stream.EndProcessing(); + wait_stream.BeginProcessing(); + ASSERT_EQ(3u, wait_stream.order_data->current_order_num()); + int test_num = 10; + const bool valid_wait = wait_stream.client->Wait( + release_stream.client->client_state().get(), 1, + base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); + EXPECT_TRUE(valid_wait); + EXPECT_EQ(10, test_num); + + // Release stream should know it should release fence sync by order [3], + // so going through order [1] should not release it yet. + release_stream.BeginProcessing(); + ASSERT_EQ(1u, release_stream.order_data->current_order_num()); + release_stream.EndProcessing(); + EXPECT_FALSE(release_stream.client->client_state()->IsFenceSyncReleased(1)); + EXPECT_EQ(10, test_num); + + // Beginning order [4] should immediately trigger the release. + release_stream.BeginProcessing(); + ASSERT_EQ(4u, release_stream.order_data->current_order_num()); + EXPECT_TRUE(release_stream.client->client_state()->IsFenceSyncReleased(1)); + EXPECT_EQ(123, test_num); +} + +} // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_fence_sync_unittest.cc b/gpu/command_buffer/tests/gl_fence_sync_unittest.cc new file mode 100644 index 0000000..ad21f34 --- /dev/null +++ b/gpu/command_buffer/tests/gl_fence_sync_unittest.cc
@@ -0,0 +1,69 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> +#include <GLES2/gl2extchromium.h> + +#include "base/memory/scoped_ptr.h" +#include "gpu/command_buffer/service/sync_point_manager.h" +#include "gpu/command_buffer/tests/gl_manager.h" +#include "gpu/command_buffer/tests/gl_test_utils.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +#define SHADER(Src) #Src + +namespace gpu { + +class GLFenceSyncTest : public testing::Test { + protected: + void SetUp() override { + sync_point_manager_.reset(new SyncPointManager(false)); + + GLManager::Options options; + options.sync_point_manager = sync_point_manager_.get(); + gl1_.Initialize(options); + gl2_.Initialize(options); + } + + void TearDown() override { + gl2_.Destroy(); + gl1_.Destroy(); + + sync_point_manager_.reset(); + } + + scoped_ptr<SyncPointManager> sync_point_manager_; + GLManager gl1_; + GLManager gl2_; +}; + +TEST_F(GLFenceSyncTest, SimpleReleaseWait) { + gl1_.MakeCurrent(); + + const GLuint64 fence_sync = glInsertFenceSyncCHROMIUM(); + GLbyte sync_token[GL_SYNC_TOKEN_SIZE_CHROMIUM]; + glFlush(); + glGenSyncTokenCHROMIUM(fence_sync, sync_token); + ASSERT_TRUE(GL_NO_ERROR == glGetError()); + + // Make sure it is actually released. + scoped_refptr<SyncPointClientState> gl1_client_state = + sync_point_manager_->GetSyncPointClientState(gl1_.GetNamespaceID(), + gl1_.GetCommandBufferID()); + EXPECT_TRUE(gl1_client_state->IsFenceSyncReleased(fence_sync)); + + gl2_.MakeCurrent(); + glWaitSyncTokenCHROMIUM(sync_token); + glFinish(); + + // gl2 should not have released anything. + scoped_refptr<SyncPointClientState> gl2_client_state = + sync_point_manager_->GetSyncPointClientState(gl2_.GetNamespaceID(), + gl2_.GetCommandBufferID()); + EXPECT_EQ(0u, gl2_client_state->fence_sync_release()); +} + +} // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc index 9c6bf41..8d38fdbd 100644 --- a/gpu/command_buffer/tests/gl_manager.cc +++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -28,6 +28,7 @@ #include "gpu/command_buffer/service/image_manager.h" #include "gpu/command_buffer/service/mailbox_manager_impl.h" #include "gpu/command_buffer/service/memory_tracking.h" +#include "gpu/command_buffer/service/sync_point_manager.h" #include "gpu/command_buffer/service/transfer_buffer_manager.h" #include "gpu/command_buffer/service/valuebuffer_manager.h" #include "testing/gtest/include/gtest/gtest.h" @@ -41,6 +42,8 @@ namespace gpu { namespace { +uint64_t g_next_command_buffer_id = 0; + class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer { public: GpuMemoryBufferImpl(base::RefCountedBytes* bytes, @@ -103,6 +106,7 @@ GLManager::Options::Options() : size(4, 4), + sync_point_manager(NULL), share_group_manager(NULL), share_mailbox_manager(NULL), virtual_manager(NULL), @@ -111,7 +115,11 @@ context_lost_allowed(false), context_type(gles2::CONTEXT_TYPE_OPENGLES2) {} -GLManager::GLManager() : context_lost_allowed_(false) { +GLManager::GLManager() + : sync_point_manager_(nullptr), + context_lost_allowed_(false), + command_buffer_id_(g_next_command_buffer_id++), + next_fence_sync_release_(1) { SetupBaseContext(); } @@ -146,6 +154,7 @@ void GLManager::Initialize(const GLManager::Options& options) { InitializeWithCommandLine(options, nullptr); } + void GLManager::InitializeWithCommandLine(const GLManager::Options& options, base::CommandLine* command_line) { const int32 kCommandBufferSize = 1024 * 1024; @@ -253,6 +262,22 @@ return; } + if (options.sync_point_manager) { + sync_point_manager_ = options.sync_point_manager; + sync_point_order_data_ = SyncPointOrderData::Create(); + sync_point_client_ = sync_point_manager_->CreateSyncPointClient( + sync_point_order_data_, GetNamespaceID(), GetCommandBufferID()); + + decoder_->SetFenceSyncReleaseCallback( + base::Bind(&GLManager::OnFenceSyncRelease, base::Unretained(this))); + decoder_->SetWaitFenceSyncCallback( + base::Bind(&GLManager::OnWaitFenceSync, base::Unretained(this))); + } else { + sync_point_manager_ = nullptr; + sync_point_order_data_ = nullptr; + sync_point_client_ = nullptr; + } + command_buffer_->SetPutOffsetChangeCallback( base::Bind(&GLManager::PumpCommands, base::Unretained(this))); command_buffer_->SetGetBufferChangeCallback( @@ -304,6 +329,28 @@ ++use_count_; } +void GLManager::OnFenceSyncRelease(uint64_t release) { + DCHECK(sync_point_client_); + DCHECK(!sync_point_client_->client_state()->IsFenceSyncReleased(release)); + sync_point_client_->ReleaseFenceSync(release); +} + +bool GLManager::OnWaitFenceSync(gpu::CommandBufferNamespace namespace_id, + uint64_t command_buffer_id, + uint64_t release) { + DCHECK(sync_point_client_); + scoped_refptr<gpu::SyncPointClientState> release_state = + sync_point_manager_->GetSyncPointClientState(namespace_id, + command_buffer_id); + if (!release_state) + return true; + + // GLManager does not support being multithreaded at this point, so the fence + // sync must be released by the time wait is called. + DCHECK(release_state->IsFenceSyncReleased(release)); + return true; +} + void GLManager::MakeCurrent() { ::gles2::SetGLContext(gles2_implementation_.get()); } @@ -322,6 +369,12 @@ transfer_buffer_.reset(); gles2_helper_.reset(); command_buffer_.reset(); + sync_point_manager_ = nullptr; + sync_point_client_ = nullptr; + if (sync_point_order_data_) { + sync_point_order_data_->Destroy(); + sync_point_order_data_ = nullptr; + } if (decoder_.get()) { bool have_context = decoder_->GetGLContext() && decoder_->GetGLContext()->MakeCurrent(surface_.get()); @@ -340,11 +393,24 @@ command_buffer_->SetParseError(::gpu::error::kLostContext); return; } + uint32_t order_num = 0; + if (sync_point_manager_) { + // If sync point manager is supported, assign order numbers to commands. + order_num = sync_point_order_data_->GenerateUnprocessedOrderNumber( + sync_point_manager_); + sync_point_order_data_->BeginProcessingOrderNumber(order_num); + } + gpu_scheduler_->PutChanged(); ::gpu::CommandBuffer::State state = command_buffer_->GetLastState(); if (!context_lost_allowed_) { ASSERT_EQ(::gpu::error::kNoError, state.error); } + + if (sync_point_manager_) { + // Finish processing order number here. + sync_point_order_data_->FinishProcessingOrderNumber(order_num); + } } bool GLManager::GetBufferChanged(int32 transfer_buffer_id) { @@ -441,7 +507,19 @@ } uint64_t GLManager::GetCommandBufferID() const { - return 0; + return command_buffer_id_; +} + +uint64_t GLManager::GenerateFenceSyncRelease() { + return next_fence_sync_release_++; +} + +bool GLManager::IsFenceSyncRelease(uint64_t release) { + return release > 0 && release < next_fence_sync_release_; +} + +bool GLManager::IsFenceSyncFlushed(uint64_t release) { + return IsFenceSyncRelease(release); } } // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_manager.h b/gpu/command_buffer/tests/gl_manager.h index 16c8e298..901bae8 100644 --- a/gpu/command_buffer/tests/gl_manager.h +++ b/gpu/command_buffer/tests/gl_manager.h
@@ -30,6 +30,9 @@ class CommandBufferService; class GpuScheduler; +class SyncPointClient; +class SyncPointOrderData; +class SyncPointManager; class TransferBuffer; namespace gles2 { @@ -50,6 +53,8 @@ Options(); // The size of the backbuffer. gfx::Size size; + // If not null will have a corresponding sync point manager. + SyncPointManager* sync_point_manager; // If not null will share resources with this context. GLManager* share_group_manager; // If not null will share a mailbox manager with this context. @@ -127,12 +132,23 @@ bool IsGpuChannelLost() override; gpu::CommandBufferNamespace GetNamespaceID() const override; uint64_t GetCommandBufferID() const override; + uint64_t GenerateFenceSyncRelease() override; + bool IsFenceSyncRelease(uint64_t release) override; + bool IsFenceSyncFlushed(uint64_t release) override; private: void PumpCommands(); bool GetBufferChanged(int32 transfer_buffer_id); void SetupBaseContext(); + void OnFenceSyncRelease(uint64_t release); + bool OnWaitFenceSync(gpu::CommandBufferNamespace namespace_id, + uint64_t command_buffer_id, + uint64_t release); + SyncPointManager* sync_point_manager_; // Non-owning. + + scoped_refptr<SyncPointOrderData> sync_point_order_data_; + scoped_ptr<SyncPointClient> sync_point_client_; scoped_refptr<gles2::MailboxManager> mailbox_manager_; scoped_refptr<gfx::GLShareGroup> share_group_; scoped_ptr<CommandBufferService> command_buffer_; @@ -145,6 +161,9 @@ scoped_ptr<gles2::GLES2Implementation> gles2_implementation_; bool context_lost_allowed_; + const uint64_t command_buffer_id_; + uint64_t next_fence_sync_release_; + // Used on Android to virtualize GL for all contexts. static int use_count_; static scoped_refptr<gfx::GLShareGroup>* base_share_group_;
diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc index 546184d..3168fa9 100644 --- a/gpu/gles2_conform_support/egl/display.cc +++ b/gpu/gles2_conform_support/egl/display.cc
@@ -35,7 +35,8 @@ #endif create_offscreen_(false), create_offscreen_width_(0), - create_offscreen_height_(0) { + create_offscreen_height_(0), + next_fence_sync_release_(1) { } Display::~Display() { @@ -352,4 +353,16 @@ return 0; } +uint64_t Display::GenerateFenceSyncRelease() { + return next_fence_sync_release_++; +} + +bool Display::IsFenceSyncRelease(uint64_t release) { + return release > 0 && release < next_fence_sync_release_; +} + +bool Display::IsFenceSyncFlushed(uint64_t release) { + return IsFenceSyncRelease(release); +} + } // namespace egl
diff --git a/gpu/gles2_conform_support/egl/display.h b/gpu/gles2_conform_support/egl/display.h index 8954c2a97..a3c69ab 100644 --- a/gpu/gles2_conform_support/egl/display.h +++ b/gpu/gles2_conform_support/egl/display.h
@@ -100,6 +100,9 @@ bool IsGpuChannelLost() override; gpu::CommandBufferNamespace GetNamespaceID() const override; uint64_t GetCommandBufferID() const override; + uint64_t GenerateFenceSyncRelease() override; + bool IsFenceSyncRelease(uint64_t release) override; + bool IsFenceSyncFlushed(uint64_t release) override; private: EGLNativeDisplayType display_id_; @@ -116,6 +119,7 @@ bool create_offscreen_; int create_offscreen_width_; int create_offscreen_height_; + uint64_t next_fence_sync_release_; scoped_refptr<gpu::TransferBufferManagerInterface> transfer_buffer_manager_; scoped_ptr<gpu::CommandBufferService> command_buffer_;
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index 930153a..7a11c3cf 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp
@@ -142,6 +142,13 @@ 'sources': [ 'angle_unittest_main.cc', ], + 'conditions': [ + ['OS=="android"', { + 'dependencies': [ + '../testing/android/native_test.gyp:native_test_native_code', + ], + }], + ], }, { # GN version: //gpu:gpu_unittests @@ -244,6 +251,7 @@ 'command_buffer/service/shader_manager_unittest.cc', 'command_buffer/service/shader_translator_cache_unittest.cc', 'command_buffer/service/shader_translator_unittest.cc', + 'command_buffer/service/sync_point_manager_unittest.cc', 'command_buffer/service/test_helper.cc', 'command_buffer/service/test_helper.h', 'command_buffer/service/path_manager_unittest.cc', @@ -359,6 +367,7 @@ 'command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc', 'command_buffer/tests/gl_cube_map_texture_unittest.cc', 'command_buffer/tests/gl_depth_texture_unittest.cc', + 'command_buffer/tests/gl_fence_sync_unittest.cc', 'command_buffer/tests/gl_gpu_memory_buffer_unittest.cc', 'command_buffer/tests/gl_lose_context_chromium_unittest.cc', 'command_buffer/tests/gl_manager.cc', @@ -707,6 +716,19 @@ ['OS == "android"', { 'targets': [ { + 'target_name': 'angle_unittests_apk', + 'type': 'none', + 'dependencies': + [ + 'angle_unittests', + ], + 'variables': + { + 'test_suite_name': 'angle_unittests', + }, + 'includes': [ '../build/apk_test.gypi' ], + }, + { 'target_name': 'gl_tests_apk', 'type': 'none', 'dependencies': [
diff --git a/ios/chrome/browser/application_context.h b/ios/chrome/browser/application_context.h index 9cf30da..3efaa5c 100644 --- a/ios/chrome/browser/application_context.h +++ b/ios/chrome/browser/application_context.h
@@ -31,12 +31,17 @@ namespace policy { class BrowserPolicyConnector; +class PolicyService; } namespace rappor { class RapporService; } +namespace variations { +class VariationsService; +} + class ApplicationContext; class PrefService; @@ -48,6 +53,19 @@ ApplicationContext(); virtual ~ApplicationContext(); + // Invoked when application enters foreground. Cancels the effect of + // OnAppEnterBackground(), in particular removes the boolean preference + // indicating that the ChromeBrowserStates have been shutdown. + virtual void OnAppEnterForeground() = 0; + + // Invoked when application enters background. Saves any state that must be + // saved before shutdown can continue. + virtual void OnAppEnterBackground() = 0; + + // Returns whether the last complete shutdown was clean (i.e. happened while + // the application was backgrounded). + virtual bool WasLastShutdownClean() = 0; + // Gets the local state associated with this application. virtual PrefService* GetLocalState() = 0; @@ -63,9 +81,15 @@ // Gets the MetricsService used by this application. virtual metrics::MetricsService* GetMetricsService() = 0; + // Gets the VariationsService used by this application. + virtual variations::VariationsService* GetVariationsService() = 0; + // Gets the policy connector, creating and starting it if necessary. virtual policy::BrowserPolicyConnector* GetBrowserPolicyConnector() = 0; + // Gets the policy service. + virtual policy::PolicyService* GetPolicyService() = 0; + // Gets the RapporService. May return null. virtual rappor::RapporService* GetRapporService() = 0;
diff --git a/ios/chrome/browser/application_context_impl.cc b/ios/chrome/browser/application_context_impl.cc index 5946416fb..e86a64b 100644 --- a/ios/chrome/browser/application_context_impl.cc +++ b/ios/chrome/browser/application_context_impl.cc
@@ -4,19 +4,50 @@ #include "ios/chrome/browser/application_context_impl.h" +#include <algorithm> +#include <vector> + #include "base/command_line.h" #include "base/files/file_path.h" #include "base/logging.h" +#include "base/macros.h" +#include "base/path_service.h" +#include "base/prefs/pref_registry_simple.h" +#include "base/prefs/pref_service.h" #include "base/time/default_tick_clock.h" +#include "components/history/core/browser/history_service.h" +#include "components/keyed_service/core/service_access_type.h" +#include "components/metrics/metrics_pref_names.h" +#include "components/metrics/metrics_service.h" #include "components/net_log/chrome_net_log.h" #include "components/network_time/network_time_tracker.h" #include "components/translate/core/browser/translate_download_manager.h" +#include "components/variations/service/variations_service.h" +#include "ios/chrome/browser/chrome_paths.h" +#include "ios/chrome/browser/history/history_service_factory.h" +#include "ios/chrome/browser/pref_names.h" +#include "ios/chrome/browser/prefs/browser_prefs.h" +#include "ios/chrome/browser/prefs/ios_chrome_pref_service_factory.h" #include "ios/chrome/common/channel_info.h" +#include "ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/public/provider/chrome/browser/browser_state/chrome_browser_state_manager.h" #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" #include "net/log/net_log_capture_mode.h" +#include "net/socket/client_socket_pool_manager.h" + +#if defined(ENABLE_CONFIGURATION_POLICY) +#include "components/policy/core/browser/browser_policy_connector.h" +#include "components/policy/core/common/policy_service.h" +#else +#include "components/policy/core/common/policy_service_stub.h" +#endif ApplicationContextImpl::ApplicationContextImpl( - const base::CommandLine& command_line) { + base::SequencedTaskRunner* local_state_task_runner, + const base::CommandLine& command_line) + : local_state_task_runner_(local_state_task_runner), + was_last_shutdown_clean_(false), + created_local_state_(false) { DCHECK(!GetApplicationContext()); SetApplicationContext(this); @@ -30,9 +61,87 @@ SetApplicationContext(nullptr); } +// static +void ApplicationContextImpl::RegisterPrefs(PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(metrics::prefs::kMetricsReportingEnabled, + false); + registry->RegisterBooleanPref(prefs::kLastSessionExitedCleanly, true); + registry->RegisterBooleanPref(prefs::kMetricsReportingWifiOnly, true); +} + +void ApplicationContextImpl::SetApplicationLocale(const std::string& locale) { + DCHECK(thread_checker_.CalledOnValidThread()); + application_locale_ = locale; + translate::TranslateDownloadManager::GetInstance()->set_application_locale( + application_locale_); +} + +void ApplicationContextImpl::OnAppEnterForeground() { + DCHECK(thread_checker_.CalledOnValidThread()); + + PrefService* local_state = GetLocalState(); + local_state->SetBoolean(prefs::kLastSessionExitedCleanly, true); + + // Tell the metrics service that the application resumes. + metrics::MetricsService* metrics_service = GetMetricsService(); + if (metrics_service && local_state) { + metrics_service->OnAppEnterForeground(); + local_state->CommitPendingWrite(); + } + + variations::VariationsService* variations_service = GetVariationsService(); + if (variations_service) + variations_service->OnAppEnterForeground(); + + std::vector<ios::ChromeBrowserState*> loaded_browser_state = + GetChromeBrowserStateManager()->GetLoadedChromeBrowserStates(); + for (ios::ChromeBrowserState* browser_state : loaded_browser_state) { + browser_state->SetExitType(ios::ChromeBrowserState::EXIT_CRASHED); + } +} + +void ApplicationContextImpl::OnAppEnterBackground() { + DCHECK(thread_checker_.CalledOnValidThread()); + // Mark all the ChromeBrowserStates as clean and persist history. + std::vector<ios::ChromeBrowserState*> loaded_browser_state = + GetChromeBrowserStateManager()->GetLoadedChromeBrowserStates(); + for (ios::ChromeBrowserState* browser_state : loaded_browser_state) { + if (history::HistoryService* history_service = + ios::HistoryServiceFactory::GetForBrowserStateIfExists( + browser_state, ServiceAccessType::EXPLICIT_ACCESS)) { + history_service->HandleBackgrounding(); + } + + browser_state->SetExitType(ios::ChromeBrowserState::EXIT_NORMAL); + PrefService* browser_state_prefs = browser_state->GetPrefs(); + if (browser_state_prefs) + browser_state_prefs->CommitPendingWrite(); + } + + PrefService* local_state = GetLocalState(); + local_state->SetBoolean(prefs::kLastSessionExitedCleanly, true); + + // Tell the metrics service it was cleanly shutdown. + metrics::MetricsService* metrics_service = GetMetricsService(); + if (metrics_service && local_state) + metrics_service->OnAppEnterBackground(); + + // Persisting to disk is protected by a critical task, so no other special + // handling is necessary on iOS. +} + +bool ApplicationContextImpl::WasLastShutdownClean() { + DCHECK(thread_checker_.CalledOnValidThread()); + // Make sure the locale state is created as the file is initialized there. + ignore_result(GetLocalState()); + return was_last_shutdown_clean_; +} + PrefService* ApplicationContextImpl::GetLocalState() { DCHECK(thread_checker_.CalledOnValidThread()); - return ios::GetChromeBrowserProvider()->GetLocalState(); + if (!created_local_state_) + CreateLocalState(); + return local_state_.get(); } net::URLRequestContextGetter* @@ -47,13 +156,6 @@ return application_locale_; } -void ApplicationContextImpl::SetApplicationLocale(const std::string& locale) { - DCHECK(thread_checker_.CalledOnValidThread()); - application_locale_ = locale; - translate::TranslateDownloadManager::GetInstance()->set_application_locale( - application_locale_); -} - ios::ChromeBrowserStateManager* ApplicationContextImpl::GetChromeBrowserStateManager() { DCHECK(thread_checker_.CalledOnValidThread()); @@ -65,12 +167,28 @@ return ios::GetChromeBrowserProvider()->GetMetricsService(); } +variations::VariationsService* ApplicationContextImpl::GetVariationsService() { + DCHECK(thread_checker_.CalledOnValidThread()); + return ios::GetChromeBrowserProvider()->GetVariationsService(); +} + policy::BrowserPolicyConnector* ApplicationContextImpl::GetBrowserPolicyConnector() { DCHECK(thread_checker_.CalledOnValidThread()); return ios::GetChromeBrowserProvider()->GetBrowserPolicyConnector(); } +policy::PolicyService* ApplicationContextImpl::GetPolicyService() { + DCHECK(thread_checker_.CalledOnValidThread()); +#if defined(ENABLE_CONFIGURATION_POLICY) + return GetBrowserPolicyConnector()->GetPolicyService(); +#else + if (!policy_service_) + policy_service_.reset(new policy::PolicyServiceStub); + return policy_service_.get(); +#endif +} + rappor::RapporService* ApplicationContextImpl::GetRapporService() { DCHECK(thread_checker_.CalledOnValidThread()); return ios::GetChromeBrowserProvider()->GetRapporService(); @@ -90,3 +208,34 @@ } return network_time_tracker_.get(); } + +void ApplicationContextImpl::CreateLocalState() { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(!created_local_state_ && !local_state_); + created_local_state_ = true; + + base::FilePath local_state_path; + CHECK(PathService::Get(ios::FILE_LOCAL_STATE, &local_state_path)); + scoped_refptr<PrefRegistrySimple> pref_registry(new PrefRegistrySimple); + + // Register local state preferences. + RegisterLocalStatePrefs(pref_registry.get()); + + local_state_ = + ::CreateLocalState(local_state_path, local_state_task_runner_.get(), + GetPolicyService(), pref_registry, false); + + const int max_per_proxy = + local_state_->GetInteger(ios::prefs::kMaxConnectionsPerProxy); + net::ClientSocketPoolManager::set_max_sockets_per_proxy_server( + net::HttpNetworkSession::NORMAL_SOCKET_POOL, + std::max(std::min(max_per_proxy, 99), + net::ClientSocketPoolManager::max_sockets_per_group( + net::HttpNetworkSession::NORMAL_SOCKET_POOL))); + + // Register the shutdown state before anything changes it. + if (local_state_->HasPrefPath(prefs::kLastSessionExitedCleanly)) { + was_last_shutdown_clean_ = + local_state_->GetBoolean(prefs::kLastSessionExitedCleanly); + } +}
diff --git a/ios/chrome/browser/application_context_impl.h b/ios/chrome/browser/application_context_impl.h index 162954a..e02aace5 100644 --- a/ios/chrome/browser/application_context_impl.h +++ b/ios/chrome/browser/application_context_impl.h
@@ -8,39 +8,68 @@ #include <string> #include "base/macros.h" +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/threading/thread_checker.h" #include "ios/chrome/browser/application_context.h" +class PrefRegistrySimple; + namespace base { class CommandLine; +class SequencedTaskRunner; } class ApplicationContextImpl : public ApplicationContext { public: - ApplicationContextImpl(const base::CommandLine& command_line); + ApplicationContextImpl(base::SequencedTaskRunner* local_state_task_runner, + const base::CommandLine& command_line); ~ApplicationContextImpl() override; + // Registers local state prefs. + static void RegisterPrefs(PrefRegistrySimple* registry); + // Sets the locale used by the application. void SetApplicationLocale(const std::string& locale); private: // ApplicationContext implementation. + void OnAppEnterForeground() override; + void OnAppEnterBackground() override; + bool WasLastShutdownClean() override; PrefService* GetLocalState() override; net::URLRequestContextGetter* GetSystemURLRequestContext() override; const std::string& GetApplicationLocale() override; ios::ChromeBrowserStateManager* GetChromeBrowserStateManager() override; metrics::MetricsService* GetMetricsService() override; + variations::VariationsService* GetVariationsService() override; policy::BrowserPolicyConnector* GetBrowserPolicyConnector() override; + policy::PolicyService* GetPolicyService() override; rappor::RapporService* GetRapporService() override; net_log::ChromeNetLog* GetNetLog() override; network_time::NetworkTimeTracker* GetNetworkTimeTracker() override; + void CreateLocalState(); + base::ThreadChecker thread_checker_; + scoped_ptr<PrefService> local_state_; scoped_ptr<net_log::ChromeNetLog> net_log_; scoped_ptr<network_time::NetworkTimeTracker> network_time_tracker_; std::string application_locale_; +#if !defined(ENABLE_CONFIGURATION_POLICY) + // Must be destroyed after |local_state_|. + // This is a stub when policy is not enabled. Otherwise the PolicyService is + // owned by the BrowserPolicyConnector and this is not used. + scoped_ptr<policy::PolicyService> policy_service_; +#endif + + // Sequenced task runner for local state related I/O tasks. + const scoped_refptr<base::SequencedTaskRunner> local_state_task_runner_; + + bool was_last_shutdown_clean_; + bool created_local_state_; + DISALLOW_COPY_AND_ASSIGN(ApplicationContextImpl); };
diff --git a/ios/chrome/browser/chrome_paths.h b/ios/chrome/browser/chrome_paths.h index 1084da48..77a9122 100644 --- a/ios/chrome/browser/chrome_paths.h +++ b/ios/chrome/browser/chrome_paths.h
@@ -17,6 +17,9 @@ DIR_CRASH_DUMPS, // Directory where crash dumps are written. DIR_TEST_DATA, // Directory where unit test data resides. + FILE_LOCAL_STATE, // Path and filename to the file in which + // installation-specific state is saved. + PATH_END };
diff --git a/ios/chrome/browser/chrome_paths.mm b/ios/chrome/browser/chrome_paths.mm index 955df2a..0a86fb5 100644 --- a/ios/chrome/browser/chrome_paths.mm +++ b/ios/chrome/browser/chrome_paths.mm
@@ -60,14 +60,18 @@ cur = cur.Append(FILE_PATH_LITERAL("data")); break; + case FILE_LOCAL_STATE: + if (!PathService::Get(ios::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("Local State")); + break; + default: return false; } - if (!base::PathExists(cur)) { - if (!create_dir || !base::CreateDirectory(cur)) - return false; - } + if (create_dir && !base::PathExists(cur) && !base::CreateDirectory(cur)) + return false; *result = cur; return true;
diff --git a/ios/chrome/browser/pref_names.cc b/ios/chrome/browser/pref_names.cc index c6b9a17f..db97805bb 100644 --- a/ios/chrome/browser/pref_names.cc +++ b/ios/chrome/browser/pref_names.cc
@@ -19,6 +19,7 @@ const char kDefaultCharset[] = "intl.charset_default"; const char kEnableDoNotTrack[] = "enable_do_not_track"; const char kHttpServerProperties[] = "net.http_server_properties"; +const char kMaxConnectionsPerProxy[] = "net.max_connections_per_proxy"; const char kSavingBrowserHistoryDisabled[] = "history.saving_disabled"; const char kSearchSuggestEnabled[] = "search.suggest_enabled"; @@ -43,6 +44,11 @@ // the bookmark promo dialog. const char kIosBookmarkPromoAlreadySeen[] = "ios.bookmark.promo_already_seen"; +// Boolean which indicates whether browsing data migration is/was possible in +// this or a previous cold start. +const char kBrowsingDataMigrationHasBeenPossible[] = + "ios.browsing_data_migration_controller.migration_has_been_possible"; + // Boolean which indicates if the user has already set a "do not backup" bit to // the OTR Profiles's state stash path to ensure that the folder is not // automatically synced to iCloud/iTunes.
diff --git a/ios/chrome/browser/pref_names.h b/ios/chrome/browser/pref_names.h index 16e8f97..ec1bd38 100644 --- a/ios/chrome/browser/pref_names.h +++ b/ios/chrome/browser/pref_names.h
@@ -17,6 +17,7 @@ extern const char kDefaultCharset[]; extern const char kEnableDoNotTrack[]; extern const char kHttpServerProperties[]; +extern const char kMaxConnectionsPerProxy[]; extern const char kSavingBrowserHistoryDisabled[]; extern const char kSearchSuggestEnabled[]; @@ -28,6 +29,7 @@ extern const char kContextualSearchEnabled[]; extern const char kIosBookmarkFolderDefault[]; extern const char kIosBookmarkPromoAlreadySeen[]; +extern const char kBrowsingDataMigrationHasBeenPossible[]; extern const char kOTRStashStatePathSystemBackupExcluded[]; extern const char kIosHandoffToOtherDevices[]; extern const char kLastSessionExitedCleanly[];
diff --git a/ios/chrome/browser/prefs/browser_prefs.cc b/ios/chrome/browser/prefs/browser_prefs.mm similarity index 89% rename from ios/chrome/browser/prefs/browser_prefs.cc rename to ios/chrome/browser/prefs/browser_prefs.mm index 1dfd220..c74ce0e 100644 --- a/ios/chrome/browser/prefs/browser_prefs.cc +++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -22,7 +22,10 @@ #include "components/translate/core/common/translate_pref_names.h" #include "components/variations/service/variations_service.h" #include "components/web_resource/promo_resource_service.h" +#include "ios/chrome/browser/application_context_impl.h" #include "ios/chrome/browser/first_run/first_run.h" +#import "ios/chrome/browser/geolocation/omnibox_geolocation_local_state.h" +#import "ios/chrome/browser/memory/memory_debugger_manager.h" #include "ios/chrome/browser/net/http_server_properties_manager_factory.h" #include "ios/chrome/browser/pref_names.h" #include "ios/chrome/browser/signin/signin_manager_factory.h" @@ -66,6 +69,18 @@ registry->RegisterIntegerPref(ios::prefs::kBrowserStatesNumCreated, 1); registry->RegisterListPref(ios::prefs::kBrowserStatesLastActive); + [OmniboxGeolocationLocalState registerLocalState:registry]; + [MemoryDebuggerManager registerLocalState:registry]; + + // TODO(shreyasv): Remove this in M49 as almost all users would have the + // "do not backup" bit set by then. crbug.com/489865. + registry->RegisterBooleanPref(prefs::kOTRStashStatePathSystemBackupExcluded, + false); + registry->RegisterBooleanPref(prefs::kBrowsingDataMigrationHasBeenPossible, + false); + + ApplicationContextImpl::RegisterPrefs(registry); + ios::GetChromeBrowserProvider()->RegisterLocalState(registry); }
diff --git a/ios/chrome/ios_chrome.gyp b/ios/chrome/ios_chrome.gyp index ddba590..7756f92 100644 --- a/ios/chrome/ios_chrome.gyp +++ b/ios/chrome/ios_chrome.gyp
@@ -321,8 +321,8 @@ 'browser/passwords/password_generation_utils.mm', 'browser/pref_names.cc', 'browser/pref_names.h', - 'browser/prefs/browser_prefs.cc', 'browser/prefs/browser_prefs.h', + 'browser/prefs/browser_prefs.mm', 'browser/prefs/ios_chrome_pref_model_associator_client.cc', 'browser/prefs/ios_chrome_pref_model_associator_client.h', 'browser/prefs/ios_chrome_pref_service_factory.cc',
diff --git a/ios/chrome/test/testing_application_context.cc b/ios/chrome/test/testing_application_context.cc index 014a913..62b2c255 100644 --- a/ios/chrome/test/testing_application_context.cc +++ b/ios/chrome/test/testing_application_context.cc
@@ -12,7 +12,8 @@ TestingApplicationContext::TestingApplicationContext() : application_locale_("en"), local_state_(nullptr), - chrome_browser_state_manager_(nullptr) { + chrome_browser_state_manager_(nullptr), + was_last_shutdown_clean_(false) { DCHECK(!GetApplicationContext()); SetApplicationContext(this); } @@ -22,19 +23,37 @@ SetApplicationContext(nullptr); } +// static +TestingApplicationContext* TestingApplicationContext::GetGlobal() { + return static_cast<TestingApplicationContext*>(GetApplicationContext()); +} + void TestingApplicationContext::SetLocalState(PrefService* local_state) { DCHECK(thread_checker_.CalledOnValidThread()); local_state_ = local_state; } +void TestingApplicationContext::SetLastShutdownClean(bool clean) { + was_last_shutdown_clean_ = clean; +} + void TestingApplicationContext::SetChromeBrowserStateManager( ios::ChromeBrowserStateManager* manager) { + DCHECK(thread_checker_.CalledOnValidThread()); chrome_browser_state_manager_ = manager; } -// static -TestingApplicationContext* TestingApplicationContext::GetGlobal() { - return static_cast<TestingApplicationContext*>(GetApplicationContext()); +void TestingApplicationContext::OnAppEnterForeground() { + DCHECK(thread_checker_.CalledOnValidThread()); +} + +void TestingApplicationContext::OnAppEnterBackground() { + DCHECK(thread_checker_.CalledOnValidThread()); +} + +bool TestingApplicationContext::WasLastShutdownClean() { + DCHECK(thread_checker_.CalledOnValidThread()); + return was_last_shutdown_clean_; } PrefService* TestingApplicationContext::GetLocalState() { @@ -65,12 +84,23 @@ return nullptr; } +variations::VariationsService* +TestingApplicationContext::GetVariationsService() { + DCHECK(thread_checker_.CalledOnValidThread()); + return nullptr; +} + policy::BrowserPolicyConnector* TestingApplicationContext::GetBrowserPolicyConnector() { DCHECK(thread_checker_.CalledOnValidThread()); return nullptr; } +policy::PolicyService* TestingApplicationContext::GetPolicyService() { + DCHECK(thread_checker_.CalledOnValidThread()); + return nullptr; +} + rappor::RapporService* TestingApplicationContext::GetRapporService() { DCHECK(thread_checker_.CalledOnValidThread()); return nullptr;
diff --git a/ios/chrome/test/testing_application_context.h b/ios/chrome/test/testing_application_context.h index 0c073c3..8025c45 100644 --- a/ios/chrome/test/testing_application_context.h +++ b/ios/chrome/test/testing_application_context.h
@@ -22,16 +22,24 @@ // Sets the local state. void SetLocalState(PrefService* local_state); + // Sets the last shutdown "clean" state. + void SetLastShutdownClean(bool clean); + // Sets the ChromeBrowserStateManager. void SetChromeBrowserStateManager(ios::ChromeBrowserStateManager* manager); // ApplicationContext implementation. + void OnAppEnterForeground() override; + void OnAppEnterBackground() override; + bool WasLastShutdownClean() override; PrefService* GetLocalState() override; net::URLRequestContextGetter* GetSystemURLRequestContext() override; const std::string& GetApplicationLocale() override; ios::ChromeBrowserStateManager* GetChromeBrowserStateManager() override; metrics::MetricsService* GetMetricsService() override; + variations::VariationsService* GetVariationsService() override; policy::BrowserPolicyConnector* GetBrowserPolicyConnector() override; + policy::PolicyService* GetPolicyService() override; rappor::RapporService* GetRapporService() override; net_log::ChromeNetLog* GetNetLog() override; network_time::NetworkTimeTracker* GetNetworkTimeTracker() override; @@ -42,6 +50,7 @@ PrefService* local_state_; ios::ChromeBrowserStateManager* chrome_browser_state_manager_; scoped_ptr<network_time::NetworkTimeTracker> network_time_tracker_; + bool was_last_shutdown_clean_; DISALLOW_COPY_AND_ASSIGN(TestingApplicationContext); };
diff --git a/ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h b/ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h index 36e7f54e..beeb810 100644 --- a/ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h +++ b/ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h
@@ -29,6 +29,11 @@ // This class is a Chrome-specific extension of the BrowserState interface. class ChromeBrowserState : public web::BrowserState { public: + enum ExitType { + EXIT_NORMAL, + EXIT_CRASHED, + }; + ~ChromeBrowserState() override {} // Returns the ChromeBrowserState corresponding to the given BrowserState. @@ -68,6 +73,18 @@ // a syncable_prefs::PrefServiceSyncable. virtual syncable_prefs::PrefServiceSyncable* GetSyncablePrefs() = 0; + // Sets the ExitType for the ChromeBrowserState. This may be invoked multiple + // times during shutdown; only the first such change (the transition from + // EXIT_CRASHED to one of the other values) is written to prefs, any later + // calls are ignored. + // + // NOTE: this is invoked internally on a normal shutdown, but is public so + // that it can be invoked to handle backgrounding/foregrounding. + virtual void SetExitType(ExitType exit_type) = 0; + + // Returns how the last session was shutdown. + virtual ExitType GetLastSessionExitType() = 0; + protected: ChromeBrowserState() {}
diff --git a/ios/public/provider/chrome/browser/chrome_browser_provider.cc b/ios/public/provider/chrome/browser/chrome_browser_provider.cc index ba82d852e..b683726 100644 --- a/ios/public/provider/chrome/browser/chrome_browser_provider.cc +++ b/ios/public/provider/chrome/browser/chrome_browser_provider.cc
@@ -33,10 +33,6 @@ return nullptr; } -PrefService* ChromeBrowserProvider::GetLocalState() { - return nullptr; -} - void ChromeBrowserProvider::AssertBrowserContextKeyedFactoriesBuilt() { } @@ -97,6 +93,10 @@ return nullptr; } +variations::VariationsService* ChromeBrowserProvider::GetVariationsService() { + return nullptr; +} + autofill::CardUnmaskPromptView* ChromeBrowserProvider::CreateCardUnmaskPromptView( autofill::CardUnmaskPromptController* controller) {
diff --git a/ios/public/provider/chrome/browser/chrome_browser_provider.h b/ios/public/provider/chrome/browser/chrome_browser_provider.h index fa6ae72..8105253 100644 --- a/ios/public/provider/chrome/browser/chrome_browser_provider.h +++ b/ios/public/provider/chrome/browser/chrome_browser_provider.h
@@ -39,6 +39,10 @@ class PrefRegistrySyncable; } +namespace variations { +class VariationsService; +} + // TODO(ios): Determine the best way to interface with Obj-C code through // the ChromeBrowserProvider. crbug/298181 #ifdef __OBJC__ @@ -75,8 +79,6 @@ // Gets the system URL request context. virtual net::URLRequestContextGetter* GetSystemURLRequestContext(); - // Gets the local state. - virtual PrefService* GetLocalState(); // Asserts all iOS-specific |BrowserContextKeyedServiceFactory| are built. virtual void AssertBrowserContextKeyedFactoriesBuilt(); // Registers all prefs that will be used via the local state PrefService. @@ -110,6 +112,8 @@ virtual void SetUIViewAlphaWithAnimation(UIView* view, float alpha); // Returns the metrics service. virtual metrics::MetricsService* GetMetricsService(); + // Returns the variations service. + virtual variations::VariationsService* GetVariationsService(); // Returns an instance of a CardUnmaskPromptView used to unmask Wallet cards. // The view is responsible for its own lifetime. virtual autofill::CardUnmaskPromptView* CreateCardUnmaskPromptView(
diff --git a/ipc/attachment_broker.h b/ipc/attachment_broker.h index 577d762..3f7a98c 100644 --- a/ipc/attachment_broker.h +++ b/ipc/attachment_broker.h
@@ -63,7 +63,7 @@ // IPC::Channel to communicate with the broker process. This may be the same // IPC::Channel that is requesting the brokering of an attachment. // Returns true on success and false otherwise. - virtual bool SendAttachmentToProcess(const BrokerableAttachment* attachment, + virtual bool SendAttachmentToProcess(BrokerableAttachment* attachment, base::ProcessId destination_process) = 0; // Returns whether the attachment was available. If the attachment was
diff --git a/ipc/attachment_broker_privileged_mac.cc b/ipc/attachment_broker_privileged_mac.cc index 7399326..0fbf2c4 100644 --- a/ipc/attachment_broker_privileged_mac.cc +++ b/ipc/attachment_broker_privileged_mac.cc
@@ -64,7 +64,7 @@ } bool AttachmentBrokerPrivilegedMac::SendAttachmentToProcess( - const BrokerableAttachment* attachment, + BrokerableAttachment* attachment, base::ProcessId destination_process) { switch (attachment->GetBrokerableType()) { case BrokerableAttachment::MACH_PORT: {
diff --git a/ipc/attachment_broker_privileged_mac.h b/ipc/attachment_broker_privileged_mac.h index 24c8b0c..bf0418a 100644 --- a/ipc/attachment_broker_privileged_mac.h +++ b/ipc/attachment_broker_privileged_mac.h
@@ -29,7 +29,7 @@ void SetPortProvider(base::PortProvider* port_provider); // IPC::AttachmentBroker overrides. - bool SendAttachmentToProcess(const BrokerableAttachment* attachment, + bool SendAttachmentToProcess(BrokerableAttachment* attachment, base::ProcessId destination_process) override; // IPC::Listener overrides.
diff --git a/ipc/attachment_broker_privileged_win.cc b/ipc/attachment_broker_privileged_win.cc index 6f3bc41..a638752f 100644 --- a/ipc/attachment_broker_privileged_win.cc +++ b/ipc/attachment_broker_privileged_win.cc
@@ -19,7 +19,7 @@ AttachmentBrokerPrivilegedWin::~AttachmentBrokerPrivilegedWin() {} bool AttachmentBrokerPrivilegedWin::SendAttachmentToProcess( - const BrokerableAttachment* attachment, + BrokerableAttachment* attachment, base::ProcessId destination_process) { switch (attachment->GetBrokerableType()) { case BrokerableAttachment::WIN_HANDLE: {
diff --git a/ipc/attachment_broker_privileged_win.h b/ipc/attachment_broker_privileged_win.h index e986a7b..f40ccf5 100644 --- a/ipc/attachment_broker_privileged_win.h +++ b/ipc/attachment_broker_privileged_win.h
@@ -20,7 +20,7 @@ ~AttachmentBrokerPrivilegedWin() override; // IPC::AttachmentBroker overrides. - bool SendAttachmentToProcess(const BrokerableAttachment* attachment, + bool SendAttachmentToProcess(BrokerableAttachment* attachment, base::ProcessId destination_process) override; // IPC::Listener overrides.
diff --git a/ipc/attachment_broker_privileged_win_unittest.cc b/ipc/attachment_broker_privileged_win_unittest.cc index 25cadcb6..02ef930 100644 --- a/ipc/attachment_broker_privileged_win_unittest.cc +++ b/ipc/attachment_broker_privileged_win_unittest.cc
@@ -277,7 +277,7 @@ public: MockBroker() {} ~MockBroker() override {} - bool SendAttachmentToProcess(const IPC::BrokerableAttachment* attachment, + bool SendAttachmentToProcess(IPC::BrokerableAttachment* attachment, base::ProcessId destination_process) override { return IPC::AttachmentBrokerUnprivilegedWin::SendAttachmentToProcess( attachment, base::Process::Current().Pid());
diff --git a/ipc/attachment_broker_unprivileged_mac.cc b/ipc/attachment_broker_unprivileged_mac.cc index b4ced08..65d26f2 100644 --- a/ipc/attachment_broker_unprivileged_mac.cc +++ b/ipc/attachment_broker_unprivileged_mac.cc
@@ -50,16 +50,19 @@ AttachmentBrokerUnprivilegedMac::~AttachmentBrokerUnprivilegedMac() {} bool AttachmentBrokerUnprivilegedMac::SendAttachmentToProcess( - const BrokerableAttachment* attachment, + BrokerableAttachment* attachment, base::ProcessId destination_process) { switch (attachment->GetBrokerableType()) { case BrokerableAttachment::MACH_PORT: { - const internal::MachPortAttachmentMac* mach_port_attachment = - static_cast<const internal::MachPortAttachmentMac*>(attachment); + internal::MachPortAttachmentMac* mach_port_attachment = + static_cast<internal::MachPortAttachmentMac*>(attachment); internal::MachPortAttachmentMac::WireFormat format = mach_port_attachment->GetWireFormat(destination_process); - return get_sender()->Send( - new AttachmentBrokerMsg_DuplicateMachPort(format)); + bool success = + get_sender()->Send(new AttachmentBrokerMsg_DuplicateMachPort(format)); + if (success) + mach_port_attachment->reset_mach_port_ownership(); + return success; } default: NOTREACHED();
diff --git a/ipc/attachment_broker_unprivileged_mac.h b/ipc/attachment_broker_unprivileged_mac.h index 58c4f87..26cf443 100644 --- a/ipc/attachment_broker_unprivileged_mac.h +++ b/ipc/attachment_broker_unprivileged_mac.h
@@ -22,7 +22,7 @@ ~AttachmentBrokerUnprivilegedMac() override; // IPC::AttachmentBroker overrides. - bool SendAttachmentToProcess(const BrokerableAttachment* attachment, + bool SendAttachmentToProcess(BrokerableAttachment* attachment, base::ProcessId destination_process) override; // IPC::Listener overrides.
diff --git a/ipc/attachment_broker_unprivileged_win.cc b/ipc/attachment_broker_unprivileged_win.cc index 1151f53..e1d9941 100644 --- a/ipc/attachment_broker_unprivileged_win.cc +++ b/ipc/attachment_broker_unprivileged_win.cc
@@ -17,7 +17,7 @@ AttachmentBrokerUnprivilegedWin::~AttachmentBrokerUnprivilegedWin() {} bool AttachmentBrokerUnprivilegedWin::SendAttachmentToProcess( - const BrokerableAttachment* attachment, + BrokerableAttachment* attachment, base::ProcessId destination_process) { switch (attachment->GetBrokerableType()) { case BrokerableAttachment::WIN_HANDLE: {
diff --git a/ipc/attachment_broker_unprivileged_win.h b/ipc/attachment_broker_unprivileged_win.h index c3d29092..bcb1500a7 100644 --- a/ipc/attachment_broker_unprivileged_win.h +++ b/ipc/attachment_broker_unprivileged_win.h
@@ -22,7 +22,7 @@ ~AttachmentBrokerUnprivilegedWin() override; // IPC::AttachmentBroker overrides. - bool SendAttachmentToProcess(const BrokerableAttachment* attachment, + bool SendAttachmentToProcess(BrokerableAttachment* attachment, base::ProcessId destination_process) override; // IPC::Listener overrides.
diff --git a/ipc/ipc_channel_posix.cc b/ipc/ipc_channel_posix.cc index b9ab794..abe2f98 100644 --- a/ipc/ipc_channel_posix.cc +++ b/ipc/ipc_channel_posix.cc
@@ -697,8 +697,8 @@ if (message->HasBrokerableAttachments()) { DCHECK(GetAttachmentBroker()); DCHECK(peer_pid_ != base::kNullProcessId); - for (const BrokerableAttachment* attachment : - message->attachment_set()->PeekBrokerableAttachments()) { + for (BrokerableAttachment* attachment : + message->attachment_set()->GetBrokerableAttachments()) { if (!GetAttachmentBroker()->SendAttachmentToProcess(attachment, peer_pid_)) { delete message;
diff --git a/ipc/ipc_channel_reader.cc b/ipc/ipc_channel_reader.cc index 5ca0e46..326c6d7e 100644 --- a/ipc/ipc_channel_reader.cc +++ b/ipc/ipc_channel_reader.cc
@@ -213,8 +213,8 @@ #if USE_ATTACHMENT_BROKER MessageAttachmentSet* set = msg->attachment_set(); - std::vector<const BrokerableAttachment*> brokerable_attachments_copy = - set->PeekBrokerableAttachments(); + std::vector<BrokerableAttachment*> brokerable_attachments_copy = + set->GetBrokerableAttachments(); for (const BrokerableAttachment* attachment : brokerable_attachments_copy) { if (attachment->NeedsBrokering()) { AttachmentBroker* broker = GetAttachmentBroker();
diff --git a/ipc/ipc_channel_reader_unittest.cc b/ipc/ipc_channel_reader_unittest.cc index 7728a817..c528996b 100644 --- a/ipc/ipc_channel_reader_unittest.cc +++ b/ipc/ipc_channel_reader_unittest.cc
@@ -42,7 +42,7 @@ public: typedef std::set<scoped_refptr<BrokerableAttachment>> AttachmentSet; - bool SendAttachmentToProcess(const BrokerableAttachment* attachment, + bool SendAttachmentToProcess(BrokerableAttachment* attachment, base::ProcessId destination_process) override { return false; }
diff --git a/ipc/ipc_channel_win.cc b/ipc/ipc_channel_win.cc index c04f0c6..d4640f4 100644 --- a/ipc/ipc_channel_win.cc +++ b/ipc/ipc_channel_win.cc
@@ -108,8 +108,8 @@ if (message->HasBrokerableAttachments()) { DCHECK(GetAttachmentBroker()); DCHECK(peer_pid_ != base::kNullProcessId); - for (const BrokerableAttachment* attachment : - message->attachment_set()->PeekBrokerableAttachments()) { + for (BrokerableAttachment* attachment : + message->attachment_set()->GetBrokerableAttachments()) { if (!GetAttachmentBroker()->SendAttachmentToProcess(attachment, peer_pid_)) { delete message;
diff --git a/ipc/ipc_message.cc b/ipc/ipc_message.cc index df28464e..684c11b 100644 --- a/ipc/ipc_message.cc +++ b/ipc/ipc_message.cc
@@ -144,8 +144,8 @@ Message::SerializedAttachmentIds Message::SerializedIdsOfBrokerableAttachments() { DCHECK(HasBrokerableAttachments()); - std::vector<const BrokerableAttachment*> attachments = - attachment_set_->PeekBrokerableAttachments(); + std::vector<BrokerableAttachment*> attachments = + attachment_set_->GetBrokerableAttachments(); CHECK_LE(attachments.size(), std::numeric_limits<size_t>::max() / BrokerableAttachment::kNonceSize); size_t size = attachments.size() * BrokerableAttachment::kNonceSize;
diff --git a/ipc/ipc_message_attachment_set.cc b/ipc/ipc_message_attachment_set.cc index 6a8024f..faf6462 100644 --- a/ipc/ipc_message_attachment_set.cc +++ b/ipc/ipc_message_attachment_set.cc
@@ -131,9 +131,9 @@ consumed_descriptor_highwater_ = 0; } -std::vector<const BrokerableAttachment*> -MessageAttachmentSet::PeekBrokerableAttachments() const { - std::vector<const BrokerableAttachment*> output; +std::vector<BrokerableAttachment*> +MessageAttachmentSet::GetBrokerableAttachments() const { + std::vector<BrokerableAttachment*> output; for (const scoped_refptr<MessageAttachment>& attachment : attachments_) { if (attachment->GetType() == MessageAttachment::TYPE_BROKERABLE_ATTACHMENT) {
diff --git a/ipc/ipc_message_attachment_set.h b/ipc/ipc_message_attachment_set.h index 4707a50..0ed62ac 100644 --- a/ipc/ipc_message_attachment_set.h +++ b/ipc/ipc_message_attachment_set.h
@@ -59,7 +59,7 @@ void CommitAll(); // Returns a vector of all brokerable attachments. - std::vector<const BrokerableAttachment*> PeekBrokerableAttachments() const; + std::vector<BrokerableAttachment*> GetBrokerableAttachments() const; // Replaces a placeholder brokerable attachment with |attachment|, matching // them by their id.
diff --git a/ipc/mach_port_attachment_mac.cc b/ipc/mach_port_attachment_mac.cc index 2a0cfa44..5aec8fcd 100644 --- a/ipc/mach_port_attachment_mac.cc +++ b/ipc/mach_port_attachment_mac.cc
@@ -4,21 +4,40 @@ #include "ipc/mach_port_attachment_mac.h" +#include "base/mac/mach_logging.h" + namespace IPC { namespace internal { MachPortAttachmentMac::MachPortAttachmentMac(mach_port_t mach_port) - : mach_port_(mach_port) {} + : mach_port_(mach_port), owns_mach_port_(true) { + if (mach_port != MACH_PORT_NULL) { + kern_return_t kr = mach_port_mod_refs(mach_task_self(), mach_port, + MACH_PORT_RIGHT_SEND, 1); + MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) + << "MachPortAttachmentMac mach_port_mod_refs"; + } +} MachPortAttachmentMac::MachPortAttachmentMac(const WireFormat& wire_format) : BrokerableAttachment(wire_format.attachment_id), - mach_port_(static_cast<mach_port_t>(wire_format.mach_port)) {} + mach_port_(static_cast<mach_port_t>(wire_format.mach_port)), + owns_mach_port_(false) {} MachPortAttachmentMac::MachPortAttachmentMac( const BrokerableAttachment::AttachmentId& id) - : BrokerableAttachment(id), mach_port_(MACH_PORT_NULL) {} + : BrokerableAttachment(id), + mach_port_(MACH_PORT_NULL), + owns_mach_port_(false) {} -MachPortAttachmentMac::~MachPortAttachmentMac() {} +MachPortAttachmentMac::~MachPortAttachmentMac() { + if (mach_port_ != MACH_PORT_NULL && owns_mach_port_) { + kern_return_t kr = mach_port_mod_refs(mach_task_self(), mach_port_, + MACH_PORT_RIGHT_SEND, -1); + MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) + << "~MachPortAttachmentMac mach_port_mod_refs"; + } +} MachPortAttachmentMac::BrokerableType MachPortAttachmentMac::GetBrokerableType() const {
diff --git a/ipc/mach_port_attachment_mac.h b/ipc/mach_port_attachment_mac.h index efe93c4..48dc9aa 100644 --- a/ipc/mach_port_attachment_mac.h +++ b/ipc/mach_port_attachment_mac.h
@@ -45,7 +45,13 @@ AttachmentId attachment_id; }; + // This constructor increments the ref count of |mach_port_| and takes + // ownership of the result. Should only be called by the sender of a Chrome + // IPC message. explicit MachPortAttachmentMac(mach_port_t mach_port); + + // These constructors do not take ownership of |mach_port|, and should only be + // called by the receiver of a Chrome IPC message. explicit MachPortAttachmentMac(const WireFormat& wire_format); explicit MachPortAttachmentMac(const BrokerableAttachment::AttachmentId& id); @@ -56,9 +62,21 @@ mach_port_t get_mach_port() const { return mach_port_; } + // The caller of this method has taken ownership of |mach_port_|. + void reset_mach_port_ownership() { owns_mach_port_ = false; } + private: ~MachPortAttachmentMac() override; mach_port_t mach_port_; + + // In the sender process, the attachment owns the Mach port of a newly created + // message. The attachment broker will eventually take ownership, and set + // this member to |false|. + // In the destination process, the attachment never owns the Mach port. The + // client code that receives the Chrome IPC message is always expected to take + // ownership. + bool owns_mach_port_; + DISALLOW_COPY_AND_ASSIGN(MachPortAttachmentMac); }; } // namespace internal
diff --git a/ipc/mach_port_mac.h b/ipc/mach_port_mac.h index 0193f9da..199147c 100644 --- a/ipc/mach_port_mac.h +++ b/ipc/mach_port_mac.h
@@ -7,24 +7,65 @@ #include <mach/mach.h> +#include "base/macros.h" #include "ipc/ipc_export.h" #include "ipc/ipc_message_macros.h" namespace IPC { -// MachPortMac is a wrapper around an OSX mach_port_t that can be transported -// across Chrome IPC channels that support attachment brokering. The mach_port_t -// will be duplicated into the destination process by the attachment broker. +// MachPortMac is a wrapper around an OSX Mach port that can be transported +// across Chrome IPC channels that support attachment brokering. The send right +// to the Mach port will be duplicated into the destination process by the +// attachment broker. If needed, attachment brokering can be trivially extended +// to support duplication of other types of rights. class IPC_EXPORT MachPortMac { public: MachPortMac() : mach_port_(MACH_PORT_NULL) {} - explicit MachPortMac(const mach_port_t& mach_port) : mach_port_(mach_port) {} + + explicit MachPortMac(mach_port_t mach_port) {}; mach_port_t get_mach_port() const { return mach_port_; } + + // This method should only be used by ipc/ translation code. void set_mach_port(mach_port_t mach_port) { mach_port_ = mach_port; } private: + // The ownership semantics of |mach_port_| cannot be easily expressed with a + // C++ scoped object. This is partly due to the mechanism by which Mach ports + // are brokered, and partly due to the architecture of Chrome IPC. + // + // The broker for Mach ports may live in a different process than the sender + // of the original Chrome IPC. In this case, it is signalled asynchronously, + // and ownership of the Mach port passes from the sender process into the + // broker process. + // + // Chrome IPC is written with the assumption that translation is a stateless + // process. There is no good mechanism to convey the semantics of ownership + // transfer from the Chrome IPC stack into the client code that receives the + // translated message. As a result, Chrome IPC code assumes that every message + // has a handler, and that the handler will take ownership of the Mach port. + // Note that the same holds true for POSIX fds and Windows HANDLEs. + // + // When used by client code in the sender process, this class is just a + // wrapper. The client code calls Send(new Message(MachPortMac(mach_port))) + // and continues on its merry way. Behind the scenes, a MachPortAttachmentMac + // takes ownership of the Mach port. When the attachment broker sends the name + // of the Mach port to the broker process, it also releases + // MachPortAttachmentMac's reference to the Mach port, as ownership has + // effectively been transferred to the broker process. + // + // The broker process receives the name, duplicates the Mach port into the + // destination process, and then decrements the ref count in the original + // process. + // + // In the destination process, the attachment broker is responsible for + // coupling the Mach port (inserted by the broker process) with Chrome IPC in + // the form of a MachPortAttachmentMac. Due to the Chrome IPC translation + // semantics discussed above, this MachPortAttachmentMac does not take + // ownership of the Mach port, and assumes that the client code which receives + // the callback will take ownership of the Mach port. mach_port_t mach_port_; + DISALLOW_COPY_AND_ASSIGN(MachPortMac); }; template <>
diff --git a/media/base/android/audio_decoder_job.cc b/media/base/android/audio_decoder_job.cc index e532103..4ef622a 100644 --- a/media/base/android/audio_decoder_job.cc +++ b/media/base/android/audio_decoder_job.cc
@@ -8,7 +8,6 @@ #include "base/lazy_instance.h" #include "base/threading/thread.h" #include "media/base/android/media_codec_bridge.h" -#include "media/base/android/media_statistics.h" #include "media/base/audio_timestamp_helper.h" #include "media/base/timestamp_constants.h" @@ -36,12 +35,10 @@ AudioDecoderJob::AudioDecoderJob( const base::Closure& request_data_cb, - const base::Closure& on_demuxer_config_changed_cb, - FrameStatistics* frame_statistics) + const base::Closure& on_demuxer_config_changed_cb) : MediaDecoderJob(g_audio_decoder_thread.Pointer()->task_runner(), request_data_cb, - on_demuxer_config_changed_cb, - frame_statistics), + on_demuxer_config_changed_cb), audio_codec_(kUnknownAudioCodec), num_channels_(0), config_sampling_rate_(0), @@ -102,9 +99,11 @@ size_t offset, size_t size, bool render_output, + bool /* is_late_frame */, base::TimeDelta current_presentation_timestamp, const ReleaseOutputCompletionCallback& callback) { render_output = render_output && (size != 0u); + bool is_audio_underrun = false; if (render_output) { int64 head_position = (static_cast<AudioCodecBridge*>( media_codec_bridge_.get()))->PlayOutputBuffer( @@ -125,10 +124,9 @@ last_buffered - audio_timestamp_helper_->GetFrameDuration(frames_to_play); - if (!next_frame_time_limit_.is_null() && - next_frame_time_limit_ < current_time) { - frame_statistics_->IncrementLateFrameCount(); - } + // Potential audio underrun is considered a late frame for UMA. + is_audio_underrun = !next_frame_time_limit_.is_null() && + next_frame_time_limit_ < current_time; next_frame_time_limit_ = current_time + (last_buffered - current_presentation_timestamp); @@ -137,7 +135,7 @@ } media_codec_bridge_->ReleaseOutputBuffer(output_buffer_index, false); - callback.Run(current_presentation_timestamp, + callback.Run(is_audio_underrun, current_presentation_timestamp, audio_timestamp_helper_->GetTimestamp()); }
diff --git a/media/base/android/audio_decoder_job.h b/media/base/android/audio_decoder_job.h index baee4a35..f302a59 100644 --- a/media/base/android/audio_decoder_job.h +++ b/media/base/android/audio_decoder_job.h
@@ -24,8 +24,7 @@ // |on_demuxer_config_changed_cb| - Callback used to inform the caller that // demuxer config has changed. AudioDecoderJob(const base::Closure& request_data_cb, - const base::Closure& on_demuxer_config_changed_cb, - FrameStatistics* frame_statistics); + const base::Closure& on_demuxer_config_changed_cb); ~AudioDecoderJob() override; // MediaDecoderJob implementation. @@ -46,6 +45,7 @@ size_t offset, size_t size, bool render_output, + bool is_late_frame, base::TimeDelta current_presentation_timestamp, const ReleaseOutputCompletionCallback& callback) override; bool ComputeTimeToRender() const override;
diff --git a/media/base/android/media_decoder_job.cc b/media/base/android/media_decoder_job.cc index 855a813b..3bf5279 100644 --- a/media/base/android/media_decoder_job.cc +++ b/media/base/android/media_decoder_job.cc
@@ -10,7 +10,6 @@ #include "base/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "media/base/android/media_drm_bridge.h" -#include "media/base/android/media_statistics.h" #include "media/base/bind_to_current_loop.h" #include "media/base/timestamp_constants.h" @@ -24,10 +23,8 @@ MediaDecoderJob::MediaDecoderJob( const scoped_refptr<base::SingleThreadTaskRunner>& decoder_task_runner, const base::Closure& request_data_cb, - const base::Closure& config_changed_cb, - FrameStatistics* frame_statistics) + const base::Closure& config_changed_cb) : need_to_reconfig_decoder_job_(false), - frame_statistics_(frame_statistics), ui_task_runner_(base::ThreadTaskRunnerHandle::Get()), decoder_task_runner_(decoder_task_runner), needs_flush_(false), @@ -91,7 +88,7 @@ if (stop_decode_pending_) { DCHECK(is_decoding()); - OnDecodeCompleted(MEDIA_CODEC_ABORT, kNoTimestamp(), kNoTimestamp()); + OnDecodeCompleted(MEDIA_CODEC_ABORT, false, kNoTimestamp(), kNoTimestamp()); return; } @@ -364,7 +361,7 @@ // MEDIA_CODEC_OUTPUT_FORMAT_CHANGED status will come later. ui_task_runner_->PostTask(FROM_HERE, base::Bind( &MediaDecoderJob::OnDecodeCompleted, base::Unretained(this), - MEDIA_CODEC_OK, kNoTimestamp(), kNoTimestamp())); + MEDIA_CODEC_OK, false, kNoTimestamp(), kNoTimestamp())); return; } // Start draining the decoder so that all the remaining frames are @@ -400,7 +397,7 @@ input_buf_index_ = -1; MediaCodecStatus reset_status = media_codec_bridge_->Reset(); if (MEDIA_CODEC_OK != reset_status) { - callback.Run(reset_status, kNoTimestamp(), kNoTimestamp()); + callback.Run(reset_status, false, kNoTimestamp(), kNoTimestamp()); return; } } @@ -412,7 +409,7 @@ // For aborted access unit, just skip it and inform the player. if (unit.status == DemuxerStream::kAborted) { - callback.Run(MEDIA_CODEC_ABORT, kNoTimestamp(), kNoTimestamp()); + callback.Run(MEDIA_CODEC_ABORT, false, kNoTimestamp(), kNoTimestamp()); return; } @@ -420,7 +417,7 @@ if (unit.is_end_of_stream || unit.data.empty()) { input_eos_encountered_ = true; output_eos_encountered_ = true; - callback.Run(MEDIA_CODEC_OUTPUT_END_OF_STREAM, kNoTimestamp(), + callback.Run(MEDIA_CODEC_OUTPUT_END_OF_STREAM, false, kNoTimestamp(), kNoTimestamp()); return; } @@ -438,7 +435,7 @@ // change can be resolved. Context: b/21786703 DVLOG(1) << "dequeueInputBuffer gave AGAIN_LATER, dequeue output buffers"; } else if (input_status != MEDIA_CODEC_OK) { - callback.Run(input_status, kNoTimestamp(), kNoTimestamp()); + callback.Run(input_status, false, kNoTimestamp(), kNoTimestamp()); return; } } @@ -474,7 +471,7 @@ status != MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER); if (status != MEDIA_CODEC_OK) { - callback.Run(status, kNoTimestamp(), kNoTimestamp()); + callback.Run(status, false, kNoTimestamp(), kNoTimestamp()); return; } @@ -488,32 +485,19 @@ (status != MEDIA_CODEC_OUTPUT_END_OF_STREAM || size != 0u); base::TimeDelta time_to_render; DCHECK(!start_time_ticks.is_null()); - if (render_output) { - frame_statistics_->IncrementFrameCount(); - - if (ComputeTimeToRender()) { - time_to_render = - presentation_timestamp - (base::TimeTicks::Now() - start_time_ticks + - start_presentation_timestamp); - - // ComputeTimeToRender() returns true for video streams only, this is a - // video stream. - if (time_to_render < base::TimeDelta()) - frame_statistics_->IncrementLateFrameCount(); - } + if (render_output && ComputeTimeToRender()) { + time_to_render = presentation_timestamp - (base::TimeTicks::Now() - + start_time_ticks + start_presentation_timestamp); } if (time_to_render > base::TimeDelta()) { decoder_task_runner_->PostDelayedTask( FROM_HERE, base::Bind(&MediaDecoderJob::ReleaseOutputBuffer, - base::Unretained(this), - buffer_index, - offset, - size, + base::Unretained(this), buffer_index, offset, size, render_output, - presentation_timestamp, - base::Bind(callback, status)), + false, // this is not a late frame + presentation_timestamp, base::Bind(callback, status)), time_to_render); return; } @@ -531,14 +515,19 @@ } else { presentation_timestamp = kNoTimestamp(); } + ReleaseOutputCompletionCallback completion_callback = base::Bind( callback, status); - ReleaseOutputBuffer(buffer_index, offset, size, render_output, + + const bool is_late_frame = (time_to_render < base::TimeDelta()); + ReleaseOutputBuffer(buffer_index, offset, size, render_output, is_late_frame, presentation_timestamp, completion_callback); } void MediaDecoderJob::OnDecodeCompleted( - MediaCodecStatus status, base::TimeDelta current_presentation_timestamp, + MediaCodecStatus status, + bool is_late_frame, + base::TimeDelta current_presentation_timestamp, base::TimeDelta max_presentation_timestamp) { DCHECK(ui_task_runner_->BelongsToCurrentThread()); @@ -600,8 +589,9 @@ } stop_decode_pending_ = false; - base::ResetAndReturn(&decode_cb_).Run( - status, current_presentation_timestamp, max_presentation_timestamp); + base::ResetAndReturn(&decode_cb_) + .Run(status, is_late_frame, current_presentation_timestamp, + max_presentation_timestamp); } const AccessUnit& MediaDecoderJob::CurrentAccessUnit() const {
diff --git a/media/base/android/media_decoder_job.h b/media/base/android/media_decoder_job.h index df7f454..752ac882 100644 --- a/media/base/android/media_decoder_job.h +++ b/media/base/android/media_decoder_job.h
@@ -18,7 +18,6 @@ namespace media { -struct FrameStatistics; class MediaDrmBridge; // Class for managing all the decoding tasks. Each decoding task will be posted @@ -40,17 +39,20 @@ }; // Callback when a decoder job finishes its work. Args: whether decode - // finished successfully, current presentation time, max presentation time. + // finished successfully, a flag whether the frame is late for statistics, + // cacurrent presentation time, max presentation time. // If the current presentation time is equal to kNoTimestamp(), the decoder // job skipped rendering of the decoded output and the callback target should - // ignore the timestamps provided. - typedef base::Callback<void(MediaCodecStatus, base::TimeDelta, + // ignore the timestamps provided. The late frame flag has no meaning in this + // case. + typedef base::Callback<void(MediaCodecStatus, bool, base::TimeDelta, base::TimeDelta)> DecoderCallback; // Callback when a decoder job finishes releasing the output buffer. - // Args: current presentation time, max presentation time. + // Args: whether the frame is a late frame, current presentation time, max + // presentation time. // If the current presentation time is equal to kNoTimestamp(), the callback - // target should ignore the timestamps provided. - typedef base::Callback<void(base::TimeDelta, base::TimeDelta)> + // target should ignore the timestamps provided and whether it is late. + typedef base::Callback<void(bool, base::TimeDelta, base::TimeDelta)> ReleaseOutputCompletionCallback; virtual ~MediaDecoderJob(); @@ -118,16 +120,18 @@ MediaDecoderJob( const scoped_refptr<base::SingleThreadTaskRunner>& decoder_task_runner, const base::Closure& request_data_cb, - const base::Closure& config_changed_cb, - FrameStatistics* frame_statistics); + const base::Closure& config_changed_cb); // Release the output buffer at index |output_buffer_index| and render it if // |render_output| is true. Upon completion, |callback| will be called. + // |is_late_frame| can be passed with the |callback| if the implementation + // does not calculate it itself. virtual void ReleaseOutputBuffer( int output_buffer_index, size_t offset, size_t size, bool render_output, + bool is_late_frame, base::TimeDelta current_presentation_timestamp, const ReleaseOutputCompletionCallback& callback) = 0; @@ -156,8 +160,6 @@ scoped_ptr<MediaCodecBridge> media_codec_bridge_; - FrameStatistics* frame_statistics_; - private: friend class MediaSourcePlayerTest; @@ -200,6 +202,7 @@ // Completes any pending job destruction or any pending decode stop. If // destruction was not pending, passes its arguments to |decode_cb_|. void OnDecodeCompleted(MediaCodecStatus status, + bool is_late_frame, base::TimeDelta current_presentation_timestamp, base::TimeDelta max_presentation_timestamp);
diff --git a/media/base/android/media_source_player.cc b/media/base/android/media_source_player.cc index 4674191..d4408b3 100644 --- a/media/base/android/media_source_player.cc +++ b/media/base/android/media_source_player.cc
@@ -54,15 +54,13 @@ base::Unretained(demuxer_.get()), DemuxerStream::AUDIO), base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged, - weak_factory_.GetWeakPtr()), - &media_stat_->audio_frame_stats())); + weak_factory_.GetWeakPtr()))); video_decoder_job_.reset(new VideoDecoderJob( base::Bind(&DemuxerAndroid::RequestDemuxerData, base::Unretained(demuxer_.get()), DemuxerStream::VIDEO), base::Bind(&MediaSourcePlayer::OnDemuxerConfigsChanged, - weak_factory_.GetWeakPtr()), - &media_stat_->video_frame_stats())); + weak_factory_.GetWeakPtr()))); demuxer_->Initialize(this); interpolator_.SetUpperBound(base::TimeDelta()); @@ -439,7 +437,9 @@ } void MediaSourcePlayer::MediaDecoderCallback( - bool is_audio, MediaCodecStatus status, + bool is_audio, + MediaCodecStatus status, + bool is_late_frame, base::TimeDelta current_presentation_timestamp, base::TimeDelta max_presentation_timestamp) { DVLOG(1) << __FUNCTION__ << ": " << is_audio << ", " << status; @@ -476,6 +476,15 @@ return; } + // Increment frame counts for UMA. + if (current_presentation_timestamp != kNoTimestamp()) { + FrameStatistics& frame_stats = is_audio ? media_stat_->audio_frame_stats() + : media_stat_->video_frame_stats(); + frame_stats.IncrementFrameCount(); + if (is_late_frame) + frame_stats.IncrementLateFrameCount(); + } + DCHECK(!IsEventPending(PREFETCH_DONE_EVENT_PENDING)); // Let |SEEK_EVENT_PENDING| (the highest priority event outside of
diff --git a/media/base/android/media_source_player.h b/media/base/android/media_source_player.h index eb4e3fc..7e4d706 100644 --- a/media/base/android/media_source_player.h +++ b/media/base/android/media_source_player.h
@@ -85,10 +85,11 @@ void PlaybackCompleted(bool is_audio); // Called when the decoder finishes its task. - void MediaDecoderCallback( - bool is_audio, MediaCodecStatus status, - base::TimeDelta current_presentation_timestamp, - base::TimeDelta max_presentation_timestamp); + void MediaDecoderCallback(bool is_audio, + MediaCodecStatus status, + bool is_late_frame, + base::TimeDelta current_presentation_timestamp, + base::TimeDelta max_presentation_timestamp); bool IsPrerollFinished(bool is_audio) const;
diff --git a/media/base/android/video_decoder_job.cc b/media/base/android/video_decoder_job.cc index 4c2cc76..d43f450 100644 --- a/media/base/android/video_decoder_job.cc +++ b/media/base/android/video_decoder_job.cc
@@ -27,12 +27,10 @@ VideoDecoderJob::VideoDecoderJob( const base::Closure& request_data_cb, - const base::Closure& on_demuxer_config_changed_cb, - FrameStatistics* frame_statistics) + const base::Closure& on_demuxer_config_changed_cb) : MediaDecoderJob(g_video_decoder_thread.Pointer()->task_runner(), request_data_cb, - on_demuxer_config_changed_cb, - frame_statistics), + on_demuxer_config_changed_cb), video_codec_(kUnknownVideoCodec), config_width_(0), config_height_(0), @@ -81,10 +79,12 @@ size_t offset, size_t size, bool render_output, + bool is_late_frame, base::TimeDelta current_presentation_timestamp, const ReleaseOutputCompletionCallback& callback) { media_codec_bridge_->ReleaseOutputBuffer(output_buffer_index, render_output); - callback.Run(current_presentation_timestamp, current_presentation_timestamp); + callback.Run(is_late_frame, current_presentation_timestamp, + current_presentation_timestamp); } bool VideoDecoderJob::ComputeTimeToRender() const {
diff --git a/media/base/android/video_decoder_job.h b/media/base/android/video_decoder_job.h index 372fe1ab..29d5761 100644 --- a/media/base/android/video_decoder_job.h +++ b/media/base/android/video_decoder_job.h
@@ -21,8 +21,7 @@ // |on_demuxer_config_changed_cb| - Callback used to inform the caller that // demuxer config has changed. VideoDecoderJob(const base::Closure& request_data_cb, - const base::Closure& on_demuxer_config_changed_cb, - FrameStatistics* frame_statistics); + const base::Closure& on_demuxer_config_changed_cb); ~VideoDecoderJob() override; // Passes a java surface object to the codec. Returns true if the surface @@ -44,6 +43,7 @@ size_t offset, size_t size, bool render_output, + bool is_late_frame, base::TimeDelta current_presentation_timestamp, const ReleaseOutputCompletionCallback& callback) override; bool ComputeTimeToRender() const override;
diff --git a/mojo/gles2/command_buffer_client_impl.cc b/mojo/gles2/command_buffer_client_impl.cc index 3548c1f..ba16771 100644 --- a/mojo/gles2/command_buffer_client_impl.cc +++ b/mojo/gles2/command_buffer_client_impl.cc
@@ -128,6 +128,8 @@ last_put_offset_(-1), next_transfer_buffer_id_(0), next_image_id_(0), + next_fence_sync_release_(1), + flushed_fence_sync_release_(0), async_waiter_(async_waiter) { command_buffer_.Bind(mojo::InterfacePtrInfo<mojo::CommandBuffer>( command_buffer_handle.Pass(), 0u), @@ -190,6 +192,7 @@ last_put_offset_ = put_offset; command_buffer_->Flush(put_offset); + flushed_fence_sync_release_ = next_fence_sync_release_ - 1; } void CommandBufferClientImpl::OrderingBarrier(int32_t put_offset) { @@ -408,4 +411,16 @@ return 0; } +uint64_t CommandBufferClientImpl::GenerateFenceSyncRelease() { + return next_fence_sync_release_++; +} + +bool CommandBufferClientImpl::IsFenceSyncRelease(uint64_t release) { + return release != 0 && release < next_fence_sync_release_; +} + +bool CommandBufferClientImpl::IsFenceSyncFlushed(uint64_t release) { + return release != 0 && release <= flushed_fence_sync_release_; +} + } // namespace gles2
diff --git a/mojo/gles2/command_buffer_client_impl.h b/mojo/gles2/command_buffer_client_impl.h index b5e2db322..2c3c925 100644 --- a/mojo/gles2/command_buffer_client_impl.h +++ b/mojo/gles2/command_buffer_client_impl.h
@@ -76,6 +76,9 @@ bool IsGpuChannelLost() override; gpu::CommandBufferNamespace GetNamespaceID() const override; uint64_t GetCommandBufferID() const override; + uint64_t GenerateFenceSyncRelease() override; + bool IsFenceSyncRelease(uint64_t release) override; + bool IsFenceSyncFlushed(uint64_t release) override; private: class SyncClientImpl; @@ -106,6 +109,9 @@ // Image IDs are allocated in sequence. int next_image_id_; + uint64_t next_fence_sync_release_; + uint64_t flushed_fence_sync_release_; + const MojoAsyncWaiter* async_waiter_; };
diff --git a/mojo/gpu/mojo_gles2_impl_autogen.cc b/mojo/gpu/mojo_gles2_impl_autogen.cc index 5237b66..f256ba0 100644 --- a/mojo/gpu/mojo_gles2_impl_autogen.cc +++ b/mojo/gpu/mojo_gles2_impl_autogen.cc
@@ -1657,6 +1657,19 @@ MojoGLES2MakeCurrent(context_); glWaitSyncPointCHROMIUM(sync_point); } +GLuint64 MojoGLES2Impl::InsertFenceSyncCHROMIUM() { + MojoGLES2MakeCurrent(context_); + return glInsertFenceSyncCHROMIUM(); +} +void MojoGLES2Impl::GenSyncTokenCHROMIUM(GLuint64 fence_sync, + GLbyte* sync_token) { + MojoGLES2MakeCurrent(context_); + glGenSyncTokenCHROMIUM(fence_sync, sync_token); +} +void MojoGLES2Impl::WaitSyncTokenCHROMIUM(const GLbyte* sync_token) { + MojoGLES2MakeCurrent(context_); + glWaitSyncTokenCHROMIUM(sync_token); +} void MojoGLES2Impl::DrawBuffersEXT(GLsizei count, const GLenum* bufs) { MojoGLES2MakeCurrent(context_); glDrawBuffersEXT(count, bufs);
diff --git a/mojo/gpu/mojo_gles2_impl_autogen.h b/mojo/gpu/mojo_gles2_impl_autogen.h index 872c4f7..6d9d0a8 100644 --- a/mojo/gpu/mojo_gles2_impl_autogen.h +++ b/mojo/gpu/mojo_gles2_impl_autogen.h
@@ -765,6 +765,9 @@ void LoseContextCHROMIUM(GLenum current, GLenum other) override; GLuint InsertSyncPointCHROMIUM() override; void WaitSyncPointCHROMIUM(GLuint sync_point) override; + GLuint64 InsertFenceSyncCHROMIUM() override; + void GenSyncTokenCHROMIUM(GLuint64 fence_sync, GLbyte* sync_token) override; + void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) override; void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override; void DiscardBackbufferCHROMIUM() override; void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order,
diff --git a/mojo/tools/mopy/gtest.py b/mojo/tools/mopy/gtest.py index e037da3..1b3afbb 100644 --- a/mojo/tools/mopy/gtest.py +++ b/mojo/tools/mopy/gtest.py
@@ -194,11 +194,19 @@ timeout_exception = '\nError: Test timeout after %s seconds' % seconds logging.getLogger().debug('Killing the runner or shell for timeout.') try: - process_or_shell.kill() - except OSError: - pass # The process may have ended after checking |is_alive|. + if sys.platform.startswith('win'): + # Taskkill is more reliable than Popen.kill() on Win; crbug.com/517661 + killer = ['taskkill.exe', '/f', '/t', '/pid', str(process_or_shell.pid)] + logging.getLogger().debug(subprocess.check_output(killer)) + else: + process_or_shell.kill() + except subprocess.CalledProcessError as e: + logging.getLogger().debug('CalledProcessError: %s' % e) + except OSError as e: + # The process may have ended after checking |thread.is_alive()|. + logging.getLogger().debug('OSError (likely ignorable): %s' % e) + thread.join(seconds) - thread.join(seconds) if thread.is_alive(): raise Exception('Error: Test hung and could not be killed!') if result.empty():
diff --git a/net/base/net_error_list.h b/net/base/net_error_list.h index ad2c8302..e53c4b0b 100644 --- a/net/base/net_error_list.h +++ b/net/base/net_error_list.h
@@ -357,6 +357,12 @@ // OK but was missing some of the fields. NET_ERROR(CT_STH_INCOMPLETE, -169) +// The attempt to reuse a connection to send proxy auth credentials failed +// before the AuthController was used to generate credentials. The caller should +// reuse the controller with a new connection. This error is only used +// internally by the network stack. +NET_ERROR(UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH, -170) + // Certificate error codes // // The values of certificate error codes must be consecutive.
diff --git a/net/base/dns_reloader.cc b/net/dns/dns_reloader.cc similarity index 98% rename from net/base/dns_reloader.cc rename to net/dns/dns_reloader.cc index 18041d9fc..8298c78 100644 --- a/net/base/dns_reloader.cc +++ b/net/dns/dns_reloader.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/base/dns_reloader.h" +#include "net/dns/dns_reloader.h" #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) && \ !defined(OS_ANDROID)
diff --git a/net/base/dns_reloader.h b/net/dns/dns_reloader.h similarity index 86% rename from net/base/dns_reloader.h rename to net/dns/dns_reloader.h index 889d404..4317d9ea 100644 --- a/net/base/dns_reloader.h +++ b/net/dns/dns_reloader.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_BASE_DNS_RELOADER_H_ -#define NET_BASE_DNS_RELOADER_H_ +#ifndef NET_DNS_DNS_RELOADER_H_ +#define NET_DNS_DNS_RELOADER_H_ #include "build/build_config.h" @@ -20,4 +20,4 @@ } // namespace net #endif // defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) -#endif // NET_BASE_DNS_RELOADER_H_ +#endif // NET_DNS_DNS_RELOADER_H_
diff --git a/net/dns/host_resolver_impl.cc b/net/dns/host_resolver_impl.cc index 97345a0..417b3ae 100644 --- a/net/dns/host_resolver_impl.cc +++ b/net/dns/host_resolver_impl.cc
@@ -35,7 +35,6 @@ #include "base/values.h" #include "net/base/address_family.h" #include "net/base/address_list.h" -#include "net/base/dns_reloader.h" #include "net/base/dns_util.h" #include "net/base/host_port_pair.h" #include "net/base/ip_endpoint.h" @@ -45,6 +44,7 @@ #include "net/dns/dns_client.h" #include "net/dns/dns_config_service.h" #include "net/dns/dns_protocol.h" +#include "net/dns/dns_reloader.h" #include "net/dns/dns_response.h" #include "net/dns/dns_transaction.h" #include "net/dns/host_resolver_proc.h"
diff --git a/net/dns/host_resolver_proc.cc b/net/dns/host_resolver_proc.cc index 98b9812..fbb40ca 100644 --- a/net/dns/host_resolver_proc.cc +++ b/net/dns/host_resolver_proc.cc
@@ -9,10 +9,10 @@ #include "base/logging.h" #include "base/sys_byteorder.h" #include "net/base/address_list.h" -#include "net/base/dns_reloader.h" #include "net/base/dns_util.h" #include "net/base/net_errors.h" #include "net/base/sys_addrinfo.h" +#include "net/dns/dns_reloader.h" #if defined(OS_OPENBSD) #define AI_ADDRCONFIG 0
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 37efedc..670db0b6 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -3319,6 +3319,446 @@ NetLog::PHASE_NONE); } +// Test a proxy auth scheme that allows default credentials and a proxy server +// that uses non-persistent connections. +TEST_P(HttpNetworkTransactionTest, + AuthAllowsDefaultCredentialsTunnelConnectionClose) { + HttpRequestInfo request; + request.method = "GET"; + request.url = GURL("https://www.example.org/"); + + // Configure against proxy server "myproxy:70". + session_deps_.proxy_service = + ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"); + + scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory( + new HttpAuthHandlerMock::Factory()); + auth_handler_factory->set_do_init_from_challenge(true); + scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock()); + mock_handler->set_allows_default_credentials(true); + auth_handler_factory->AddMockHandler(mock_handler.release(), + HttpAuth::AUTH_PROXY); + session_deps_.http_auth_handler_factory = auth_handler_factory.Pass(); + + // Add NetLog just so can verify load timing information gets a NetLog ID. + NetLog net_log; + session_deps_.net_log = &net_log; + scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); + + // Since we have proxy, should try to establish tunnel. + MockWrite data_writes1[] = { + MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"), + }; + + // The proxy responds to the connect with a 407, using a non-persistent + // connection. + MockRead data_reads1[] = { + // No credentials. + MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), + MockRead("Proxy-Authenticate: Mock\r\n"), + MockRead("Proxy-Connection: close\r\n\r\n"), + }; + + // Since the first connection couldn't be reused, need to establish another + // once given credentials. + MockWrite data_writes2[] = { + // After calling trans->RestartWithAuth(), this is the request we should + // be issuing -- the final header line contains the credentials. + MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Proxy-Connection: keep-alive\r\n" + "Proxy-Authorization: auth_token\r\n\r\n"), + + MockWrite("GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n\r\n"), + }; + + MockRead data_reads2[] = { + MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"), + + MockRead("HTTP/1.1 200 OK\r\n"), + MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), + MockRead("Content-Length: 5\r\n\r\n"), + MockRead(SYNCHRONOUS, "hello"), + }; + + StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), + data_writes1, arraysize(data_writes1)); + session_deps_.socket_factory->AddSocketDataProvider(&data1); + StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), + data_writes2, arraysize(data_writes2)); + session_deps_.socket_factory->AddSocketDataProvider(&data2); + SSLSocketDataProvider ssl(ASYNC, OK); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); + + scoped_ptr<HttpTransaction> trans( + new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + + TestCompletionCallback callback; + int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + EXPECT_EQ(OK, callback.GetResult(rv)); + + const HttpResponseInfo* response = trans->GetResponseInfo(); + ASSERT_TRUE(response); + ASSERT_TRUE(response->headers); + EXPECT_FALSE(response->headers->IsKeepAlive()); + EXPECT_EQ(407, response->headers->response_code()); + EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); + EXPECT_TRUE(trans->IsReadyToRestartForAuth()); + EXPECT_FALSE(response->auth_challenge.get()); + + LoadTimingInfo load_timing_info; + // CONNECT requests and responses are handled at the connect job level, so + // the transaction does not yet have a connection. + EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info)); + + rv = trans->RestartWithAuth(AuthCredentials(), callback.callback()); + EXPECT_EQ(OK, callback.GetResult(rv)); + response = trans->GetResponseInfo(); + ASSERT_TRUE(response); + ASSERT_TRUE(response->headers); + EXPECT_TRUE(response->headers->IsKeepAlive()); + EXPECT_EQ(200, response->headers->response_code()); + EXPECT_EQ(5, response->headers->GetContentLength()); + EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); + + // The password prompt info should not be set. + EXPECT_FALSE(response->auth_challenge); + + EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + TestLoadTimingNotReusedWithPac(load_timing_info, + CONNECT_TIMING_HAS_SSL_TIMES); + + trans.reset(); + session->CloseAllConnections(); +} + +// Test a proxy auth scheme that allows default credentials and a proxy server +// that hangs up when credentials are initially sent. +TEST_P(HttpNetworkTransactionTest, + AuthAllowsDefaultCredentialsTunnelServerClosesConnection) { + HttpRequestInfo request; + request.method = "GET"; + request.url = GURL("https://www.example.org/"); + + // Configure against proxy server "myproxy:70". + session_deps_.proxy_service = + ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"); + + scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory( + new HttpAuthHandlerMock::Factory()); + auth_handler_factory->set_do_init_from_challenge(true); + scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock()); + mock_handler->set_allows_default_credentials(true); + auth_handler_factory->AddMockHandler(mock_handler.release(), + HttpAuth::AUTH_PROXY); + session_deps_.http_auth_handler_factory = auth_handler_factory.Pass(); + + // Add NetLog just so can verify load timing information gets a NetLog ID. + NetLog net_log; + session_deps_.net_log = &net_log; + scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); + + // Should try to establish tunnel. + MockWrite data_writes1[] = { + MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"), + + MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Proxy-Connection: keep-alive\r\n" + "Proxy-Authorization: auth_token\r\n\r\n"), + }; + + // The proxy responds to the connect with a 407, using a non-persistent + // connection. + MockRead data_reads1[] = { + // No credentials. + MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), + MockRead("Proxy-Authenticate: Mock\r\n\r\n"), + MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED), + }; + + // Since the first connection was closed, need to establish another once given + // credentials. + MockWrite data_writes2[] = { + MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Proxy-Connection: keep-alive\r\n" + "Proxy-Authorization: auth_token\r\n\r\n"), + + MockWrite("GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n\r\n"), + }; + + MockRead data_reads2[] = { + MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"), + + MockRead("HTTP/1.1 200 OK\r\n"), + MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), + MockRead("Content-Length: 5\r\n\r\n"), + MockRead(SYNCHRONOUS, "hello"), + }; + + StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), + data_writes1, arraysize(data_writes1)); + session_deps_.socket_factory->AddSocketDataProvider(&data1); + StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), + data_writes2, arraysize(data_writes2)); + session_deps_.socket_factory->AddSocketDataProvider(&data2); + SSLSocketDataProvider ssl(ASYNC, OK); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); + + scoped_ptr<HttpTransaction> trans( + new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + + TestCompletionCallback callback; + int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + EXPECT_EQ(OK, callback.GetResult(rv)); + + const HttpResponseInfo* response = trans->GetResponseInfo(); + ASSERT_TRUE(response); + ASSERT_TRUE(response->headers); + EXPECT_TRUE(response->headers->IsKeepAlive()); + EXPECT_EQ(407, response->headers->response_code()); + EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); + EXPECT_TRUE(trans->IsReadyToRestartForAuth()); + EXPECT_FALSE(response->auth_challenge); + + LoadTimingInfo load_timing_info; + // CONNECT requests and responses are handled at the connect job level, so + // the transaction does not yet have a connection. + EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info)); + + rv = trans->RestartWithAuth(AuthCredentials(), callback.callback()); + EXPECT_EQ(OK, callback.GetResult(rv)); + + response = trans->GetResponseInfo(); + ASSERT_TRUE(response); + ASSERT_TRUE(response->headers); + EXPECT_TRUE(response->headers->IsKeepAlive()); + EXPECT_EQ(200, response->headers->response_code()); + EXPECT_EQ(5, response->headers->GetContentLength()); + EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); + + // The password prompt info should not be set. + EXPECT_TRUE(response->auth_challenge.get() == NULL); + + EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + TestLoadTimingNotReusedWithPac(load_timing_info, + CONNECT_TIMING_HAS_SSL_TIMES); + + trans.reset(); + session->CloseAllConnections(); +} + +// Test a proxy auth scheme that allows default credentials and a proxy server +// that hangs up when credentials are initially sent, and hangs up again when +// they are retried. +TEST_P(HttpNetworkTransactionTest, + AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) { + HttpRequestInfo request; + request.method = "GET"; + request.url = GURL("https://www.example.org/"); + + // Configure against proxy server "myproxy:70". + session_deps_.proxy_service = + ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"); + + scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory( + new HttpAuthHandlerMock::Factory()); + auth_handler_factory->set_do_init_from_challenge(true); + scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock()); + mock_handler->set_allows_default_credentials(true); + auth_handler_factory->AddMockHandler(mock_handler.release(), + HttpAuth::AUTH_PROXY); + session_deps_.http_auth_handler_factory = auth_handler_factory.Pass(); + + // Add NetLog just so can verify load timing information gets a NetLog ID. + NetLog net_log; + session_deps_.net_log = &net_log; + scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); + + // Should try to establish tunnel. + MockWrite data_writes1[] = { + MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"), + + MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Proxy-Connection: keep-alive\r\n" + "Proxy-Authorization: auth_token\r\n\r\n"), + }; + + // The proxy responds to the connect with a 407, and then hangs up after the + // second request is sent. + MockRead data_reads1[] = { + // No credentials. + MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), + MockRead("Content-Length: 0\r\n"), + MockRead("Proxy-Connection: keep-alive\r\n"), + MockRead("Proxy-Authenticate: Mock\r\n\r\n"), + MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED), + }; + + // HttpNetworkTransaction sees a reused connection that was closed with + // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the + // request. + MockWrite data_writes2[] = { + MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"), + }; + + // The proxy, having had more than enough of us, just hangs up. + MockRead data_reads2[] = { + // No credentials. + MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED), + }; + + StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), + data_writes1, arraysize(data_writes1)); + session_deps_.socket_factory->AddSocketDataProvider(&data1); + StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), + data_writes2, arraysize(data_writes2)); + session_deps_.socket_factory->AddSocketDataProvider(&data2); + + scoped_ptr<HttpTransaction> trans( + new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + + TestCompletionCallback callback; + int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + EXPECT_EQ(OK, callback.GetResult(rv)); + + const HttpResponseInfo* response = trans->GetResponseInfo(); + ASSERT_TRUE(response); + ASSERT_TRUE(response->headers); + EXPECT_TRUE(response->headers->IsKeepAlive()); + EXPECT_EQ(407, response->headers->response_code()); + EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); + EXPECT_TRUE(trans->IsReadyToRestartForAuth()); + EXPECT_FALSE(response->auth_challenge); + + LoadTimingInfo load_timing_info; + EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info)); + + rv = trans->RestartWithAuth(AuthCredentials(), callback.callback()); + EXPECT_EQ(ERR_EMPTY_RESPONSE, callback.GetResult(rv)); + + trans.reset(); + session->CloseAllConnections(); +} + +// Test a proxy auth scheme that allows default credentials and a proxy server +// that hangs up when credentials are initially sent, and sends a challenge +// again they are retried. +TEST_P(HttpNetworkTransactionTest, + AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) { + HttpRequestInfo request; + request.method = "GET"; + request.url = GURL("https://www.example.org/"); + + // Configure against proxy server "myproxy:70". + session_deps_.proxy_service = + ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"); + + scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory( + new HttpAuthHandlerMock::Factory()); + auth_handler_factory->set_do_init_from_challenge(true); + scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock()); + mock_handler->set_allows_default_credentials(true); + auth_handler_factory->AddMockHandler(mock_handler.release(), + HttpAuth::AUTH_PROXY); + // Add another handler for the second challenge. It supports default + // credentials, but they shouldn't be used, since they were already tried. + mock_handler.reset(new HttpAuthHandlerMock()); + mock_handler->set_allows_default_credentials(true); + auth_handler_factory->AddMockHandler(mock_handler.release(), + HttpAuth::AUTH_PROXY); + session_deps_.http_auth_handler_factory = auth_handler_factory.Pass(); + + // Add NetLog just so can verify load timing information gets a NetLog ID. + NetLog net_log; + session_deps_.net_log = &net_log; + scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); + + // Should try to establish tunnel. + MockWrite data_writes1[] = { + MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"), + }; + + // The proxy responds to the connect with a 407, using a non-persistent + // connection. + MockRead data_reads1[] = { + // No credentials. + MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), + MockRead("Proxy-Authenticate: Mock\r\n"), + MockRead("Proxy-Connection: close\r\n\r\n"), + }; + + // Since the first connection was closed, need to establish another once given + // credentials. + MockWrite data_writes2[] = { + MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Proxy-Connection: keep-alive\r\n" + "Proxy-Authorization: auth_token\r\n\r\n"), + }; + + MockRead data_reads2[] = { + MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), + MockRead("Proxy-Authenticate: Mock\r\n"), + MockRead("Proxy-Connection: close\r\n\r\n"), + }; + + StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), + data_writes1, arraysize(data_writes1)); + session_deps_.socket_factory->AddSocketDataProvider(&data1); + StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), + data_writes2, arraysize(data_writes2)); + session_deps_.socket_factory->AddSocketDataProvider(&data2); + SSLSocketDataProvider ssl(ASYNC, OK); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); + + scoped_ptr<HttpTransaction> trans( + new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + + TestCompletionCallback callback; + int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + EXPECT_EQ(OK, callback.GetResult(rv)); + + const HttpResponseInfo* response = trans->GetResponseInfo(); + ASSERT_TRUE(response); + ASSERT_TRUE(response->headers); + EXPECT_EQ(407, response->headers->response_code()); + EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); + EXPECT_TRUE(trans->IsReadyToRestartForAuth()); + EXPECT_FALSE(response->auth_challenge); + + LoadTimingInfo load_timing_info; + EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info)); + + rv = trans->RestartWithAuth(AuthCredentials(), callback.callback()); + EXPECT_EQ(OK, callback.GetResult(rv)); + response = trans->GetResponseInfo(); + ASSERT_TRUE(response); + ASSERT_TRUE(response->headers); + EXPECT_EQ(407, response->headers->response_code()); + EXPECT_FALSE(trans->IsReadyToRestartForAuth()); + EXPECT_TRUE(response->auth_challenge); + + trans.reset(); + session->CloseAllConnections(); +} + // Test the load timing for HTTPS requests with an HTTP proxy. TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) { HttpRequestInfo request1;
diff --git a/net/http/http_proxy_client_socket.cc b/net/http/http_proxy_client_socket.cc index 92a631e7..f188333 100644 --- a/net/http/http_proxy_client_socket.cc +++ b/net/http/http_proxy_client_socket.cc
@@ -32,8 +32,7 @@ const std::string& user_agent, const HostPortPair& endpoint, const HostPortPair& proxy_server, - HttpAuthCache* http_auth_cache, - HttpAuthHandlerFactory* http_auth_handler_factory, + HttpAuthController* http_auth_controller, bool tunnel, bool using_spdy, NextProto protocol_negotiated, @@ -44,13 +43,7 @@ next_state_(STATE_NONE), transport_(transport_socket), endpoint_(endpoint), - auth_(tunnel ? - new HttpAuthController(HttpAuth::AUTH_PROXY, - GURL((is_https_proxy ? "https://" : "http://") - + proxy_server.ToString()), - http_auth_cache, - http_auth_handler_factory) - : NULL), + auth_(http_auth_controller), tunnel_(tunnel), using_spdy_(using_spdy), protocol_negotiated_(protocol_negotiated), @@ -273,7 +266,7 @@ !http_stream_parser_->CanFindEndOfResponse() || !transport_->socket()->IsConnectedAndIdle()) { transport_->socket()->Disconnect(); - return ERR_CONNECTION_CLOSED; + return ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH; } // If the auth request had a body, need to drain it before reusing the socket. @@ -527,7 +520,7 @@ int HttpProxyClientSocket::DoDrainBodyComplete(int result) { if (result < 0) - return result; + return ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH; if (!http_stream_parser_->IsResponseBodyComplete()) { // Keep draining. @@ -538,4 +531,6 @@ return DidDrainBodyForAuthRestart(); } +//---------------------------------------------------------------- + } // namespace net
diff --git a/net/http/http_proxy_client_socket.h b/net/http/http_proxy_client_socket.h index ab973cc..f154a88e 100644 --- a/net/http/http_proxy_client_socket.h +++ b/net/http/http_proxy_client_socket.h
@@ -25,7 +25,6 @@ class AddressList; class ClientSocketHandle; class GrowableIOBuffer; -class HttpAuthCache; class HttpStream; class HttpStreamParser; class IOBuffer; @@ -40,8 +39,7 @@ const std::string& user_agent, const HostPortPair& endpoint, const HostPortPair& proxy_server, - HttpAuthCache* http_auth_cache, - HttpAuthHandlerFactory* http_auth_handler_factory, + HttpAuthController* http_auth_controller, bool tunnel, bool using_spdy, NextProto protocol_negotiated,
diff --git a/net/http/http_proxy_client_socket_pool.cc b/net/http/http_proxy_client_socket_pool.cc index 1a60c6ae..8e0580e 100644 --- a/net/http/http_proxy_client_socket_pool.cc +++ b/net/http/http_proxy_client_socket_pool.cc
@@ -13,7 +13,7 @@ #include "net/base/net_errors.h" #include "net/base/proxy_delegate.h" #include "net/http/http_network_session.h" -#include "net/http/http_proxy_client_socket.h" +#include "net/http/http_proxy_client_socket_wrapper.h" #include "net/socket/client_socket_factory.h" #include "net/socket/client_socket_handle.h" #include "net/socket/client_socket_pool_base.h" @@ -86,305 +86,66 @@ SSLClientSocketPool* ssl_pool, Delegate* delegate, NetLog* net_log) - : ConnectJob(group_name, timeout_duration, priority, delegate, + : ConnectJob(group_name, + base::TimeDelta() /* The socket takes care of timeouts */, + priority, + delegate, BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)), - params_(params), - transport_pool_(transport_pool), - ssl_pool_(ssl_pool), - using_spdy_(false), - protocol_negotiated_(kProtoUnknown), - weak_ptr_factory_(this) { - callback_= base::Bind(&HttpProxyConnectJob::OnIOComplete, - weak_ptr_factory_.GetWeakPtr()); -} + client_socket_(new HttpProxyClientSocketWrapper( + group_name, + priority, + timeout_duration, + base::TimeDelta::FromSeconds(kHttpProxyConnectJobTimeoutInSeconds), + transport_pool, + ssl_pool, + params->transport_params(), + params->ssl_params(), + params->user_agent(), + params->endpoint(), + params->http_auth_cache(), + params->http_auth_handler_factory(), + params->spdy_session_pool(), + params->tunnel(), + params->proxy_delegate(), + this->net_log())) {} HttpProxyConnectJob::~HttpProxyConnectJob() {} LoadState HttpProxyConnectJob::GetLoadState() const { - switch (next_state_) { - case STATE_TCP_CONNECT: - case STATE_TCP_CONNECT_COMPLETE: - case STATE_SSL_CONNECT: - case STATE_SSL_CONNECT_COMPLETE: - return transport_socket_handle_->GetLoadState(); - case STATE_HTTP_PROXY_CONNECT: - case STATE_HTTP_PROXY_CONNECT_COMPLETE: - case STATE_SPDY_PROXY_CREATE_STREAM: - case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE: - return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL; - default: - NOTREACHED(); - return LOAD_STATE_IDLE; - } + return client_socket_->GetConnectLoadState(); } void HttpProxyConnectJob::GetAdditionalErrorState(ClientSocketHandle * handle) { - if (error_response_info_.cert_request_info.get()) { - handle->set_ssl_error_response_info(error_response_info_); + if (error_response_info_) { + handle->set_ssl_error_response_info(*error_response_info_); handle->set_is_ssl_error(true); } } -void HttpProxyConnectJob::OnIOComplete(int result) { - int rv = DoLoop(result); - if (rv != ERR_IO_PENDING) { - NotifyProxyDelegateOfCompletion(rv); - NotifyDelegateOfCompletion(rv); // Deletes |this| - } +int HttpProxyConnectJob::ConnectInternal() { + int result = client_socket_->Connect(base::Bind( + &HttpProxyConnectJob::OnConnectComplete, base::Unretained(this))); + return HandleConnectResult(result); } -int HttpProxyConnectJob::DoLoop(int result) { - DCHECK_NE(next_state_, STATE_NONE); - - int rv = result; - do { - State state = next_state_; - next_state_ = STATE_NONE; - switch (state) { - case STATE_TCP_CONNECT: - DCHECK_EQ(OK, rv); - rv = DoTransportConnect(); - break; - case STATE_TCP_CONNECT_COMPLETE: - rv = DoTransportConnectComplete(rv); - break; - case STATE_SSL_CONNECT: - DCHECK_EQ(OK, rv); - rv = DoSSLConnect(); - break; - case STATE_SSL_CONNECT_COMPLETE: - rv = DoSSLConnectComplete(rv); - break; - case STATE_HTTP_PROXY_CONNECT: - DCHECK_EQ(OK, rv); - rv = DoHttpProxyConnect(); - break; - case STATE_HTTP_PROXY_CONNECT_COMPLETE: - rv = DoHttpProxyConnectComplete(rv); - break; - case STATE_SPDY_PROXY_CREATE_STREAM: - DCHECK_EQ(OK, rv); - rv = DoSpdyProxyCreateStream(); - break; - case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE: - rv = DoSpdyProxyCreateStreamComplete(rv); - break; - default: - NOTREACHED() << "bad state"; - rv = ERR_FAILED; - break; - } - } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); - - return rv; +void HttpProxyConnectJob::OnConnectComplete(int result) { + DCHECK_NE(ERR_IO_PENDING, result); + result = HandleConnectResult(result); + NotifyDelegateOfCompletion(result); + // |this| will have been deleted at this point. } -int HttpProxyConnectJob::DoTransportConnect() { - next_state_ = STATE_TCP_CONNECT_COMPLETE; - transport_socket_handle_.reset(new ClientSocketHandle()); - return transport_socket_handle_->Init(group_name(), - params_->transport_params(), - priority(), - callback_, - transport_pool_, - net_log()); -} +int HttpProxyConnectJob::HandleConnectResult(int result) { + if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) + error_response_info_ = client_socket_->GetAdditionalErrorState(); -int HttpProxyConnectJob::DoTransportConnectComplete(int result) { - if (result != OK) - return ERR_PROXY_CONNECTION_FAILED; - - // Reset the timer to just the length of time allowed for HttpProxy handshake - // so that a fast TCP connection plus a slow HttpProxy failure doesn't take - // longer to timeout than it should. - ResetTimer(base::TimeDelta::FromSeconds( - kHttpProxyConnectJobTimeoutInSeconds)); - - next_state_ = STATE_HTTP_PROXY_CONNECT; - return result; -} - -int HttpProxyConnectJob::DoSSLConnect() { - if (params_->tunnel()) { - SpdySessionKey key(params_->destination().host_port_pair(), - ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); - if (params_->spdy_session_pool()->FindAvailableSession(key, net_log())) { - using_spdy_ = true; - next_state_ = STATE_SPDY_PROXY_CREATE_STREAM; - return OK; - } - } - next_state_ = STATE_SSL_CONNECT_COMPLETE; - transport_socket_handle_.reset(new ClientSocketHandle()); - return transport_socket_handle_->Init( - group_name(), params_->ssl_params(), priority(), callback_, - ssl_pool_, net_log()); -} - -int HttpProxyConnectJob::DoSSLConnectComplete(int result) { - if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { - error_response_info_ = transport_socket_handle_->ssl_error_response_info(); - DCHECK(error_response_info_.cert_request_info.get()); - error_response_info_.cert_request_info->is_proxy = true; - return result; - } - if (IsCertificateError(result)) { - if (params_->ssl_params()->load_flags() & LOAD_IGNORE_ALL_CERT_ERRORS) { - result = OK; - } else { - // TODO(rch): allow the user to deal with proxy cert errors in the - // same way as server cert errors. - transport_socket_handle_->socket()->Disconnect(); - return ERR_PROXY_CERTIFICATE_INVALID; - } - } - // A SPDY session to the proxy completed prior to resolving the proxy - // hostname. Surface this error, and allow the delegate to retry. - // See crbug.com/334413. - if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { - DCHECK(!transport_socket_handle_->socket()); - return ERR_SPDY_SESSION_ALREADY_EXISTS; - } - if (result < 0) { - if (transport_socket_handle_->socket()) - transport_socket_handle_->socket()->Disconnect(); - return ERR_PROXY_CONNECTION_FAILED; - } - - SSLClientSocket* ssl = - static_cast<SSLClientSocket*>(transport_socket_handle_->socket()); - protocol_negotiated_ = ssl->GetNegotiatedProtocol(); - using_spdy_ = NextProtoIsSPDY(protocol_negotiated_); - - // Reset the timer to just the length of time allowed for HttpProxy handshake - // so that a fast SSL connection plus a slow HttpProxy failure doesn't take - // longer to timeout than it should. - ResetTimer(base::TimeDelta::FromSeconds( - kHttpProxyConnectJobTimeoutInSeconds)); - // TODO(rch): If we ever decide to implement a "trusted" SPDY proxy - // (one that we speak SPDY over SSL to, but to which we send HTTPS - // request directly instead of through CONNECT tunnels, then we - // need to add a predicate to this if statement so we fall through - // to the else case. (HttpProxyClientSocket currently acts as - // a "trusted" SPDY proxy). - if (using_spdy_ && params_->tunnel()) { - next_state_ = STATE_SPDY_PROXY_CREATE_STREAM; - } else { - next_state_ = STATE_HTTP_PROXY_CONNECT; - } - return result; -} - -int HttpProxyConnectJob::DoHttpProxyConnect() { - next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE; - const HostResolver::RequestInfo& tcp_destination = params_->destination(); - const HostPortPair& proxy_server = tcp_destination.host_port_pair(); - - // Add a HttpProxy connection on top of the tcp socket. - transport_socket_.reset( - new HttpProxyClientSocket(transport_socket_handle_.release(), - params_->user_agent(), - params_->endpoint(), - proxy_server, - params_->http_auth_cache(), - params_->http_auth_handler_factory(), - params_->tunnel(), - using_spdy_, - protocol_negotiated_, - params_->proxy_delegate(), - params_->ssl_params().get() != NULL)); - return transport_socket_->Connect(callback_); -} - -int HttpProxyConnectJob::DoHttpProxyConnectComplete(int result) { if (result == OK || result == ERR_PROXY_AUTH_REQUESTED || result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { - SetSocket(transport_socket_.Pass()); + SetSocket(client_socket_.Pass()); } - - if (result == ERR_HTTP_1_1_REQUIRED) - return ERR_PROXY_HTTP_1_1_REQUIRED; - return result; } -int HttpProxyConnectJob::DoSpdyProxyCreateStream() { - DCHECK(using_spdy_); - DCHECK(params_->tunnel()); - SpdySessionKey key(params_->destination().host_port_pair(), - ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); - SpdySessionPool* spdy_pool = params_->spdy_session_pool(); - base::WeakPtr<SpdySession> spdy_session = - spdy_pool->FindAvailableSession(key, net_log()); - // It's possible that a session to the proxy has recently been created - if (spdy_session) { - if (transport_socket_handle_.get()) { - if (transport_socket_handle_->socket()) - transport_socket_handle_->socket()->Disconnect(); - transport_socket_handle_->Reset(); - } - } else { - // Create a session direct to the proxy itself - spdy_session = - spdy_pool->CreateAvailableSessionFromSocket( - key, transport_socket_handle_.Pass(), - net_log(), OK, /*using_ssl_*/ true); - DCHECK(spdy_session); - } - - next_state_ = STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE; - return spdy_stream_request_.StartRequest( - SPDY_BIDIRECTIONAL_STREAM, spdy_session, - GURL("https://" + params_->endpoint().ToString()), priority(), - spdy_session->net_log(), callback_); -} - -int HttpProxyConnectJob::DoSpdyProxyCreateStreamComplete(int result) { - if (result < 0) - return result; - - next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE; - base::WeakPtr<SpdyStream> stream = spdy_stream_request_.ReleaseStream(); - DCHECK(stream.get()); - // |transport_socket_| will set itself as |stream|'s delegate. - transport_socket_.reset( - new SpdyProxyClientSocket(stream, - params_->user_agent(), - params_->endpoint(), - params_->destination().host_port_pair(), - net_log(), - params_->http_auth_cache(), - params_->http_auth_handler_factory())); - return transport_socket_->Connect(callback_); -} - -void HttpProxyConnectJob::NotifyProxyDelegateOfCompletion(int result) { - if (!params_->proxy_delegate()) - return; - - const HostPortPair& proxy_server = params_->destination().host_port_pair(); - params_->proxy_delegate()->OnTunnelConnectCompleted(params_->endpoint(), - proxy_server, - result); -} - -int HttpProxyConnectJob::ConnectInternal() { - if (params_->transport_params().get()) { - next_state_ = STATE_TCP_CONNECT; - } else { - next_state_ = STATE_SSL_CONNECT; - } - - int rv = DoLoop(OK); - if (rv != ERR_IO_PENDING) { - NotifyProxyDelegateOfCompletion(rv); - } - - return rv; -} - HttpProxyClientSocketPool:: HttpProxyConnectJobFactory::HttpProxyConnectJobFactory( TransportClientSocketPool* transport_pool,
diff --git a/net/http/http_proxy_client_socket_pool.h b/net/http/http_proxy_client_socket_pool.h index 1440fc7..9e550b6 100644 --- a/net/http/http_proxy_client_socket_pool.h +++ b/net/http/http_proxy_client_socket_pool.h
@@ -26,6 +26,7 @@ class HttpAuthCache; class HttpAuthHandlerFactory; +class HttpProxyClientSocketWrapper; class ProxyDelegate; class SSLClientSocketPool; class SSLSocketParams; @@ -113,39 +114,6 @@ void GetAdditionalErrorState(ClientSocketHandle* handle) override; private: - enum State { - STATE_TCP_CONNECT, - STATE_TCP_CONNECT_COMPLETE, - STATE_SSL_CONNECT, - STATE_SSL_CONNECT_COMPLETE, - STATE_HTTP_PROXY_CONNECT, - STATE_HTTP_PROXY_CONNECT_COMPLETE, - STATE_SPDY_PROXY_CREATE_STREAM, - STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE, - STATE_SPDY_PROXY_CONNECT_COMPLETE, - STATE_NONE, - }; - - void OnIOComplete(int result); - - // Runs the state transition loop. - int DoLoop(int result); - - // Connecting to HTTP Proxy - int DoTransportConnect(); - int DoTransportConnectComplete(int result); - // Connecting to HTTPS Proxy - int DoSSLConnect(); - int DoSSLConnectComplete(int result); - - int DoHttpProxyConnect(); - int DoHttpProxyConnectComplete(int result); - - int DoSpdyProxyCreateStream(); - int DoSpdyProxyCreateStreamComplete(int result); - - void NotifyProxyDelegateOfCompletion(int result); - // Begins the tcp connection and the optional Http proxy tunnel. If the // request is not immediately servicable (likely), the request will return // ERR_IO_PENDING. An OK return from this function or the callback means @@ -155,23 +123,13 @@ // a standard net error code will be returned. int ConnectInternal() override; - scoped_refptr<HttpProxySocketParams> params_; - TransportClientSocketPool* const transport_pool_; - SSLClientSocketPool* const ssl_pool_; + void OnConnectComplete(int result); - State next_state_; - CompletionCallback callback_; - scoped_ptr<ClientSocketHandle> transport_socket_handle_; - scoped_ptr<ProxyClientSocket> transport_socket_; - bool using_spdy_; - // Protocol negotiated with the server. - NextProto protocol_negotiated_; + int HandleConnectResult(int result); - HttpResponseInfo error_response_info_; + scoped_ptr<HttpProxyClientSocketWrapper> client_socket_; - SpdyStreamRequest spdy_stream_request_; - - base::WeakPtrFactory<HttpProxyConnectJob> weak_ptr_factory_; + scoped_ptr<HttpResponseInfo> error_response_info_; DISALLOW_COPY_AND_ASSIGN(HttpProxyConnectJob); };
diff --git a/net/http/http_proxy_client_socket_wrapper.cc b/net/http/http_proxy_client_socket_wrapper.cc new file mode 100644 index 0000000..40acc5c --- /dev/null +++ b/net/http/http_proxy_client_socket_wrapper.cc
@@ -0,0 +1,630 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/http/http_proxy_client_socket_wrapper.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/callback_helpers.h" +#include "base/memory/weak_ptr.h" +#include "base/profiler/scoped_tracker.h" +#include "base/values.h" +#include "net/base/net_util.h" +#include "net/base/proxy_delegate.h" +#include "net/http/http_proxy_client_socket.h" +#include "net/http/http_response_info.h" +#include "net/socket/client_socket_handle.h" +#include "net/spdy/spdy_proxy_client_socket.h" +#include "net/spdy/spdy_session.h" +#include "net/spdy/spdy_session_pool.h" +#include "net/spdy/spdy_stream.h" +#include "net/ssl/ssl_cert_request_info.h" +#include "url/gurl.h" + +namespace net { + +HttpProxyClientSocketWrapper::HttpProxyClientSocketWrapper( + const std::string& group_name, + RequestPriority priority, + base::TimeDelta connect_timeout_duration, + base::TimeDelta proxy_negotiation_timeout_duration, + TransportClientSocketPool* transport_pool, + SSLClientSocketPool* ssl_pool, + const scoped_refptr<TransportSocketParams>& transport_params, + const scoped_refptr<SSLSocketParams>& ssl_params, + const std::string& user_agent, + const HostPortPair& endpoint, + HttpAuthCache* http_auth_cache, + HttpAuthHandlerFactory* http_auth_handler_factory, + SpdySessionPool* spdy_session_pool, + bool tunnel, + ProxyDelegate* proxy_delegate, + const BoundNetLog& net_log) + : next_state_(STATE_NONE), + group_name_(group_name), + priority_(priority), + connect_timeout_duration_(connect_timeout_duration), + proxy_negotiation_timeout_duration_(proxy_negotiation_timeout_duration), + transport_pool_(transport_pool), + ssl_pool_(ssl_pool), + transport_params_(transport_params), + ssl_params_(ssl_params), + user_agent_(user_agent), + endpoint_(endpoint), + http_auth_cache_(http_auth_cache), + http_auth_handler_factory_(http_auth_handler_factory), + spdy_session_pool_(spdy_session_pool), + tunnel_(tunnel), + proxy_delegate_(proxy_delegate), + using_spdy_(false), + http_auth_controller_( + tunnel ? new HttpAuthController( + HttpAuth::AUTH_PROXY, + GURL((ssl_params_.get() ? "https://" : "http://") + + GetDestination().host_port_pair().ToString()), + http_auth_cache, + http_auth_handler_factory) + : nullptr), + net_log_(BoundNetLog::Make(net_log.net_log(), + NetLog::SOURCE_PROXY_CLIENT_SOCKET_WRAPPER)) { + net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, + net_log.source().ToEventParametersCallback()); + DCHECK(transport_params || ssl_params); + DCHECK(!transport_params || !ssl_params); +} + +HttpProxyClientSocketWrapper::~HttpProxyClientSocketWrapper() { + // Make sure no sockets are returned to the lower level socket pools. + Disconnect(); + + net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); +} + +LoadState HttpProxyClientSocketWrapper::GetConnectLoadState() const { + switch (next_state_) { + case STATE_BEGIN_CONNECT: + case STATE_TCP_CONNECT: + case STATE_TCP_CONNECT_COMPLETE: + case STATE_SSL_CONNECT: + case STATE_SSL_CONNECT_COMPLETE: + return transport_socket_handle_->GetLoadState(); + case STATE_HTTP_PROXY_CONNECT: + case STATE_HTTP_PROXY_CONNECT_COMPLETE: + case STATE_SPDY_PROXY_CREATE_STREAM: + case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE: + case STATE_SPDY_PROXY_CONNECT_COMPLETE: + case STATE_RESTART_WITH_AUTH: + case STATE_RESTART_WITH_AUTH_COMPLETE: + return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL; + case STATE_NONE: + // May be possible for this method to be called after an error, shouldn't + // be called after a successful connect. + break; + } + return LOAD_STATE_IDLE; +} + +scoped_ptr<HttpResponseInfo> +HttpProxyClientSocketWrapper::GetAdditionalErrorState() { + return error_response_info_.Pass(); +} + +const HttpResponseInfo* HttpProxyClientSocketWrapper::GetConnectResponseInfo() + const { + if (transport_socket_) + return transport_socket_->GetConnectResponseInfo(); + return nullptr; +} + +HttpStream* HttpProxyClientSocketWrapper::CreateConnectResponseStream() { + if (transport_socket_) + return transport_socket_->CreateConnectResponseStream(); + return nullptr; +} + +int HttpProxyClientSocketWrapper::RestartWithAuth( + const CompletionCallback& callback) { + DCHECK(!callback.is_null()); + DCHECK(connect_callback_.is_null()); + DCHECK(transport_socket_); + DCHECK_EQ(STATE_NONE, next_state_); + + connect_callback_ = callback; + next_state_ = STATE_RESTART_WITH_AUTH; + return DoLoop(OK); +} + +const scoped_refptr<HttpAuthController>& +HttpProxyClientSocketWrapper::GetAuthController() const { + return http_auth_controller_; +} + +bool HttpProxyClientSocketWrapper::IsUsingSpdy() const { + if (transport_socket_) + return transport_socket_->IsUsingSpdy(); + return false; +} + +NextProto HttpProxyClientSocketWrapper::GetProtocolNegotiated() const { + if (transport_socket_) + return transport_socket_->GetProtocolNegotiated(); + return kProtoUnknown; +} + +int HttpProxyClientSocketWrapper::Connect(const CompletionCallback& callback) { + DCHECK(!callback.is_null()); + DCHECK(connect_callback_.is_null()); + + // If connecting or previously connected and not disconnected, return OK, to + // match TCPClientSocket's behavior. + if (next_state_ != STATE_NONE || transport_socket_) + return OK; + + next_state_ = STATE_BEGIN_CONNECT; + int rv = DoLoop(OK); + if (rv == ERR_IO_PENDING) { + connect_callback_ = callback; + } else { + connect_timer_.Stop(); + NotifyProxyDelegateOfCompletion(rv); + } + + return rv; +} + +void HttpProxyClientSocketWrapper::Disconnect() { + connect_callback_.Reset(); + connect_timer_.Stop(); + next_state_ = STATE_NONE; + spdy_stream_request_.CancelRequest(); + if (transport_socket_handle_) { + if (transport_socket_handle_->socket()) + transport_socket_handle_->socket()->Disconnect(); + transport_socket_handle_->Reset(); + transport_socket_handle_.reset(); + } + + if (transport_socket_) + transport_socket_->Disconnect(); +} + +bool HttpProxyClientSocketWrapper::IsConnected() const { + if (transport_socket_) + return transport_socket_->IsConnected(); + // Don't return true if still connecting. Shouldn't really matter, either + // way. + return false; +} + +bool HttpProxyClientSocketWrapper::IsConnectedAndIdle() const { + if (transport_socket_) + return transport_socket_->IsConnectedAndIdle(); + return false; +} + +const BoundNetLog& HttpProxyClientSocketWrapper::NetLog() const { + return net_log_; +} + +void HttpProxyClientSocketWrapper::SetSubresourceSpeculation() { + // This flag isn't passed to reconnected sockets, as only the first connection + // can be a preconnect. + if (transport_socket_) + transport_socket_->SetSubresourceSpeculation(); +} + +void HttpProxyClientSocketWrapper::SetOmniboxSpeculation() { + // This flag isn't passed to reconnected sockets, as only the first connection + // can be a preconnect. + if (transport_socket_) + transport_socket_->SetOmniboxSpeculation(); +} + +bool HttpProxyClientSocketWrapper::WasEverUsed() const { + // TODO(mmenke): This is a little weird. Figure out if something else should + // be done. + if (transport_socket_) + return transport_socket_->WasEverUsed(); + return false; +} + +bool HttpProxyClientSocketWrapper::UsingTCPFastOpen() const { + if (transport_socket_) + return transport_socket_->UsingTCPFastOpen(); + return false; +} + +bool HttpProxyClientSocketWrapper::WasNpnNegotiated() const { + if (transport_socket_) + return transport_socket_->WasNpnNegotiated(); + return false; +} + +NextProto HttpProxyClientSocketWrapper::GetNegotiatedProtocol() const { + if (transport_socket_) + return transport_socket_->GetNegotiatedProtocol(); + return kProtoUnknown; +} + +bool HttpProxyClientSocketWrapper::GetSSLInfo(SSLInfo* ssl_info) { + if (transport_socket_) + return transport_socket_->GetSSLInfo(ssl_info); + return false; +} + +void HttpProxyClientSocketWrapper::GetConnectionAttempts( + ConnectionAttempts* out) const { + // TODO(mmenke): Not clear how reconnecting for auth fits into things. + if (transport_socket_) { + transport_socket_->GetConnectionAttempts(out); + } else { + out->clear(); + } +} + +void HttpProxyClientSocketWrapper::ClearConnectionAttempts() { + if (transport_socket_) + transport_socket_->ClearConnectionAttempts(); +} + +void HttpProxyClientSocketWrapper::AddConnectionAttempts( + const ConnectionAttempts& attempts) { + if (transport_socket_) + transport_socket_->AddConnectionAttempts(attempts); +} + +int HttpProxyClientSocketWrapper::Read(IOBuffer* buf, + int buf_len, + const CompletionCallback& callback) { + if (transport_socket_) + return transport_socket_->Read(buf, buf_len, callback); + return ERR_SOCKET_NOT_CONNECTED; +} + +int HttpProxyClientSocketWrapper::Write(IOBuffer* buf, + int buf_len, + const CompletionCallback& callback) { + if (transport_socket_) + return transport_socket_->Write(buf, buf_len, callback); + return ERR_SOCKET_NOT_CONNECTED; +} + +int HttpProxyClientSocketWrapper::SetReceiveBufferSize(int32 size) { + // TODO(mmenke): Should this persist across reconnects? Seems a little + // weird, and not done for normal reconnects. + if (transport_socket_) + return transport_socket_->SetReceiveBufferSize(size); + return ERR_SOCKET_NOT_CONNECTED; +} + +int HttpProxyClientSocketWrapper::SetSendBufferSize(int32 size) { + if (transport_socket_) + return transport_socket_->SetSendBufferSize(size); + return ERR_SOCKET_NOT_CONNECTED; +} + +int HttpProxyClientSocketWrapper::GetPeerAddress(IPEndPoint* address) const { + if (transport_socket_) + return transport_socket_->GetPeerAddress(address); + return ERR_SOCKET_NOT_CONNECTED; +} + +int HttpProxyClientSocketWrapper::GetLocalAddress(IPEndPoint* address) const { + if (transport_socket_) + return transport_socket_->GetLocalAddress(address); + return ERR_SOCKET_NOT_CONNECTED; +} + +void HttpProxyClientSocketWrapper::OnIOComplete(int result) { + int rv = DoLoop(result); + if (rv != ERR_IO_PENDING) { + connect_timer_.Stop(); + NotifyProxyDelegateOfCompletion(rv); + // May delete |this|. + base::ResetAndReturn(&connect_callback_).Run(rv); + } +} + +int HttpProxyClientSocketWrapper::DoLoop(int result) { + DCHECK_NE(next_state_, STATE_NONE); + + int rv = result; + do { + State state = next_state_; + next_state_ = STATE_NONE; + switch (state) { + case STATE_BEGIN_CONNECT: + DCHECK_EQ(OK, rv); + rv = DoBeginConnect(); + break; + case STATE_TCP_CONNECT: + DCHECK_EQ(OK, rv); + rv = DoTransportConnect(); + break; + case STATE_TCP_CONNECT_COMPLETE: + rv = DoTransportConnectComplete(rv); + break; + case STATE_SSL_CONNECT: + DCHECK_EQ(OK, rv); + rv = DoSSLConnect(); + break; + case STATE_SSL_CONNECT_COMPLETE: + rv = DoSSLConnectComplete(rv); + break; + case STATE_HTTP_PROXY_CONNECT: + DCHECK_EQ(OK, rv); + rv = DoHttpProxyConnect(); + break; + case STATE_HTTP_PROXY_CONNECT_COMPLETE: + rv = DoHttpProxyConnectComplete(rv); + break; + case STATE_SPDY_PROXY_CREATE_STREAM: + DCHECK_EQ(OK, rv); + rv = DoSpdyProxyCreateStream(); + break; + case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE: + rv = DoSpdyProxyCreateStreamComplete(rv); + break; + case STATE_RESTART_WITH_AUTH: + DCHECK_EQ(OK, rv); + rv = DoRestartWithAuth(); + break; + case STATE_RESTART_WITH_AUTH_COMPLETE: + rv = DoRestartWithAuthComplete(rv); + break; + default: + NOTREACHED() << "bad state"; + rv = ERR_FAILED; + break; + } + } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); + + return rv; +} + +int HttpProxyClientSocketWrapper::DoBeginConnect() { + SetConnectTimer(connect_timeout_duration_); + if (transport_params_) { + next_state_ = STATE_TCP_CONNECT; + } else { + next_state_ = STATE_SSL_CONNECT; + } + + return OK; +} + +int HttpProxyClientSocketWrapper::DoTransportConnect() { + next_state_ = STATE_TCP_CONNECT_COMPLETE; + transport_socket_handle_.reset(new ClientSocketHandle()); + return transport_socket_handle_->Init( + group_name_, transport_params_, priority_, + base::Bind(&HttpProxyClientSocketWrapper::OnIOComplete, + base::Unretained(this)), + transport_pool_, net_log_); +} + +int HttpProxyClientSocketWrapper::DoTransportConnectComplete(int result) { + if (result != OK) + return ERR_PROXY_CONNECTION_FAILED; + + // Reset the timer to just the length of time allowed for HttpProxy handshake + // so that a fast TCP connection plus a slow HttpProxy failure doesn't take + // longer to timeout than it should. + SetConnectTimer(proxy_negotiation_timeout_duration_); + + next_state_ = STATE_HTTP_PROXY_CONNECT; + return result; +} + +int HttpProxyClientSocketWrapper::DoSSLConnect() { + if (tunnel_) { + SpdySessionKey key(GetDestination().host_port_pair(), ProxyServer::Direct(), + PRIVACY_MODE_DISABLED); + if (spdy_session_pool_->FindAvailableSession(key, net_log_)) { + using_spdy_ = true; + next_state_ = STATE_SPDY_PROXY_CREATE_STREAM; + return OK; + } + } + next_state_ = STATE_SSL_CONNECT_COMPLETE; + transport_socket_handle_.reset(new ClientSocketHandle()); + return transport_socket_handle_->Init( + group_name_, ssl_params_, priority_, + base::Bind(&HttpProxyClientSocketWrapper::OnIOComplete, + base::Unretained(this)), + ssl_pool_, net_log_); +} + +int HttpProxyClientSocketWrapper::DoSSLConnectComplete(int result) { + if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { + DCHECK( + transport_socket_handle_->ssl_error_response_info().cert_request_info); + error_response_info_.reset(new HttpResponseInfo( + transport_socket_handle_->ssl_error_response_info())); + error_response_info_->cert_request_info->is_proxy = true; + return result; + } + + if (IsCertificateError(result)) { + if (ssl_params_->load_flags() & LOAD_IGNORE_ALL_CERT_ERRORS) { + result = OK; + } else { + // TODO(rch): allow the user to deal with proxy cert errors in the + // same way as server cert errors. + transport_socket_handle_->socket()->Disconnect(); + return ERR_PROXY_CERTIFICATE_INVALID; + } + } + // A SPDY session to the proxy completed prior to resolving the proxy + // hostname. Surface this error, and allow the delegate to retry. + // See crbug.com/334413. + if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { + DCHECK(!transport_socket_handle_->socket()); + return ERR_SPDY_SESSION_ALREADY_EXISTS; + } + if (result < 0) { + if (transport_socket_handle_->socket()) + transport_socket_handle_->socket()->Disconnect(); + return ERR_PROXY_CONNECTION_FAILED; + } + + SSLClientSocket* ssl = + static_cast<SSLClientSocket*>(transport_socket_handle_->socket()); + protocol_negotiated_ = ssl->GetNegotiatedProtocol(); + using_spdy_ = NextProtoIsSPDY(protocol_negotiated_); + + // Reset the timer to just the length of time allowed for HttpProxy handshake + // so that a fast SSL connection plus a slow HttpProxy failure doesn't take + // longer to timeout than it should. + SetConnectTimer(proxy_negotiation_timeout_duration_); + + // TODO(rch): If we ever decide to implement a "trusted" SPDY proxy + // (one that we speak SPDY over SSL to, but to which we send HTTPS + // request directly instead of through CONNECT tunnels, then we + // need to add a predicate to this if statement so we fall through + // to the else case. (HttpProxyClientSocket currently acts as + // a "trusted" SPDY proxy). + if (using_spdy_ && tunnel_) { + next_state_ = STATE_SPDY_PROXY_CREATE_STREAM; + } else { + next_state_ = STATE_HTTP_PROXY_CONNECT; + } + return result; +} + +int HttpProxyClientSocketWrapper::DoHttpProxyConnect() { + next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE; + + // Add a HttpProxy connection on top of the tcp socket. + transport_socket_.reset(new HttpProxyClientSocket( + transport_socket_handle_.release(), user_agent_, endpoint_, + GetDestination().host_port_pair(), http_auth_controller_.get(), tunnel_, + using_spdy_, protocol_negotiated_, proxy_delegate_, + ssl_params_.get() != nullptr)); + return transport_socket_->Connect(base::Bind( + &HttpProxyClientSocketWrapper::OnIOComplete, base::Unretained(this))); +} + +int HttpProxyClientSocketWrapper::DoHttpProxyConnectComplete(int result) { + if (result == ERR_HTTP_1_1_REQUIRED) + return ERR_PROXY_HTTP_1_1_REQUIRED; + + return result; +} + +int HttpProxyClientSocketWrapper::DoSpdyProxyCreateStream() { + DCHECK(using_spdy_); + DCHECK(tunnel_); + SpdySessionKey key(GetDestination().host_port_pair(), ProxyServer::Direct(), + PRIVACY_MODE_DISABLED); + base::WeakPtr<SpdySession> spdy_session = + spdy_session_pool_->FindAvailableSession(key, net_log_); + // It's possible that a session to the proxy has recently been created + if (spdy_session) { + if (transport_socket_handle_.get()) { + if (transport_socket_handle_->socket()) + transport_socket_handle_->socket()->Disconnect(); + transport_socket_handle_->Reset(); + } + } else { + // Create a session direct to the proxy itself + spdy_session = spdy_session_pool_->CreateAvailableSessionFromSocket( + key, transport_socket_handle_.Pass(), net_log_, OK, + /*using_ssl_*/ true); + DCHECK(spdy_session); + } + + next_state_ = STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE; + return spdy_stream_request_.StartRequest( + SPDY_BIDIRECTIONAL_STREAM, spdy_session, + GURL("https://" + endpoint_.ToString()), priority_, + spdy_session->net_log(), + base::Bind(&HttpProxyClientSocketWrapper::OnIOComplete, + base::Unretained(this))); +} + +int HttpProxyClientSocketWrapper::DoSpdyProxyCreateStreamComplete(int result) { + if (result < 0) + return result; + + next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE; + base::WeakPtr<SpdyStream> stream = spdy_stream_request_.ReleaseStream(); + DCHECK(stream.get()); + // |transport_socket_| will set itself as |stream|'s delegate. + transport_socket_.reset(new SpdyProxyClientSocket( + stream, user_agent_, endpoint_, GetDestination().host_port_pair(), + net_log_, http_auth_controller_.get())); + return transport_socket_->Connect(base::Bind( + &HttpProxyClientSocketWrapper::OnIOComplete, base::Unretained(this))); +} + +int HttpProxyClientSocketWrapper::DoRestartWithAuth() { + DCHECK(transport_socket_); + + next_state_ = STATE_RESTART_WITH_AUTH_COMPLETE; + return transport_socket_->RestartWithAuth(base::Bind( + &HttpProxyClientSocketWrapper::OnIOComplete, base::Unretained(this))); +} + +int HttpProxyClientSocketWrapper::DoRestartWithAuthComplete(int result) { + DCHECK_NE(ERR_IO_PENDING, result); + // If the connection could not be reused to attempt to send proxy auth + // credentials, try reconnecting. If auth credentials were sent, pass the + // error on to caller, even if the credentials may have passed a close message + // from the server in flight. + if (result == ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH) { + // If can't reuse the connection, attempt to create a new one. + transport_socket_.reset(); + // Reconnect with HIGHEST priority to get in front of other requests that + // don't yet have the information |http_auth_controller_| does. + // TODO(mmenke): This may still result in waiting in line, if there are + // other HIGHEST priority requests. Consider a workaround for + // that. Starting the new request before releasing the old + // socket and using LOAD_IGNORE_LIMITS would do the trick, + // without exceding the the socket pool limits (Since the old + // socket would free up the extra socket slot when destroyed). + priority_ = HIGHEST; + next_state_ = STATE_BEGIN_CONNECT; + return OK; + } + + return result; +} + +void HttpProxyClientSocketWrapper::NotifyProxyDelegateOfCompletion(int result) { + if (!proxy_delegate_) + return; + + const HostPortPair& proxy_server = GetDestination().host_port_pair(); + proxy_delegate_->OnTunnelConnectCompleted(endpoint_, proxy_server, result); +} + +void HttpProxyClientSocketWrapper::SetConnectTimer(base::TimeDelta delay) { + connect_timer_.Stop(); + connect_timer_.Start(FROM_HERE, delay, this, + &HttpProxyClientSocketWrapper::ConnectTimeout); +} + +void HttpProxyClientSocketWrapper::ConnectTimeout() { + // Timer shouldn't be running if next_state_ is STATE_NONE. + DCHECK_NE(STATE_NONE, next_state_); + DCHECK(!connect_callback_.is_null()); + + NotifyProxyDelegateOfCompletion(ERR_CONNECTION_TIMED_OUT); + + CompletionCallback callback = connect_callback_; + Disconnect(); + callback.Run(ERR_CONNECTION_TIMED_OUT); +} + +const HostResolver::RequestInfo& +HttpProxyClientSocketWrapper::GetDestination() { + if (transport_params_) { + return transport_params_->destination(); + } else { + return ssl_params_->GetDirectConnectionParams()->destination(); + } +} + +} // namespace net
diff --git a/net/http/http_proxy_client_socket_wrapper.h b/net/http/http_proxy_client_socket_wrapper.h new file mode 100644 index 0000000..b3bfa29 --- /dev/null +++ b/net/http/http_proxy_client_socket_wrapper.h
@@ -0,0 +1,211 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_WRAPPER_H_ +#define NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_WRAPPER_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/time/time.h" +#include "base/timer/timer.h" +#include "net/base/completion_callback.h" +#include "net/base/host_port_pair.h" +#include "net/base/load_timing_info.h" +#include "net/http/http_auth_controller.h" +#include "net/http/proxy_client_socket.h" +#include "net/log/net_log.h" +#include "net/socket/next_proto.h" +#include "net/socket/ssl_client_socket.h" +#include "net/socket/ssl_client_socket_pool.h" +#include "net/socket/transport_client_socket_pool.h" +#include "net/spdy/spdy_session.h" + +namespace net { + +class ClientSocketHandle; +class IOBuffer; +class HttpAuthCache; +class HttpResponseInfo; +class HttpStream; +class IOBuffer; +class ProxyDelegate; +class SpdySessionPool; +class SSLClientSocketPool; +class TransportClientSocketPool; + +// Class that establishes connections by calling into the lower layer socket +// pools, creates a HttpProxyClientSocket / SpdyProxyClientSocket, and then +// wraps the resulting socket. +// +// This class is needed to handle auth state across multiple connection. On +// auth challenge, this class retains auth state in its AuthController, and can +// either send the auth response to the old connection, or establish a new +// connection and send the response there. +// +// TODO(mmenke): Ideally, we'd have a central location store auth state across +// multiple connections to the same server instead. +class HttpProxyClientSocketWrapper : public ProxyClientSocket { + public: + HttpProxyClientSocketWrapper( + const std::string& group_name, + RequestPriority priority, + base::TimeDelta connect_timeout_duration, + base::TimeDelta proxy_negotiation_timeout_duration, + TransportClientSocketPool* transport_pool, + SSLClientSocketPool* ssl_pool, + const scoped_refptr<TransportSocketParams>& transport_params, + const scoped_refptr<SSLSocketParams>& ssl_params, + const std::string& user_agent, + const HostPortPair& endpoint, + HttpAuthCache* http_auth_cache, + HttpAuthHandlerFactory* http_auth_handler_factory, + SpdySessionPool* spdy_session_pool, + bool tunnel, + ProxyDelegate* proxy_delegate, + const BoundNetLog& net_log); + + // On destruction Disconnect() is called. + ~HttpProxyClientSocketWrapper() override; + + // Returns load state while establishing a connection. Returns + // LOAD_STATE_IDLE at other times. + LoadState GetConnectLoadState() const; + + scoped_ptr<HttpResponseInfo> GetAdditionalErrorState(); + + // ProxyClientSocket implementation. + const HttpResponseInfo* GetConnectResponseInfo() const override; + HttpStream* CreateConnectResponseStream() override; + int RestartWithAuth(const CompletionCallback& callback) override; + const scoped_refptr<HttpAuthController>& GetAuthController() const override; + bool IsUsingSpdy() const override; + NextProto GetProtocolNegotiated() const override; + + // StreamSocket implementation. + int Connect(const CompletionCallback& callback) override; + void Disconnect() override; + bool IsConnected() const override; + bool IsConnectedAndIdle() const override; + const BoundNetLog& NetLog() const override; + void SetSubresourceSpeculation() override; + void SetOmniboxSpeculation() override; + bool WasEverUsed() const override; + bool UsingTCPFastOpen() const override; + bool WasNpnNegotiated() const override; + NextProto GetNegotiatedProtocol() const override; + bool GetSSLInfo(SSLInfo* ssl_info) override; + void GetConnectionAttempts(ConnectionAttempts* out) const override; + void ClearConnectionAttempts() override; + void AddConnectionAttempts(const ConnectionAttempts& attempts) override; + + // Socket implementation. + int Read(IOBuffer* buf, + int buf_len, + const CompletionCallback& callback) override; + int Write(IOBuffer* buf, + int buf_len, + const CompletionCallback& callback) override; + int SetReceiveBufferSize(int32 size) override; + int SetSendBufferSize(int32 size) override; + int GetPeerAddress(IPEndPoint* address) const override; + int GetLocalAddress(IPEndPoint* address) const override; + + private: + enum State { + STATE_BEGIN_CONNECT, + STATE_TCP_CONNECT, + STATE_TCP_CONNECT_COMPLETE, + STATE_SSL_CONNECT, + STATE_SSL_CONNECT_COMPLETE, + STATE_HTTP_PROXY_CONNECT, + STATE_HTTP_PROXY_CONNECT_COMPLETE, + STATE_SPDY_PROXY_CREATE_STREAM, + STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE, + STATE_SPDY_PROXY_CONNECT_COMPLETE, + STATE_RESTART_WITH_AUTH, + STATE_RESTART_WITH_AUTH_COMPLETE, + STATE_NONE, + }; + + void OnIOComplete(int result); + + // Runs the state transition loop. + int DoLoop(int result); + + // Determine if need to go through TCP or SSL path. + int DoBeginConnect(); + // Connecting to HTTP Proxy + int DoTransportConnect(); + int DoTransportConnectComplete(int result); + // Connecting to HTTPS Proxy + int DoSSLConnect(); + int DoSSLConnectComplete(int result); + + int DoHttpProxyConnect(); + int DoHttpProxyConnectComplete(int result); + + int DoSpdyProxyCreateStream(); + int DoSpdyProxyCreateStreamComplete(int result); + + int DoRestartWithAuth(); + int DoRestartWithAuthComplete(int result); + + void NotifyProxyDelegateOfCompletion(int result); + + void SetConnectTimer(base::TimeDelta duration); + void ConnectTimeout(); + + const HostResolver::RequestInfo& GetDestination(); + + State next_state_; + + const std::string group_name_; + RequestPriority priority_; + const base::TimeDelta connect_timeout_duration_; + const base::TimeDelta proxy_negotiation_timeout_duration_; + + TransportClientSocketPool* const transport_pool_; + SSLClientSocketPool* const ssl_pool_; + const scoped_refptr<TransportSocketParams> transport_params_; + const scoped_refptr<SSLSocketParams> ssl_params_; + + const std::string user_agent_; + const HostPortPair endpoint_; + HttpAuthCache* const http_auth_cache_; + HttpAuthHandlerFactory* const http_auth_handler_factory_; + SpdySessionPool* const spdy_session_pool_; + + const bool tunnel_; + ProxyDelegate* const proxy_delegate_; + + bool using_spdy_; + NextProto protocol_negotiated_; + + scoped_ptr<HttpResponseInfo> error_response_info_; + + scoped_ptr<ClientSocketHandle> transport_socket_handle_; + scoped_ptr<ProxyClientSocket> transport_socket_; + + // Called when a connection is established. Also used when restarting with + // AUTH, which will invoke this when ready to restart, after reconnecting + // if necessary. + CompletionCallback connect_callback_; + + SpdyStreamRequest spdy_stream_request_; + + scoped_refptr<HttpAuthController> http_auth_controller_; + + BoundNetLog net_log_; + + base::OneShotTimer connect_timer_; + + DISALLOW_COPY_AND_ASSIGN(HttpProxyClientSocketWrapper); +}; + +} // namespace net + +#endif // NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_WRAPPER_H_
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc index b27b44e..3625e4a 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_factory_impl_job.cc
@@ -1293,15 +1293,6 @@ return OK; } - if (result == ERR_CONNECTION_CLOSED || result == ERR_CONNECTION_RESET || - result == ERR_SOCKET_NOT_CONNECTED) { - // The server may have closed the connection while waiting for auth data. - // Automatically try to use a new connection. - establishing_tunnel_ = false; - ReturnToStateInitConnection(true /* close connection */); - return OK; - } - return ReconsiderProxyAfterError(result); }
diff --git a/net/log/net_log_source_type_list.h b/net/log/net_log_source_type_list.h index 79af389..63feed8 100644 --- a/net/log/net_log_source_type_list.h +++ b/net/log/net_log_source_type_list.h
@@ -25,6 +25,7 @@ SOURCE_TYPE(FILESTREAM) SOURCE_TYPE(DNS_PROBER) SOURCE_TYPE(PROXY_CLIENT_SOCKET) +SOURCE_TYPE(PROXY_CLIENT_SOCKET_WRAPPER) SOURCE_TYPE(DATA_REDUCTION_PROXY) SOURCE_TYPE(IOS_WEB_VIEW_CERT_VERIFIER) SOURCE_TYPE(SAFE_BROWSING)
diff --git a/net/net.gypi b/net/net.gypi index 1c2ec2d..a6e27b3 100644 --- a/net/net.gypi +++ b/net/net.gypi
@@ -409,8 +409,6 @@ 'base/crypto_module_openssl.cc', 'base/data_url.cc', 'base/data_url.h', - 'base/dns_reloader.cc', - 'base/dns_reloader.h', 'base/elements_upload_data_stream.cc', 'base/elements_upload_data_stream.h', 'base/expiring_cache.h', @@ -742,6 +740,8 @@ 'dns/dns_protocol.h', 'dns/dns_query.cc', 'dns/dns_query.h', + 'dns/dns_reloader.cc', + 'dns/dns_reloader.h', 'dns/dns_response.cc', 'dns/dns_response.h', 'dns/dns_session.cc', @@ -845,6 +845,8 @@ 'http/http_proxy_client_socket.h', 'http/http_proxy_client_socket_pool.cc', 'http/http_proxy_client_socket_pool.h', + 'http/http_proxy_client_socket_wrapper.cc', + 'http/http_proxy_client_socket_wrapper.h', 'http/http_request_info.cc', 'http/http_request_info.h', 'http/http_response_body_drainer.cc',
diff --git a/net/spdy/spdy_proxy_client_socket.cc b/net/spdy/spdy_proxy_client_socket.cc index e6d521e..6c28026d 100644 --- a/net/spdy/spdy_proxy_client_socket.cc +++ b/net/spdy/spdy_proxy_client_socket.cc
@@ -34,15 +34,11 @@ const HostPortPair& endpoint, const HostPortPair& proxy_server, const BoundNetLog& source_net_log, - HttpAuthCache* auth_cache, - HttpAuthHandlerFactory* auth_handler_factory) + HttpAuthController* auth_controller) : next_state_(STATE_DISCONNECTED), spdy_stream_(spdy_stream), endpoint_(endpoint), - auth_(new HttpAuthController(HttpAuth::AUTH_PROXY, - GURL("https://" + proxy_server.ToString()), - auth_cache, - auth_handler_factory)), + auth_(auth_controller), user_agent_(user_agent), user_buffer_len_(0), write_buffer_len_(0),
diff --git a/net/spdy/spdy_proxy_client_socket.h b/net/spdy/spdy_proxy_client_socket.h index af38767..c3dd2a3 100644 --- a/net/spdy/spdy_proxy_client_socket.h +++ b/net/spdy/spdy_proxy_client_socket.h
@@ -45,9 +45,7 @@ const HostPortPair& endpoint, const HostPortPair& proxy_server, const BoundNetLog& source_net_log, - HttpAuthCache* auth_cache, - HttpAuthHandlerFactory* auth_handler_factory); - + HttpAuthController* auth_controller); // On destruction Disconnect() is called. ~SpdyProxyClientSocket() override;
diff --git a/net/spdy/spdy_proxy_client_socket_unittest.cc b/net/spdy/spdy_proxy_client_socket_unittest.cc index b8f62cf..de9cb0d 100644 --- a/net/spdy/spdy_proxy_client_socket_unittest.cc +++ b/net/spdy/spdy_proxy_client_socket_unittest.cc
@@ -201,8 +201,10 @@ // Create the SpdyProxyClientSocket. sock_.reset(new SpdyProxyClientSocket( spdy_stream, user_agent_, endpoint_host_port_pair_, proxy_host_port_, - net_log_.bound(), session_->http_auth_cache(), - session_->http_auth_handler_factory())); + net_log_.bound(), + new HttpAuthController( + HttpAuth::AUTH_PROXY, GURL("https://" + proxy_host_port_.ToString()), + session_->http_auth_cache(), session_->http_auth_handler_factory()))); } scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer(
diff --git a/net/tools/epoll_server/epoll_server.cc b/net/tools/epoll_server/epoll_server.cc index 7b60ce2..aa1c2da 100644 --- a/net/tools/epoll_server/epoll_server.cc +++ b/net/tools/epoll_server/epoll_server.cc
@@ -221,12 +221,8 @@ cb->OnRegistration(this, fd, event_mask); } -int EpollServer::GetFlags(int fd) { - return fcntl(fd, F_GETFL, 0); -} - void EpollServer::SetNonblocking(int fd) { - int flags = GetFlags(fd); + int flags = fcntl(fd, F_GETFL, 0); if (flags == -1) { int saved_errno = errno; char buf[kErrorBufferSize]; @@ -236,7 +232,7 @@ } if (!(flags & O_NONBLOCK)) { int saved_flags = flags; - flags = SetFlags(fd, flags | O_NONBLOCK); + flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK); if (flags == -1) { // bad. int saved_errno = errno;
diff --git a/net/tools/epoll_server/epoll_server.h b/net/tools/epoll_server/epoll_server.h index 139ae27..b241861 100644 --- a/net/tools/epoll_server/epoll_server.h +++ b/net/tools/epoll_server/epoll_server.h
@@ -487,11 +487,6 @@ void CallReadyListCallbacks(); protected: - virtual int GetFlags(int fd); - inline int SetFlags(int fd, int flags) { - return fcntl(fd, F_SETFL, flags | O_NONBLOCK); - } - virtual void SetNonblocking(int fd); // This exists here so that we can override this function in unittests
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc index f23a3bbd..641c07b 100644 --- a/net/url_request/url_request_job.cc +++ b/net/url_request/url_request_job.cc
@@ -401,7 +401,9 @@ // This should not be called on error, and the job type should have cleared // IO_PENDING state before calling this method. - DCHECK(request_->status().is_success()); + // TODO(mmenke): Change this to a DCHECK once https://crbug.com/508900 is + // resolved. + CHECK(request_->status().is_success()); // Initialize to the current time, and let the subclass optionally override // the time stamps if it has that information. The default request_time is @@ -792,9 +794,11 @@ // An error status should never be replaced by a non-error status by a // URLRequestJob. URLRequest has some retry paths, but it resets the status // itself, if needed. - DCHECK(request_->status().is_io_pending() || - request_->status().is_success() || - (!status.is_success() && !status.is_io_pending())); + // TODO(mmenke): Change this to a DCHECK once https://crbug.com/508900 is + // resolved. + CHECK(request_->status().is_io_pending() || + request_->status().is_success() || + (!status.is_success() && !status.is_io_pending())); request_->set_status(status); } }
diff --git a/ppapi/proxy/ppapi_command_buffer_proxy.cc b/ppapi/proxy/ppapi_command_buffer_proxy.cc index c430c78..56e7486 100644 --- a/ppapi/proxy/ppapi_command_buffer_proxy.cc +++ b/ppapi/proxy/ppapi_command_buffer_proxy.cc
@@ -22,7 +22,10 @@ : command_buffer_id_(command_buffer_id), capabilities_(capabilities), resource_(resource), - dispatcher_(dispatcher) { + dispatcher_(dispatcher), + next_fence_sync_release_(1), + pending_fence_sync_release_(0), + flushed_fence_sync_release_(0) { shared_state_shm_.reset( new base::SharedMemory(shared_state.shmem(), false)); shared_state_shm_->Map(shared_state.size()); @@ -62,12 +65,14 @@ if (last_state_.error != gpu::error::kNoError) return; - if (flush_info_->flush_pending && flush_info_->resource != resource_) + if (flush_info_->flush_pending && flush_info_->resource != resource_) { FlushInternal(); + } flush_info_->flush_pending = true; flush_info_->resource = resource_; flush_info_->put_offset = put_offset; + pending_fence_sync_release_ = next_fence_sync_release_ - 1; } void PpapiCommandBufferProxy::WaitForTokenInRange(int32 start, int32 end) { @@ -187,6 +192,18 @@ return command_buffer_id_; } +uint64_t PpapiCommandBufferProxy::GenerateFenceSyncRelease() { + return next_fence_sync_release_++; +} + +bool PpapiCommandBufferProxy::IsFenceSyncRelease(uint64_t release) { + return release != 0 && release < next_fence_sync_release_; +} + +bool PpapiCommandBufferProxy::IsFenceSyncFlushed(uint64_t release) { + return release <= flushed_fence_sync_release_; +} + uint32 PpapiCommandBufferProxy::InsertSyncPoint() { uint32 sync_point = 0; if (last_state_.error == gpu::error::kNoError) { @@ -294,6 +311,7 @@ DCHECK(last_state_.error == gpu::error::kNoError); DCHECK(flush_info_->flush_pending); + DCHECK_GE(pending_fence_sync_release_, flushed_fence_sync_release_); IPC::Message* message = new PpapiHostMsg_PPBGraphics3D_AsyncFlush( ppapi::API_ID_PPB_GRAPHICS_3D, flush_info_->resource, @@ -307,6 +325,7 @@ flush_info_->flush_pending = false; flush_info_->resource.SetHostResource(0, 0); + flushed_fence_sync_release_ = pending_fence_sync_release_; } } // namespace proxy
diff --git a/ppapi/proxy/ppapi_command_buffer_proxy.h b/ppapi/proxy/ppapi_command_buffer_proxy.h index ddb3838..dc480579 100644 --- a/ppapi/proxy/ppapi_command_buffer_proxy.h +++ b/ppapi/proxy/ppapi_command_buffer_proxy.h
@@ -70,6 +70,9 @@ bool IsGpuChannelLost() override; gpu::CommandBufferNamespace GetNamespaceID() const override; uint64_t GetCommandBufferID() const override; + uint64_t GenerateFenceSyncRelease() override; + bool IsFenceSyncRelease(uint64_t release) override; + bool IsFenceSyncFlushed(uint64_t release) override; private: bool Send(IPC::Message* msg); @@ -96,6 +99,10 @@ InstanceData::FlushInfo *flush_info_; + uint64_t next_fence_sync_release_; + uint64_t pending_fence_sync_release_; + uint64_t flushed_fence_sync_release_; + DISALLOW_COPY_AND_ASSIGN(PpapiCommandBufferProxy); };
diff --git a/remoting/remoting_webapp_files.gypi b/remoting/remoting_webapp_files.gypi index a080136e..b18e540e 100644 --- a/remoting/remoting_webapp_files.gypi +++ b/remoting/remoting_webapp_files.gypi
@@ -97,6 +97,7 @@ 'webapp/base/js/identity_unittest.js', 'webapp/base/js/ipc_unittest.js', 'webapp/base/js/l10n_unittest.js', + 'webapp/base/js/network_connectivity_detector_unittest.js', 'webapp/base/js/platform_unittest.js', 'webapp/base/js/protocol_extension_manager_unittest.js', 'webapp/base/js/session_logger_unittest.js', @@ -182,7 +183,6 @@ 'webapp/base/js/credentials_provider.js', 'webapp/base/js/experiments.js', 'webapp/base/js/host_desktop.js', - 'webapp/base/js/smart_reconnector.js', 'webapp/base/js/telemetry_event_writer.js', 'webapp/base/js/xmpp_error_cache.js', ], @@ -198,6 +198,7 @@ 'webapp/base/js/protocol_extension_manager.js', 'webapp/base/js/protocol_extension.js', 'webapp/base/js/error.js', + 'webapp/base/js/network_connectivity_detector.js', 'webapp/base/js/plugin_settings.js', 'webapp/base/js/suspend_detector.js', 'webapp/base/js/typecheck.js',
diff --git a/remoting/webapp/base/js/error.js b/remoting/webapp/base/js/error.js index 28d79c6..fa1684d 100644 --- a/remoting/webapp/base/js/error.js +++ b/remoting/webapp/base/js/error.js
@@ -100,11 +100,11 @@ // not normally cause the error text to be shown to the user, so the // i18n-content prefix is not needed in this case. CANCELLED: '__CANCELLED__', + // Used to signify that the local computer was suspended for long enough that // the connection is expected to drop, allowing a reconnect attempt to be - // scheduled sooner. This is not shown to the user so i18n-content prefix is - // not needed in this case. - CLIENT_SUSPENDED: '__CLIENT_SUSPENDED__', + // scheduled sooner. + CLIENT_SUSPENDED: /*i18n-content*/ 'ERROR_NETWORK_FAILURE', INVALID_ACCESS_CODE: /*i18n-content*/ 'ERROR_INVALID_ACCESS_CODE', MISSING_PLUGIN: /*i18n-content*/ 'ERROR_MISSING_PLUGIN',
diff --git a/remoting/webapp/base/js/network_connectivity_detector.js b/remoting/webapp/base/js/network_connectivity_detector.js new file mode 100644 index 0000000..cc8f66e --- /dev/null +++ b/remoting/webapp/base/js/network_connectivity_detector.js
@@ -0,0 +1,125 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** @suppress {duplicate} */ +var remoting = remoting || {}; + +(function () { + +'use strict'; + +/** + * remoting.NetworkConnectivityDetector provides a reliable way to detect + * whether the current computer has connectivity. + * + * The waitForOnline() method returns a promise that resolves when the machine + * has network connectivity or rejects with remoting.Error.Tag.CANCELLED when + * cancel() is called. + * + * @constructor + * @implements {base.Disposable} + */ +remoting.NetworkConnectivityDetector = function() { + /** @private {base.Deferred} */ + this.deferred_ = null; + + /** @private {base.Disposable}*/ + this.pendingXhr_ = null; +}; + +remoting.NetworkConnectivityDetector.prototype.dispose = function() { + this.cancel(); +}; + +remoting.NetworkConnectivityDetector.prototype.cancel = function() { + base.dispose(this.pendingXhr_); + this.pendingXhr_ = null; + + if (this.deferred_) { + this.deferred_.reject(new remoting.Error(remoting.Error.Tag.CANCELLED)); + } + this.deferred_ = null; +}; + +/** + * @return {Promise} A promise that resolves when the device is online or + * rejects with the error tag remoting.Error.Tag.Cancelled when cancel() is + * called. + */ +remoting.NetworkConnectivityDetector.prototype.waitForOnline = function() { + if (this.deferred_) { + return this.deferred_.promise(); + } + + this.deferred_ = new base.Deferred(); + + var that = this; + + this.waitForOnlineEvent_().then( + this.waitForConnectivity_.bind(this) + ).then(function() { + that.deferred_.resolve(); + that.cancel(); + }).catch(function(){ + that.cancel(); + }); + + return this.deferred_.promise(); +}; + +/** + * @private + * @return {Promise} + */ +remoting.NetworkConnectivityDetector.prototype.waitForOnlineEvent_ = function(){ + if (base.isOnline()) { + return Promise.resolve(); + } + + var pending = new base.Deferred(); + function onOnline() { + pending.resolve(); + window.removeEventListener('online', onOnline, false); + } + + window.addEventListener('online', onOnline, false); + return pending.promise(); +}; + +/** + * @private + * @return {Promise} + */ +remoting.NetworkConnectivityDetector.prototype.waitForConnectivity_= + function() { + console.assert(this.pendingXhr_ == null, 'Unexpected pending request'); + + if (!this.deferred_) { + // It is canceled. + return Promise.reject(); + } + + this.pendingXhr_ = new remoting.AutoRetryXhr({ + method: 'GET', + url: remoting.NetworkConnectivityDetector.getUrlForTesting(), + }); + return this.pendingXhr_.start(); +}; + +/** + * Factory method for stubbing in unittests + * + * @return {remoting.NetworkConnectivityDetector} + */ +remoting.NetworkConnectivityDetector.create = function() { + return new remoting.NetworkConnectivityDetector(); +}; + +/** @return {string} */ +remoting.NetworkConnectivityDetector.getUrlForTesting = function() { + return remoting.settings.TALK_GADGET_URL + + '/oauth/chrome-remote-desktop-client'; +}; + +})();
diff --git a/remoting/webapp/base/js/network_connectivity_detector_unittest.js b/remoting/webapp/base/js/network_connectivity_detector_unittest.js new file mode 100644 index 0000000..0a01af6d --- /dev/null +++ b/remoting/webapp/base/js/network_connectivity_detector_unittest.js
@@ -0,0 +1,95 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(function() { + +'use strict'; + +/** @type {remoting.NetworkConnectivityDetector} */ +var detector; + +/** @type {sinon.TestStub} */ +var onlineStub; + +function setXhrStatus(/** number */ status) { + remoting.MockXhr.setEmptyResponseFor( + 'GET', remoting.NetworkConnectivityDetector.getUrlForTesting(), status); + +} + +QUnit.module('NetworkConnectivityDetector', { + beforeEach: function() { + remoting.settings = new remoting.Settings(); + remoting.MockXhr.activate(); + onlineStub = sinon.stub(base, 'isOnline'); + detector = remoting.NetworkConnectivityDetector.create(); + }, + afterEach: function() { + onlineStub.restore(); + base.dispose(detector); + detector = null; + remoting.MockXhr.restore(); + remoting.settings = null; + } +}); + +QUnit.test('waitForOnline() window.onLine = true', function(assert){ + onlineStub.returns(true); + setXhrStatus(200); + return detector.waitForOnline().then(function() { + assert.ok(true); + }); +}); + +QUnit.test('waitForOnline() window.onLine = false', function(assert){ + onlineStub.returns(false); + setXhrStatus(200); + var promise = detector.waitForOnline().then(function() { + assert.ok(true); + }); + + Promise.resolve().then(function() { + onlineStub.returns(true); + window.dispatchEvent(new CustomEvent('online')); + }); + return promise; +}); + +QUnit.test('waitForOnline() use one single XHR for multiple clients', + function(assert){ + onlineStub.returns(true); + + // We only set one single Xhr response. The next Xhr will fail. + setXhrStatus(200); + + var promise1 = detector.waitForOnline(); + var promise2 = detector.waitForOnline(); + var promise3 = detector.waitForOnline(); + return Promise.all([promise1, promise2, promise3]).then(function(){ + assert.ok(true); + }); +}); + +QUnit.test('cancel() rejects the promise', function(assert){ + onlineStub.returns(false); + setXhrStatus(200); + var promise = detector.waitForOnline().then(function() { + assert.ok(true); + }).then(function(){ + assert.ok(false, 'Expects the promise to reject with Canceled'); + }).catch(function(/** * */ reason) { + var error = /** @type {remoting.Error} */ (reason); + assert.ok(error.hasTag(remoting.Error.Tag.CANCELLED)); + }); + + detector.cancel(); + Promise.resolve().then(function() { + onlineStub.returns(true); + window.dispatchEvent(new CustomEvent('online')); + }); + + return promise; +}); + +})();
diff --git a/remoting/webapp/base/js/smart_reconnector.js b/remoting/webapp/base/js/smart_reconnector.js deleted file mode 100644 index afb6975..0000000 --- a/remoting/webapp/base/js/smart_reconnector.js +++ /dev/null
@@ -1,126 +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. - -/** - * @fileoverview - * Class handling reconnecting the session when it is disconnected due to - * network failure. - * - * The SmartReconnector listens for changes in connection state of - * |clientSession| to determine if a reconnection is needed. It then calls into - * |connector| to reconnect the session. - */ - -/** @suppress {duplicate} */ -var remoting = remoting || {}; - -(function () { - -'use strict'; - -/** - * @constructor - * @param {remoting.ConnectingDialog} connectingDialog - * @param {function()} reconnectCallback - * @param {function()} disconnectCallback - * @param {remoting.ClientSession} clientSession This represents the current - * remote desktop connection. It is used to monitor the changes in - * connection state. - * @implements {base.Disposable} - */ -remoting.SmartReconnector = function(connectingDialog, reconnectCallback, - disconnectCallback, clientSession) { - /** @private */ - this.reconnectCallback_ = reconnectCallback; - - /** @private */ - this.disconnectCallback_ = disconnectCallback; - - /** @private */ - this.clientSession_ = clientSession; - - /** - * Placeholder of any pending reconnect operations, e.g. Waiting for online, - * or a timeout to reconnect. - * - * @private {base.Disposable} - */ - this.pending_ = null; - - /** @private */ - this.connectingDialog_ = connectingDialog; - - var Events = remoting.ClientSession.Events; - /** @private */ - this.eventHook_ = - new base.EventHook(clientSession, Events.videoChannelStateChanged, - this.videoChannelStateChanged_.bind(this)); -}; - -// The online event only means the network adapter is enabled, but -// it doesn't necessarily mean that we have a working internet connection. -// Therefore, delay the connection by |RECONNECT_DELAY_MS| to allow for the -// network to connect. -var RECONNECT_DELAY_MS = 2000; - -// If the video channel is inactive for 10 seconds reconnect the session. -var CONNECTION_TIMEOUT_MS = 10000; - -remoting.SmartReconnector.prototype.reconnect_ = function() { - this.cancelPending_(); - this.disconnectCallback_(); - this.reconnectCallback_(); -}; - -remoting.SmartReconnector.prototype.reconnectAsync_ = function() { - this.cancelPending_(); - this.connectingDialog_.show(); - this.pending_ = - new base.OneShotTimer(this.reconnect_.bind(this), RECONNECT_DELAY_MS); -}; - -/** - * @param {!remoting.Error} reason - */ -remoting.SmartReconnector.prototype.onConnectionDropped = function(reason) { - this.cancelPending_(); - if (navigator.onLine) { - this.reconnect_(); - } else { - this.pending_ = new base.DomEventHook( - window, 'online', this.reconnectAsync_.bind(this), false); - } -}; - -/** - * @param {boolean=} active True if the video channel is active. - */ -remoting.SmartReconnector.prototype.videoChannelStateChanged_ = - function (active) { - this.cancelPending_(); - if (!active) { - this.pending_ = new base.DomEventHook( - window, 'online', this.startReconnectTimeout_.bind(this), false); - } -}; - -remoting.SmartReconnector.prototype.startReconnectTimeout_ = function() { - this.cancelPending_(); - this.pending_ = - new base.OneShotTimer(this.reconnect_.bind(this), CONNECTION_TIMEOUT_MS); -}; - -/** @private */ -remoting.SmartReconnector.prototype.cancelPending_ = function() { - base.dispose(this.pending_); - this.pending_ = null; -}; - -remoting.SmartReconnector.prototype.dispose = function() { - this.cancelPending_(); - base.dispose(this.eventHook_); - this.eventHook_ = null; -}; - -})();
diff --git a/remoting/webapp/base/js/xhr.js b/remoting/webapp/base/js/xhr.js index 4815ec1..dc50fd1 100644 --- a/remoting/webapp/base/js/xhr.js +++ b/remoting/webapp/base/js/xhr.js
@@ -355,6 +355,8 @@ * * @param {remoting.Xhr.Params} params * @param {number=} opt_maxRetryAttempts + * @implements {base.Disposable} + * * @constructor */ remoting.AutoRetryXhr = function(params, opt_maxRetryAttempts) { @@ -370,6 +372,11 @@ this.deferred_ = new base.Deferred(); }; +remoting.AutoRetryXhr.prototype.dispose = function() { + this.retryAttemptsRemaining_ = 0; + this.deferred_.reject(new remoting.Error(remoting.Error.Tag.CANCELLED)); +}; + /** * Calling this method multiple times will return the same promise and will not * start a new request.
diff --git a/remoting/webapp/crd/js/me2me_activity.js b/remoting/webapp/crd/js/me2me_activity.js index 9f742e0..57b1fd7 100644 --- a/remoting/webapp/crd/js/me2me_activity.js +++ b/remoting/webapp/crd/js/me2me_activity.js
@@ -31,8 +31,8 @@ /** @private */ this.retryOnHostOffline_ = true; - /** @private {remoting.SmartReconnector} */ - this.reconnector_ = null; + /** @private {remoting.NetworkConnectivityDetector} */ + this.networkDetector_ = null; /** @private {remoting.SessionLogger} */ this.logger_ = null; @@ -44,6 +44,8 @@ remoting.Me2MeActivity.prototype.dispose = function() { base.dispose(this.desktopActivity_); this.desktopActivity_ = null; + base.dispose(this.networkDetector_); + this.networkDetector_ = null; }; remoting.Me2MeActivity.prototype.start = function() { @@ -227,26 +229,27 @@ plugin.extensions().register(new remoting.GnubbyAuthHandler()); this.pinDialog_.requestPairingIfNecessary(connectionInfo.plugin()); - var SessionEntryPoint = remoting.ChromotingEvent.SessionEntryPoint; - - base.dispose(this.reconnector_); - this.reconnector_ = new remoting.SmartReconnector( - this.desktopActivity_.getConnectingDialog(), - this.reconnect_.bind( - this, SessionEntryPoint.AUTO_RECONNECT_ON_CONNECTION_DROPPED), - this.stop.bind(this), connectionInfo.session()); + // Drop the session after 30s of suspension. If this timeout is too short, we + // risk dropping a connection that is self-recoverable. If this timeout is too + // long, the user may lose his/her patience and just manually reconnects. + this.desktopActivity_.getSession().dropSessionOnSuspend(30 * 1000); }; remoting.Me2MeActivity.prototype.onDisconnected = function(error) { + base.dispose(this.desktopActivity_); + this.desktopActivity_ = null; + if (error.isNone()) { this.showFinishDialog_(remoting.AppMode.CLIENT_SESSION_FINISHED_ME2ME); } else { - this.reconnector_.onConnectionDropped(error); this.showErrorMessage_(error); + var SessionEntryPoint = remoting.ChromotingEvent.SessionEntryPoint; + base.dispose(this.networkDetector_); + this.networkDetector_ = remoting.NetworkConnectivityDetector.create(); + this.networkDetector_.waitForOnline().then( + this.reconnect_.bind( + this, SessionEntryPoint.AUTO_RECONNECT_ON_CONNECTION_DROPPED)); } - - base.dispose(this.desktopActivity_); - this.desktopActivity_ = null; }; /** @@ -274,6 +277,9 @@ var that = this; dialog.show().then(function(/** Result */result) { + base.dispose(that.networkDetector_); + that.networkDetector_ = null; + if (result === Result.PRIMARY) { remoting.setMode(remoting.AppMode.HOME); } else {
diff --git a/remoting/webapp/crd/js/me2me_telemetry_integration_test.js b/remoting/webapp/crd/js/me2me_telemetry_integration_test.js index 8db3a32..b7d36cf 100644 --- a/remoting/webapp/crd/js/me2me_telemetry_integration_test.js +++ b/remoting/webapp/crd/js/me2me_telemetry_integration_test.js
@@ -30,35 +30,21 @@ /** * @param {remoting.Me2MeTestDriver} testDriver * @param {Object} baseEvent + * @param {Array<remoting.ChromotingEvent.SessionState>} sequence */ -var expectSucceeded = function(testDriver, baseEvent) { - var ChromotingEvent = remoting.ChromotingEvent; - var sequence = [{ - session_state: ChromotingEvent.SessionState.STARTED, - },{ - session_state: ChromotingEvent.SessionState.SIGNALING, - previous_session_state: ChromotingEvent.SessionState.STARTED - },{ - session_state: ChromotingEvent.SessionState.CREATING_PLUGIN, - previous_session_state: ChromotingEvent.SessionState.SIGNALING - },{ - session_state: ChromotingEvent.SessionState.CONNECTING, - previous_session_state: ChromotingEvent.SessionState.CREATING_PLUGIN - },{ - session_state: ChromotingEvent.SessionState.AUTHENTICATED, - previous_session_state: ChromotingEvent.SessionState.CONNECTING - },{ - session_state: ChromotingEvent.SessionState.CONNECTED, - previous_session_state: ChromotingEvent.SessionState.AUTHENTICATED - },{ - session_state: ChromotingEvent.SessionState.CLOSED, - previous_session_state: ChromotingEvent.SessionState.CONNECTED - }]; - - var expectedEvents = sequence.map(function(/** Object */ sequenceValue) { - var event = /** @type {Object} */ (base.deepCopy(baseEvent)); - base.mix(event, sequenceValue); - return event; +var expectSequence = function(testDriver, baseEvent, sequence) { + var expectedEvents = sequence.map( + /** + * @param {remoting.ChromotingEvent.SessionState} state + * @param {number} i + */ + function(state, i) { + var event = /** @type {Object} */ (base.deepCopy(baseEvent)); + event.session_state = state; + if (i > 0) { + event.previous_session_state = sequence[i -1]; + } + return event; }); testDriver.expectEvents(expectedEvents); }; @@ -67,30 +53,32 @@ * @param {remoting.Me2MeTestDriver} testDriver * @param {Object} baseEvent */ +var expectSucceeded = function(testDriver, baseEvent) { + var ChromotingEvent = remoting.ChromotingEvent; + expectSequence(testDriver, baseEvent, [ + ChromotingEvent.SessionState.STARTED, + ChromotingEvent.SessionState.SIGNALING, + ChromotingEvent.SessionState.CREATING_PLUGIN, + ChromotingEvent.SessionState.CONNECTING, + ChromotingEvent.SessionState.AUTHENTICATED, + ChromotingEvent.SessionState.CONNECTED, + ChromotingEvent.SessionState.CLOSED + ]); +}; + +/** + * @param {remoting.Me2MeTestDriver} testDriver + * @param {Object} baseEvent + */ var expectCanceled = function(testDriver, baseEvent) { var ChromotingEvent = remoting.ChromotingEvent; - var sequence = [{ - session_state: ChromotingEvent.SessionState.STARTED, - },{ - session_state: ChromotingEvent.SessionState.SIGNALING, - previous_session_state: ChromotingEvent.SessionState.STARTED - },{ - session_state: ChromotingEvent.SessionState.CREATING_PLUGIN, - previous_session_state: ChromotingEvent.SessionState.SIGNALING - },{ - session_state: ChromotingEvent.SessionState.CONNECTING, - previous_session_state: ChromotingEvent.SessionState.CREATING_PLUGIN - },{ - session_state: ChromotingEvent.SessionState.CONNECTION_CANCELED, - previous_session_state: ChromotingEvent.SessionState.CONNECTING - }]; - - var expectedEvents = sequence.map(function(/** Object */ sequenceValue) { - var event = /** @type {Object} */ (base.deepCopy(baseEvent)); - base.mix(event, sequenceValue); - return event; - }); - testDriver.expectEvents(expectedEvents); + expectSequence(testDriver, baseEvent, [ + ChromotingEvent.SessionState.STARTED, + ChromotingEvent.SessionState.SIGNALING, + ChromotingEvent.SessionState.CREATING_PLUGIN, + ChromotingEvent.SessionState.CONNECTING, + ChromotingEvent.SessionState.CONNECTION_CANCELED + ]); }; /** @@ -100,29 +88,18 @@ */ var expectFailed = function(testDriver, baseEvent, error) { var ChromotingEvent = remoting.ChromotingEvent; - var sequence = [{ - session_state: ChromotingEvent.SessionState.STARTED, - },{ - session_state: ChromotingEvent.SessionState.SIGNALING, - previous_session_state: ChromotingEvent.SessionState.STARTED - },{ - session_state: ChromotingEvent.SessionState.CREATING_PLUGIN, - previous_session_state: ChromotingEvent.SessionState.SIGNALING - },{ - session_state: ChromotingEvent.SessionState.CONNECTING, - previous_session_state: ChromotingEvent.SessionState.CREATING_PLUGIN - },{ - session_state: ChromotingEvent.SessionState.CONNECTION_FAILED, - previous_session_state: ChromotingEvent.SessionState.CONNECTING, - connection_error: error - }]; + expectSequence(testDriver, baseEvent, [ + ChromotingEvent.SessionState.STARTED, + ChromotingEvent.SessionState.SIGNALING, + ChromotingEvent.SessionState.CREATING_PLUGIN, + ChromotingEvent.SessionState.CONNECTING, + ]); - var expectedEvents = sequence.map(function(/** Object */ sequenceValue) { - var event = /** @type {Object} */ (base.deepCopy(baseEvent)); - base.mix(event, sequenceValue); - return event; - }); - testDriver.expectEvents(expectedEvents); + var failedEvent = /** @type {Object} */ (base.deepCopy(baseEvent)); + failedEvent.session_state = ChromotingEvent.SessionState.CONNECTION_FAILED; + failedEvent.previous_session_state = ChromotingEvent.SessionState.CONNECTING; + failedEvent.connection_error = error; + testDriver.expectEvents([failedEvent]); }; QUnit.test('Connection succeeded', function() { @@ -378,4 +355,55 @@ return testDriver.startTest(); }); + +QUnit.test('Connection dropped - Auto Reconnect', function() { + var EntryPoint = remoting.ChromotingEvent.SessionEntryPoint; + expectSequence(testDriver, { + session_entry_point: EntryPoint.CONNECT_BUTTON, + role: remoting.ChromotingEvent.Role.CLIENT, + mode: remoting.ChromotingEvent.Mode.ME2ME, + }, [ + remoting.ChromotingEvent.SessionState.STARTED, + remoting.ChromotingEvent.SessionState.SIGNALING, + remoting.ChromotingEvent.SessionState.CREATING_PLUGIN, + remoting.ChromotingEvent.SessionState.CONNECTING, + remoting.ChromotingEvent.SessionState.AUTHENTICATED, + remoting.ChromotingEvent.SessionState.CONNECTED, + remoting.ChromotingEvent.SessionState.CONNECTION_DROPPED, + ]); + + expectSucceeded(testDriver, { + session_entry_point: EntryPoint.AUTO_RECONNECT_ON_CONNECTION_DROPPED, + role: remoting.ChromotingEvent.Role.CLIENT, + mode: remoting.ChromotingEvent.Mode.ME2ME, + }); + + var count = 0; + + /** + * @param {remoting.MockClientPlugin} plugin + * @param {remoting.ClientSession.State} state + */ + function onStatusChanged(plugin, state) { + if (state == remoting.ClientSession.State.CONNECTED) { + count++; + if (count == 1) { + // On first CONNECTED, fake network failure. + plugin.mock$setConnectionStatus( + remoting.ClientSession.State.FAILED, + remoting.ClientSession.ConnectionError.NETWORK_FAILURE); + } else if (count == 2) { + // On second CONNECTED, disconnect and finish the test. + testDriver.me2meActivity().stop(); + testDriver.endTest(); + } + } + } + + testDriver.mockConnection().pluginFactory().mock$setPluginStatusChanged( + onStatusChanged); + + return testDriver.startTest(); +}); + })();
diff --git a/remoting/webapp/crd/js/remoting_activity_test_driver.js b/remoting/webapp/crd/js/remoting_activity_test_driver.js index 08767ba8..f45fa48 100644 --- a/remoting/webapp/crd/js/remoting_activity_test_driver.js +++ b/remoting/webapp/crd/js/remoting_activity_test_driver.js
@@ -53,6 +53,21 @@ MockDesktopConnectedView.prototype.setRemapKeys = function() {}; /** + * @constructor + * @extends {remoting.NetworkConnectivityDetector} + */ +var MockNetworkConnectivityDetector = function() {}; +/** @override */ +MockNetworkConnectivityDetector.prototype.waitForOnline = function() { + return Promise.resolve(); +}; + +/** @override */ +MockNetworkConnectivityDetector.prototype.cancel = function() {}; +/** @override */ +MockNetworkConnectivityDetector.prototype.dispose = function() {}; + +/** * A test driver that mocks out the UI components that are required by the * DesktopRemotingActivity. * @@ -77,6 +92,12 @@ this.eventWriterMock_ = sinon.mock(remoting.TelemetryEventWriter.Client); /** @private */ this.setModeStub_ = sinon.stub(remoting, 'setMode'); + /** @private */ + this.createNetworkConnectivityDetectorStub_ = + sinon.stub(remoting.NetworkConnectivityDetector, 'create', function(){ + return new MockNetworkConnectivityDetector(); + }); + /** * Use fake timers to prevent the generation of session ID expiration events. * @private @@ -103,7 +124,7 @@ this.setModeStub_.restore(); this.eventWriterMock_.restore(); this.desktopConnectedViewCreateStub_.restore(); - + this.createNetworkConnectivityDetectorStub_.restore(); if (Boolean(this.mockConnection_)) { this.mockConnection_.restore(); this.mockConnection_ = null; @@ -205,6 +226,9 @@ return this.me2meActivity_; }; +remoting.Me2MeTestDriver.prototype.mockOnline = function() { +}; + /** @return {Promise} */ remoting.Me2MeTestDriver.prototype.startTest = function() { var host = new remoting.Host('fake_host_id');
diff --git a/remoting/webapp/files.gni b/remoting/webapp/files.gni index 070c9d45..261d5a6 100644 --- a/remoting/webapp/files.gni +++ b/remoting/webapp/files.gni
@@ -94,6 +94,7 @@ "base/js/identity_unittest.js", "base/js/ipc_unittest.js", "base/js/l10n_unittest.js", + "base/js/network_connectivity_detector_unittest.js", "base/js/platform_unittest.js", "base/js/protocol_extension_manager_unittest.js", "base/js/session_logger_unittest.js", @@ -174,7 +175,6 @@ "base/js/credentials_provider.js", "base/js/experiments.js", "base/js/host_desktop.js", - "base/js/smart_reconnector.js", "base/js/telemetry_event_writer.js", "base/js/xmpp_error_cache.js", ] @@ -191,6 +191,7 @@ "base/js/protocol_extension_manager.js", "base/js/protocol_extension.js", "base/js/error.js", + "base/js/network_connectivity_detector.js", "base/js/plugin_settings.js", "base/js/suspend_detector.js", "base/js/typecheck.js",
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 5fea2373..b7c6aeb 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -114,6 +114,12 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "components_browsertests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "components_unittests" }, { @@ -126,6 +132,12 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "content_browsertests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "content_unittests" }, { @@ -243,6 +255,12 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "mojo_public_bindings_unittests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "mojo_public_environment_unittests" }, { @@ -324,6 +342,12 @@ "swarming": { "can_use_on_swarming_builders": true }, + "test": "unit_tests" + }, + { + "swarming": { + "can_use_on_swarming_builders": true + }, "test": "url_unittests" }, {
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests index f68b16aab..3569680a 100644 --- a/third_party/WebKit/LayoutTests/SlowTests +++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -161,8 +161,6 @@ crbug.com/490511 imported/web-platform-tests/html/syntax/parsing/html5lib_tests19.html [ Slow ] crbug.com/490511 imported/web-platform-tests/html/syntax/parsing/html5lib_tests2.html [ Slow ] -crbug.com/528421 [ Win ] fast/repaint/fixed-in-page-scale.html [ Slow ] - # FIXME: These tests might still be buggy and time out. They were marked as Slow on 9/20/2013. # Double-check the data after they've been running another week or so. webkit.org/b/58193 [ Win7 ] http/tests/local/fileapi/send-sliced-dragged-file.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 0eafdcb..7841a9b 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -405,9 +405,6 @@ crbug.com/539623 [ SnowLeopard ] fast/repaint/selection-change-in-iframe-with-relative-parent.html [ Pass Failure ImageOnlyFailure ] -# Temporarily disabled until Chromium side supports meaningful MediaStreamTracks. -crbug.com/532509 fast/mediarecorder/MediaRecorder-basic-video.html [ Skip ] - crbug.com/387740 imported/web-platform-tests/mediacapture-streams/stream-api/introduction/disabled-audio-silence.html [ Skip ] crbug.com/387740 imported/web-platform-tests/mediacapture-streams/stream-api/introduction/disabled-video-black.html [ Skip ] crbug.com/387740 imported/web-platform-tests/mediacapture-streams/stream-api/mediastreamtrack/mediastreamtrack-end.html [ Skip ] @@ -419,12 +416,6 @@ crbug.com/387740 imported/web-platform-tests/mediacapture-streams/stream-api/mediastream/mediastream-idl.html [ Skip ] crbug.com/387740 imported/web-platform-tests/mediacapture-streams/stream-api/mediastream/mediastream-removetrack.html [ Skip ] -crbug.com/487028 editing/selection/vertical-rl-rtl-extend-line-backward-p.html [ NeedsRebaseline ] -crbug.com/487028 editing/selection/vertical-rl-rtl-extend-line-forward-p.html [ NeedsRebaseline ] -crbug.com/487028 fast/forms/cursor-at-editable-content-boundary.html [ NeedsRebaseline ] -crbug.com/487028 editing/selection/vertical-rl-rtl-extend-line-backward-br.html [ NeedsRebaseline ] -crbug.com/487028 editing/selection/vertical-rl-rtl-extend-line-forward-br.html [ NeedsRebaseline ] - crbug.com/412381 imported/web-platform-tests/mediacapture-streams/obtaining-local-multimedia-content/navigatorusermedia/empty-option-param.html [ Failure ] crbug.com/412381 imported/web-platform-tests/mediacapture-streams/obtaining-local-multimedia-content/navigatorusermedia/getusermedia-optional-constraint.html [ Failure ] crbug.com/412381 imported/web-platform-tests/mediacapture-streams/obtaining-local-multimedia-content/navigatorusermedia/getusermedia-trivial-constraint.html [ Failure ] @@ -555,8 +546,6 @@ crbug.com/505151 imported/csswg-test/css-writing-modes-3/abs-pos-non-replaced-vrl-220.xht [ ImageOnlyFailure ] crbug.com/505151 imported/csswg-test/css-writing-modes-3/abs-pos-non-replaced-vrl-224.xht [ ImageOnlyFailure ] -crbug.com/535897 [ Mac Linux ] fast/text/international/complex-joining-using-gpos.html [ NeedsRebaseline ] - crbug.com/492664 imported/csswg-test/css-writing-modes-3/inline-block-alignment-003.xht [ ImageOnlyFailure ] crbug.com/492664 imported/csswg-test/css-writing-modes-3/inline-block-alignment-005.xht [ ImageOnlyFailure ] crbug.com/492664 imported/csswg-test/css-writing-modes-3/inline-block-alignment-007.xht [ ImageOnlyFailure ] @@ -1136,10 +1125,6 @@ # Unclear semantics of ToString (actually ToPrimitive) across iframes. crbug.com/532469 http/tests/security/cross-frame-access-custom.html [ NeedsManualRebaseline ] -crbug.com/538692 css3/filters/effect-reference-hw.html [ NeedsRebaseline ] -crbug.com/538692 css3/filters/effect-reference-subregion-hw.html [ NeedsRebaseline ] -crbug.com/538692 css3/filters/effect-reference-tile-hw.html [ NeedsRebaseline ] - # Win10 specific failures that still need triaging. crbug.com/521730 [ Win10 ] fast/dom/Window/property-access-on-cached-properties-after-frame-navigated.html [ Failure ] crbug.com/521730 [ Win10 ] fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/fast/mediarecorder/MediaRecorder-basic-video-expected.txt b/third_party/WebKit/LayoutTests/fast/mediarecorder/MediaRecorder-basic-video-expected.txt deleted file mode 100644 index d3482d8..0000000 --- a/third_party/WebKit/LayoutTests/fast/mediarecorder/MediaRecorder-basic-video-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL checks the video-only MediaRecorder API. assert_unreached: Exception while creating MediaRecorder: NotSupportedError: Failed to construct 'MediaRecorder': No MediaRecorder handler can be created. Reached unreachable code -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 3341cf8e..4765b076 100644 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -4,6 +4,9 @@ method close method constructor method slice +interface ByteLengthQueuingStrategy + method constructor + method size interface Cache method add method addAll
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/byte-length-queuing-strategy.html b/third_party/WebKit/LayoutTests/http/tests/streams/byte-length-queuing-strategy.html new file mode 100644 index 0000000..5c02eb5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/byte-length-queuing-strategy.html
@@ -0,0 +1,13 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/serviceworker/resources/test-helpers.js"></script> + +<script src="byte-length-queuing-strategy.js"></script> +<script> +'use strict'; +fetch_tests_from_worker(new Worker('byte-length-queuing-strategy.js')); +fetch_tests_from_worker(new SharedWorker('byte-length-queuing-strategy.js')); +service_worker_test('byte-length-queuing-strategy.js'); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/byte-length-queuing-strategy.js b/third_party/WebKit/LayoutTests/http/tests/streams/byte-length-queuing-strategy.js new file mode 100644 index 0000000..1aaccfe --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/byte-length-queuing-strategy.js
@@ -0,0 +1,95 @@ +'use strict'; + +if (self.importScripts) { + self.importScripts('/resources/testharness.js'); +} + +test(() => { + + const strategy = new ByteLengthQueuingStrategy({ highWaterMark: 4 }); + +}, 'Can construct a ByteLengthQueuingStrategy with a valid high water mark'); + +test(() => { + + for (const highWaterMark of [-Infinity, NaN, 'foo', {}, () => {}]) { + const strategy = new ByteLengthQueuingStrategy({ highWaterMark }); + assert_equals(strategy.highWaterMark, highWaterMark, `${highWaterMark} gets set correctly`); + } + +}, 'Can construct a ByteLengthQueuingStrategy with any value as its high water mark'); + +test(() => { + + const highWaterMark = 1; + const highWaterMarkObjectGetter = { + get highWaterMark() { return highWaterMark; }, + }; + const error = new Error('wow!'); + const highWaterMarkObjectGetterThrowing = { + get highWaterMark() { throw error; }, + }; + + assert_throws({ name: 'TypeError' }, () => new ByteLengthQueuingStrategy(), 'construction fails with undefined'); + assert_throws({ name: 'TypeError' }, () => new ByteLengthQueuingStrategy(null), 'construction fails with null'); + assert_throws({ name: 'Error' }, () => new ByteLengthQueuingStrategy(highWaterMarkObjectGetterThrowing), + 'construction fails with an object with a throwing highWaterMark getter'); + + // Should not fail: + new ByteLengthQueuingStrategy('potato'); + new ByteLengthQueuingStrategy({}); + new ByteLengthQueuingStrategy(highWaterMarkObjectGetter); + +}, 'ByteLengthQueuingStrategy constructor behaves as expected with strange arguments'); + +test(() => { + + const size = 1024; + const chunk = { byteLength: size }; + const chunkGetter = { + get byteLength() { return size; }, + } + const error = new Error('wow!'); + const chunkGetterThrowing = { + get byteLength() { throw error; }, + } + assert_throws({ name: 'TypeError' }, () => ByteLengthQueuingStrategy.prototype.size(), 'size fails with undefined'); + assert_throws({ name: 'TypeError' }, () => ByteLengthQueuingStrategy.prototype.size(null), 'size fails with null'); + assert_equals(ByteLengthQueuingStrategy.prototype.size('potato'), undefined, + 'size succeeds with undefined with a random non-object type'); + assert_equals(ByteLengthQueuingStrategy.prototype.size({}), undefined, + 'size succeeds with undefined with an object without hwm property'); + assert_equals(ByteLengthQueuingStrategy.prototype.size(chunk), size, + 'size succeeds with the right amount with an object with a hwm'); + assert_equals(ByteLengthQueuingStrategy.prototype.size(chunkGetter), size, + 'size succeeds with the right amount with an object with a hwm getter'); + assert_throws({ name: 'Error' }, () => ByteLengthQueuingStrategy.prototype.size(chunkGetterThrowing), + 'size fails with the error thrown by the getter'); + +}, 'ByteLengthQueuingStrategy size behaves as expected with strange arguments'); + +test(() => { + + const strategy = new ByteLengthQueuingStrategy({ highWaterMark: 4 }); + + assert_object_equals(Object.getOwnPropertyDescriptor(strategy, 'highWaterMark'), + { value: 4, writable: true, enumerable: true, configurable: true }, + 'highWaterMark property should be a data property with the value passed the constructor'); + assert_equals(typeof strategy.size, 'function'); + +}, 'ByteLengthQueuingStrategy instances have the correct properties'); + +test(() => { + + const strategy = new ByteLengthQueuingStrategy({ highWaterMark: 4 }); + assert_equals(strategy.highWaterMark, 4); + + strategy.highWaterMark = 10; + assert_equals(strategy.highWaterMark, 10); + + strategy.highWaterMark = "banana"; + assert_equals(strategy.highWaterMark, "banana"); + +}, 'ByteLengthQueuingStrategy\'s highWaterMark property can be set to anything'); + +done();
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getAXNode-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getAXNode-expected.txt index 2c3e447c..714f02fd 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getAXNode-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getAXNode-expected.txt
@@ -36,7 +36,33 @@ "value": false } } - ] + ], + "name": { + "type": "computedString", + "value": "", + "sources": [ + { + "type": "relatedElement", + "attribute": "aria-labelledby" + }, + { + "type": "attribute", + "attribute": "aria-label" + }, + { + "type": "relatedElement", + "nativeSource": "label" + }, + { + "type": "placeholder", + "attribute": "placeholder" + }, + { + "type": "attribute", + "attribute": "title" + } + ] + } } }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getRelationships-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getRelationships-expected.txt index 9ef77ec..825de93 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getRelationships-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getRelationships-expected.txt
@@ -49,16 +49,44 @@ "idref": "rg1_label", "nodeResult": "h3#rg1_label" } - ] + ], + "value": "rg1_label" } } ], "name": { - "type": "string", - "value": "Lunch Options" + "type": "computedString", + "value": "Lunch Options", + "sources": [ + { + "type": "relatedElement", + "value": { + "type": "idrefList", + "relatedNodeArrayValue": [ + { + "idref": "rg1_label", + "text": "Lunch Options", + "nodeResult": "h3#rg1_label" + } + ], + "value": "rg1_label" + }, + "attribute": "aria-labelledby" + }, + { + "type": "attribute", + "attribute": "aria-label", + "superseded": true + }, + { + "type": "attribute", + "attribute": "title", + "superseded": true + } + ] }, "description": { - "type": "string", + "type": "computedString", "value": "Lunch Options" } } @@ -91,16 +119,44 @@ "idref": "rg2_label", "nodeResult": "h3#rg2_label" } - ] + ], + "value": "rg2_label" } } ], "name": { - "type": "string", - "value": "Drink Options" + "type": "computedString", + "value": "Drink Options", + "sources": [ + { + "type": "relatedElement", + "value": { + "type": "idrefList", + "relatedNodeArrayValue": [ + { + "idref": "rg2_label", + "text": "Drink Options", + "nodeResult": "h3#rg2_label" + } + ], + "value": "rg2_label" + }, + "attribute": "aria-labelledby" + }, + { + "type": "attribute", + "attribute": "aria-label", + "superseded": true + }, + { + "type": "attribute", + "attribute": "title", + "superseded": true + } + ] }, "description": { - "type": "string", + "type": "computedString", "value": "Drink Options" } }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getRelationships.html b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getRelationships.html index 815a158e..39b0239 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getRelationships.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-getRelationships.html
@@ -99,6 +99,21 @@ InspectorTest.completeTest(); } + function rewriteValue(value, promises) + { + if (value.type === "idrefList") { + checkExists("relatedNodeArrayValue", value); + var relatedNodeArray = value.relatedNodeArrayValue; + check(Array.isArray(relatedNodeArray), "relatedNodeArrayValue should be an array", JSON.stringify(value)); + for (var relatedNode of relatedNodeArray) { + promises.push(rewriteNode(relatedNode)); + } + } else if (value.type === "idref") { + checkExists("relatedNodeValue", value); + var relatedNode = value.relatedNodeValue; + promises.push(rewriteNode(relatedNode)); + } + } function rewriteNodes(msg) { if (msg.error) { @@ -108,22 +123,17 @@ } checkExists("result.accessibilityNode.properties", msg); - var properties = msg.result.accessibilityNode.properties; + var node = msg.result.accessibilityNode; + var properties = node.properties; var promises = []; - for (var property of properties) { - if (property.value.type === "idrefList") { - checkExists("value.relatedNodeArrayValue", property); - var relatedNodeArray = property.value.relatedNodeArrayValue; - check(Array.isArray(relatedNodeArray), "value.relatedNodeArrayValue should be an array", JSON.stringify(property)); - for (var relatedNode of relatedNodeArray) { - promises.push(rewriteNode(relatedNode)); - } - } else if (property.value.type === "idref") { - checkExists("value.relatedNodeValue", property); - var relatedNode = property.value.relatedNodeValue; - promises.push(rewriteNode(relatedNode)); - } + if (node.name && node.name.sources) { + for (var source of node.name.sources) { + if (source.value) + rewriteValue(source.value, promises); + } } + for (var property of properties) + rewriteValue(property.value, promises); function onSuccess() {
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodes-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodes-expected.txt index 1d81777..640ea0f 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodes-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodes-expected.txt
@@ -17,7 +17,25 @@ "type": "internalRole", "value": "Div" }, - "properties": [] + "properties": [], + "name": { + "type": "computedString", + "value": "", + "sources": [ + { + "type": "relatedElement", + "attribute": "aria-labelledby" + }, + { + "type": "attribute", + "attribute": "aria-label" + }, + { + "type": "attribute", + "attribute": "title" + } + ] + } } } } @@ -53,7 +71,33 @@ "value": false } } - ] + ], + "name": { + "type": "computedString", + "value": "non-hidden treeitem", + "sources": [ + { + "type": "relatedElement", + "attribute": "aria-labelledby" + }, + { + "type": "attribute", + "attribute": "aria-label" + }, + { + "type": "contents", + "value": { + "type": "string", + "value": "non-hidden treeitem" + } + }, + { + "type": "attribute", + "attribute": "title", + "superseded": true + } + ] + } } } } @@ -186,7 +230,34 @@ "type": "role", "value": "img" }, - "properties": [] + "properties": [], + "name": { + "type": "computedString", + "value": "", + "sources": [ + { + "type": "relatedElement", + "attribute": "aria-labelledby" + }, + { + "type": "attribute", + "attribute": "aria-label" + }, + { + "type": "attribute", + "value": { + "type": "string", + "value": "" + }, + "attribute": "alt" + }, + { + "type": "attribute", + "attribute": "title", + "superseded": true + } + ] + } } } } @@ -247,7 +318,25 @@ "type": "internalRole", "value": "Div" }, - "properties": [] + "properties": [], + "name": { + "type": "computedString", + "value": "", + "sources": [ + { + "type": "relatedElement", + "attribute": "aria-labelledby" + }, + { + "type": "attribute", + "attribute": "aria-label" + }, + { + "type": "attribute", + "attribute": "title" + } + ] + } } } }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodesModal-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodesModal-expected.txt index 563dc097..fc7eb82 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodesModal-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/accessibility/accessibility-ignoredNodesModal-expected.txt
@@ -36,7 +36,25 @@ "type": "role", "value": "dialog" }, - "properties": [] + "properties": [], + "name": { + "type": "computedString", + "value": "", + "sources": [ + { + "type": "relatedElement", + "attribute": "aria-labelledby" + }, + { + "type": "attribute", + "attribute": "aria-label" + }, + { + "type": "attribute", + "attribute": "title" + } + ] + } } } } @@ -50,7 +68,25 @@ "type": "internalRole", "value": "Div" }, - "properties": [] + "properties": [], + "name": { + "type": "computedString", + "value": "", + "sources": [ + { + "type": "relatedElement", + "attribute": "aria-labelledby" + }, + { + "type": "attribute", + "attribute": "aria-label" + }, + { + "type": "attribute", + "attribute": "title" + } + ] + } } } }
diff --git a/third_party/WebKit/LayoutTests/platform/android/css3/filters/effect-reference-tile-hw-expected.png b/third_party/WebKit/LayoutTests/platform/android/css3/filters/effect-reference-tile-hw-expected.png deleted file mode 100644 index 61c416bf..0000000 --- a/third_party/WebKit/LayoutTests/platform/android/css3/filters/effect-reference-tile-hw-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux-precise/fast/text/international/complex-joining-using-gpos-expected.png b/third_party/WebKit/LayoutTests/platform/linux-precise/fast/text/international/complex-joining-using-gpos-expected.png new file mode 100644 index 0000000..a089d96 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux-precise/fast/text/international/complex-joining-using-gpos-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css3/filters/effect-reference-hw-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css3/filters/effect-reference-hw-expected.png index 522a240..90547ba 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/css3/filters/effect-reference-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/css3/filters/effect-reference-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css3/filters/effect-reference-subregion-hw-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css3/filters/effect-reference-subregion-hw-expected.png index 6b6ba9a..79b5f7d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/css3/filters/effect-reference-subregion-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/css3/filters/effect-reference-subregion-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/international/complex-joining-using-gpos-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/text/international/complex-joining-using-gpos-expected.png index e62623e..ddb81d68 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/text/international/complex-joining-using-gpos-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/international/complex-joining-using-gpos-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/international/complex-joining-using-gpos-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/text/international/complex-joining-using-gpos-expected.txt index d8447d6..ba526ef 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/text/international/complex-joining-using-gpos-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/international/complex-joining-using-gpos-expected.txt
@@ -10,11 +10,11 @@ LayoutText {#text} at (0,0) size 679x19 text run at (0,0) width 679: "The backslash-looking mark should connect into the the character on the center, not be positioned off to the side." LayoutBlockFlow {DIV} at (0,72) size 784x123 - LayoutText {#text} at (0,16) size 279x80 - text run at (0,16) width 279: "\x{915}+\x{947} = \x{915}\x{947}" + LayoutText {#text} at (0,16) size 297x80 + text run at (0,16) width 297: "\x{915}+ \x{947} = \x{915}\x{947}" LayoutBlockFlow {DIV} at (0,195) size 784x53 - LayoutText {#text} at (0,7) size 121x34 - text run at (0,7) width 121: "\x{915}+\x{947} = \x{915}\x{947}" + LayoutText {#text} at (0,7) size 129x34 + text run at (0,7) width 129: "\x{915}+ \x{947} = \x{915}\x{947}" LayoutBlockFlow {P} at (0,264) size 784x20 LayoutText {#text} at (0,0) size 586x19 text run at (0,0) width 586: "The three words should be separated by spaces, and there should be no marks above the spaces."
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-reference-hw-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-reference-hw-expected.png index 1ff35c89..6f12dc5 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-reference-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-reference-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-reference-subregion-hw-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-reference-subregion-hw-expected.png index 0baa4ba..c926577 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-reference-subregion-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-reference-subregion-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-reference-tile-hw-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-reference-tile-hw-expected.png index 48c392c..18802e352 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-reference-tile-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-reference-tile-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/css3/filters/effect-reference-hw-expected.png b/third_party/WebKit/LayoutTests/platform/win-xp/css3/filters/effect-reference-hw-expected.png index 480a3e4..d15c7545 100644 --- a/third_party/WebKit/LayoutTests/platform/win-xp/css3/filters/effect-reference-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win-xp/css3/filters/effect-reference-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/css3/filters/effect-reference-subregion-hw-expected.png b/third_party/WebKit/LayoutTests/platform/win-xp/css3/filters/effect-reference-subregion-hw-expected.png index 9f671ce1..c99a015 100644 --- a/third_party/WebKit/LayoutTests/platform/win-xp/css3/filters/effect-reference-subregion-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win-xp/css3/filters/effect-reference-subregion-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-reference-hw-expected.png b/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-reference-hw-expected.png index 88c5ebf..ed98a8f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-reference-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-reference-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-reference-subregion-hw-expected.png b/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-reference-subregion-hw-expected.png index 078c5574..e0966ff 100644 --- a/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-reference-subregion-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-reference-subregion-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-reference-tile-hw-expected.png b/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-reference-tile-hw-expected.png index 53bca2c0..61c416bf 100644 --- a/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-reference-tile-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/css3/filters/effect-reference-tile-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-compositor-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-compositor-worker-expected.txt index d86fbbd2..f4d04e47 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-compositor-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-compositor-worker-expected.txt
@@ -13,6 +13,9 @@ Starting worker: resources/global-interface-listing.js [Worker] [INTERFACES] +[Worker] interface ByteLengthQueuingStrategy +[Worker] method constructor +[Worker] method size [Worker] interface CompositorProxy [Worker] getter opacity [Worker] getter scrollLeft
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt index 1bc4056..81587e03 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -19,6 +19,9 @@ [Worker] method close [Worker] method constructor [Worker] method slice +[Worker] interface ByteLengthQueuingStrategy +[Worker] method constructor +[Worker] method size [Worker] interface Cache [Worker] method add [Worker] method addAll
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index b1b36da..c33e12a 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -317,6 +317,9 @@ method getCharacteristic interface BluetoothUUID method constructor +interface ByteLengthQueuingStrategy + method constructor + method size interface CDATASection method constructor interface CSS
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt index 7d46f1a..3c27077e 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -11,6 +11,9 @@ [Worker] method close [Worker] method constructor [Worker] method slice +[Worker] interface ByteLengthQueuingStrategy +[Worker] method constructor +[Worker] method size [Worker] interface Cache [Worker] method add [Worker] method addAll
diff --git a/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp b/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp index 73e61700..9accf18 100644 --- a/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp
@@ -145,16 +145,22 @@ disposeContext(DetachGlobal); } -void WindowProxy::takeGlobalFrom(WindowProxy* windowProxy) +v8::Local<v8::Object> WindowProxy::releaseGlobal() { - v8::HandleScope handleScope(m_isolate); - ASSERT(!windowProxy->isContextInitialized()); + ASSERT(!isContextInitialized()); // If a ScriptState was created, the context was initialized at some point. // Make sure the global object was detached from the proxy by calling clearForNavigation(). - if (windowProxy->m_scriptState) - ASSERT(windowProxy->m_scriptState->isGlobalObjectDetached()); - m_global.set(m_isolate, windowProxy->m_global.newLocal(m_isolate)); - windowProxy->m_global.clear(); + if (m_scriptState) + ASSERT(m_scriptState->isGlobalObjectDetached()); + v8::Local<v8::Object> global = m_global.newLocal(m_isolate); + m_global.clear(); + return global; +} + +void WindowProxy::setGlobal(v8::Local<v8::Object> global) +{ + m_global.set(m_isolate, global); + // Initialize the window proxy now, to re-establish the connection between // the global object and the v8::Context. This is really only needed for a // RemoteDOMWindow, since it has no scripting environment of its own.
diff --git a/third_party/WebKit/Source/bindings/core/v8/WindowProxy.h b/third_party/WebKit/Source/bindings/core/v8/WindowProxy.h index 6c6368e..3ae03af 100644 --- a/third_party/WebKit/Source/bindings/core/v8/WindowProxy.h +++ b/third_party/WebKit/Source/bindings/core/v8/WindowProxy.h
@@ -80,7 +80,8 @@ void clearForNavigation(); void clearForClose(); - void takeGlobalFrom(WindowProxy*); + v8::Local<v8::Object> releaseGlobal(); + void setGlobal(v8::Local<v8::Object>); DOMWrapperWorld& world() { return *m_world; }
diff --git a/third_party/WebKit/Source/bindings/core/v8/WindowProxyManager.cpp b/third_party/WebKit/Source/bindings/core/v8/WindowProxyManager.cpp index 4ee62ee0..970faaf3 100644 --- a/third_party/WebKit/Source/bindings/core/v8/WindowProxyManager.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/WindowProxyManager.cpp
@@ -83,11 +83,17 @@ } } -void WindowProxyManager::takeGlobalFrom(WindowProxyManager* other) +void WindowProxyManager::releaseGlobals(HashMap<DOMWrapperWorld*, v8::Local<v8::Object>>& map) { - m_windowProxy->takeGlobalFrom(other->m_windowProxy.get()); - for (auto& entry : other->m_isolatedWorlds) - windowProxy(entry.value->world())->takeGlobalFrom(entry.value.get()); + map.add(&m_windowProxy->world(), m_windowProxy->releaseGlobal()); + for (auto& entry : m_isolatedWorlds) + map.add(&entry.value->world(), windowProxy(entry.value->world())->releaseGlobal()); +} + +void WindowProxyManager::setGlobals(const HashMap<DOMWrapperWorld*, v8::Local<v8::Object>>& map) +{ + for (auto& entry : map) + windowProxy(*entry.key)->setGlobal(entry.value); } WindowProxyManager::WindowProxyManager(Frame& frame)
diff --git a/third_party/WebKit/Source/bindings/core/v8/WindowProxyManager.h b/third_party/WebKit/Source/bindings/core/v8/WindowProxyManager.h index 71ac000..ec76b60 100644 --- a/third_party/WebKit/Source/bindings/core/v8/WindowProxyManager.h +++ b/third_party/WebKit/Source/bindings/core/v8/WindowProxyManager.h
@@ -5,6 +5,7 @@ #ifndef WindowProxyManager_h #define WindowProxyManager_h +#include "core/CoreExport.h" #include "platform/heap/Handle.h" #include "wtf/Vector.h" #include <utility> @@ -18,7 +19,7 @@ class SecurityOrigin; class WindowProxy; -class WindowProxyManager final : public NoBaseWillBeGarbageCollectedFinalized<WindowProxyManager> { +class CORE_EXPORT WindowProxyManager final : public NoBaseWillBeGarbageCollectedFinalized<WindowProxyManager> { WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED(WindowProxyManager); public: static PassOwnPtrWillBeRawPtr<WindowProxyManager> create(Frame&); @@ -39,7 +40,8 @@ WindowProxy* existingWindowProxy(DOMWrapperWorld&); void collectIsolatedContexts(Vector<std::pair<ScriptState*, SecurityOrigin*>>&); - void takeGlobalFrom(WindowProxyManager*); + void releaseGlobals(HashMap<DOMWrapperWorld*, v8::Local<v8::Object>>&); + void setGlobals(const HashMap<DOMWrapperWorld*, v8::Local<v8::Object>>&); private: typedef WillBeHeapHashMap<int, OwnPtrWillBeMember<WindowProxy>> IsolatedWorldMap;
diff --git a/third_party/WebKit/Source/core/animation/Animation.cpp b/third_party/WebKit/Source/core/animation/Animation.cpp index dc4aeca..4c831eb 100644 --- a/third_party/WebKit/Source/core/animation/Animation.cpp +++ b/third_party/WebKit/Source/core/animation/Animation.cpp
@@ -994,11 +994,11 @@ bool wasActive = oldPlayState == Pending || oldPlayState == Running; bool isActive = newPlayState == Pending || newPlayState == Running; if (!wasActive && isActive) - TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("blink.animations,devtools.timeline", "Animation", m_animation, "data", InspectorAnimationEvent::data(*m_animation)); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("blink.animations,devtools.timeline,benchmark", "Animation", m_animation, "data", InspectorAnimationEvent::data(*m_animation)); else if (wasActive && !isActive) - TRACE_EVENT_NESTABLE_ASYNC_END1("blink.animations,devtools.timeline", "Animation", m_animation, "endData", InspectorAnimationStateEvent::data(*m_animation)); + TRACE_EVENT_NESTABLE_ASYNC_END1("blink.animations,devtools.timeline,benchmark", "Animation", m_animation, "endData", InspectorAnimationStateEvent::data(*m_animation)); else - TRACE_EVENT_NESTABLE_ASYNC_INSTANT1("blink.animations,devtools.timeline", "Animation", m_animation, "data", InspectorAnimationStateEvent::data(*m_animation)); + TRACE_EVENT_NESTABLE_ASYNC_INSTANT1("blink.animations,devtools.timeline,benchmark", "Animation", m_animation, "data", InspectorAnimationStateEvent::data(*m_animation)); } // Ordering is important, the ready promise should resolve/reject before
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi index 52dab96..0320ed7 100644 --- a/third_party/WebKit/Source/core/core.gypi +++ b/third_party/WebKit/Source/core/core.gypi
@@ -1656,6 +1656,8 @@ 'inspector/InjectedScriptHost.h', 'inspector/InjectedScriptManager.cpp', 'inspector/InjectedScriptManager.h', + 'inspector/InspectedFrames.cpp', + 'inspector/InspectedFrames.h', 'inspector/InspectorAnimationAgent.cpp', 'inspector/InspectorAnimationAgent.h', 'inspector/InspectorApplicationCacheAgent.cpp', @@ -1966,6 +1968,7 @@ 'paint/NinePieceImageGrid.h', 'paint/NinePieceImagePainter.cpp', 'paint/NinePieceImagePainter.h', + 'paint/ObjectPaintProperties.h', 'paint/ObjectPainter.cpp', 'paint/ObjectPainter.h', 'paint/PaintInfo.h',
diff --git a/third_party/WebKit/Source/core/frame/Frame.cpp b/third_party/WebKit/Source/core/frame/Frame.cpp index 6a1fdbc..37419ea 100644 --- a/third_party/WebKit/Source/core/frame/Frame.cpp +++ b/third_party/WebKit/Source/core/frame/Frame.cpp
@@ -30,7 +30,6 @@ #include "config.h" #include "core/frame/Frame.h" -#include "bindings/core/v8/WindowProxyManager.h" #include "core/dom/DocumentType.h" #include "core/events/Event.h" #include "core/frame/LocalDOMWindow.h" @@ -161,13 +160,6 @@ return emptyChromeClient(); } -void Frame::finishSwapFrom(Frame* old) -{ - WindowProxyManager* oldManager = old->windowProxyManager(); - oldManager->clearForNavigation(); - windowProxyManager()->takeGlobalFrom(oldManager); -} - Frame* Frame::findFrameForNavigation(const AtomicString& name, Frame& activeFrame) { Frame* frame = tree().find(name);
diff --git a/third_party/WebKit/Source/core/frame/Frame.h b/third_party/WebKit/Source/core/frame/Frame.h index 02c1d310..7bdcb06 100644 --- a/third_party/WebKit/Source/core/frame/Frame.h +++ b/third_party/WebKit/Source/core/frame/Frame.h
@@ -111,7 +111,6 @@ // Returns true if the frame is ready to receive the next commit, or false // otherwise. virtual bool prepareForCommit() = 0; - void finishSwapFrom(Frame*); bool canNavigate(const Frame&); virtual void printNavigationErrorMessage(const Frame&, const char* reason) = 0; @@ -129,11 +128,11 @@ void setIsLoading(bool isLoading) { m_isLoading = isLoading; } bool isLoading() const { return m_isLoading; } + virtual WindowProxyManager* windowProxyManager() const = 0; + protected: Frame(FrameClient*, FrameHost*, FrameOwner*); - virtual WindowProxyManager* windowProxyManager() const = 0; - mutable FrameTree m_treeNode; RawPtrWillBeMember<FrameHost> m_host;
diff --git a/third_party/WebKit/Source/core/frame/VisualViewport.cpp b/third_party/WebKit/Source/core/frame/VisualViewport.cpp index 384faf6..cc6e5b0 100644 --- a/third_party/WebKit/Source/core/frame/VisualViewport.cpp +++ b/third_party/WebKit/Source/core/frame/VisualViewport.cpp
@@ -370,8 +370,6 @@ ScrollbarOrientation webcoreOrientation = isHorizontal ? HorizontalScrollbar : VerticalScrollbar; webScrollbarLayer = coordinator->createSolidColorScrollbarLayer(webcoreOrientation, thumbThickness, scrollbarMargin, false); - webScrollbarLayer->setClipLayer(m_innerViewportContainerLayer->platformLayer()); - // The compositor will control the scrollbar's visibility. Set to invisible by defualt // so scrollbars don't show up in layout tests. webScrollbarLayer->layer()->setOpacity(0);
diff --git a/third_party/WebKit/Source/core/html/PluginDocument.cpp b/third_party/WebKit/Source/core/html/PluginDocument.cpp index e64e048..05fb404 100644 --- a/third_party/WebKit/Source/core/html/PluginDocument.cpp +++ b/third_party/WebKit/Source/core/html/PluginDocument.cpp
@@ -103,11 +103,13 @@ m_embedElement->setAttribute(widthAttr, "100%"); m_embedElement->setAttribute(heightAttr, "100%"); m_embedElement->setAttribute(nameAttr, "plugin"); + m_embedElement->setAttribute(idAttr, "plugin"); m_embedElement->setAttribute(srcAttr, AtomicString(document()->url().string())); m_embedElement->setAttribute(typeAttr, document()->loader()->mimeType()); body->appendChild(m_embedElement); toPluginDocument(document())->setPluginNode(m_embedElement.get()); + m_embedElement->focus(); document()->updateLayout();
diff --git a/third_party/WebKit/Source/core/inspector/InspectedFrames.cpp b/third_party/WebKit/Source/core/inspector/InspectedFrames.cpp new file mode 100644 index 0000000..12911049 --- /dev/null +++ b/third_party/WebKit/Source/core/inspector/InspectedFrames.cpp
@@ -0,0 +1,68 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" +#include "core/inspector/InspectedFrames.h" + +#include "core/frame/LocalFrame.h" + +namespace blink { + +InspectedFrames::InspectedFrames(LocalFrame* root) + : m_root(root) +{ +} + +InspectedFrames::Iterator InspectedFrames::begin() +{ + return Iterator(m_root, m_root); +} + +InspectedFrames::Iterator InspectedFrames::end() +{ + return Iterator(m_root, nullptr); +} + +InspectedFrames::Iterator::Iterator(LocalFrame* root, LocalFrame* current) + : m_root(root) + , m_current(current) +{ +} + +InspectedFrames::Iterator& InspectedFrames::Iterator::operator++() +{ + if (!m_current) + return *this; + Frame* frame = m_current->tree().traverseNext(m_root); + m_current = nullptr; + for (; frame; frame = frame->tree().traverseNext(m_root)) { + if (!frame->isLocalFrame()) + continue; + LocalFrame* local = toLocalFrame(frame); + if (local->instrumentingAgents() == m_root->instrumentingAgents()) { + m_current = local; + break; + } + } + return *this; +} + +InspectedFrames::Iterator InspectedFrames::Iterator::operator++(int) +{ + LocalFrame* old = m_current; + ++*this; + return Iterator(m_root, old); +} + +bool InspectedFrames::Iterator::operator==(const Iterator& other) +{ + return m_current == other.m_current && m_root == other.m_root; +} + +bool InspectedFrames::Iterator::operator!=(const Iterator& other) +{ + return !(*this == other); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectedFrames.h b/third_party/WebKit/Source/core/inspector/InspectedFrames.h new file mode 100644 index 0000000..b2f1cad --- /dev/null +++ b/third_party/WebKit/Source/core/inspector/InspectedFrames.h
@@ -0,0 +1,44 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef InspectedFrames_h +#define InspectedFrames_h + +#include "core/CoreExport.h" +#include "wtf/Noncopyable.h" + +namespace blink { + +class LocalFrame; + +class CORE_EXPORT InspectedFrames { + WTF_MAKE_NONCOPYABLE(InspectedFrames); +public: + class Iterator { + public: + Iterator operator++(int); + Iterator& operator++(); + bool operator==(const Iterator& other); + bool operator!=(const Iterator& other); + LocalFrame* operator*() { return m_current; } + LocalFrame* operator->() { return m_current; } + private: + friend class InspectedFrames; + Iterator(LocalFrame* root, LocalFrame* current); + LocalFrame* m_root; + LocalFrame* m_current; + }; + + explicit InspectedFrames(LocalFrame* root); + LocalFrame* root() { return m_root; } + Iterator begin(); + Iterator end(); + +private: + LocalFrame* m_root; +}; + +} // namespace blink + +#endif // InspectedFrames_h
diff --git a/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp index 94e4385f..2cf9bef 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp
@@ -20,6 +20,7 @@ #include "core/css/resolver/StyleResolver.h" #include "core/dom/DOMNodeIds.h" #include "core/inspector/InjectedScriptManager.h" +#include "core/inspector/InspectedFrames.h" #include "core/inspector/InspectorDOMAgent.h" #include "core/inspector/InspectorPageAgent.h" #include "core/inspector/InspectorState.h" @@ -188,10 +189,8 @@ void InspectorAnimationAgent::setPlaybackRate(ErrorString*, double playbackRate) { - for (Frame* frame = m_pageAgent->inspectedFrame(); frame; frame = frame->tree().traverseNext(m_pageAgent->inspectedFrame())) { - if (frame->isLocalFrame()) - toLocalFrame(frame)->document()->timeline().setPlaybackRate(playbackRate); - } + for (LocalFrame* frame : InspectedFrames(m_pageAgent->inspectedFrame())) + frame->document()->timeline().setPlaybackRate(playbackRate); } void InspectorAnimationAgent::getCurrentTime(ErrorString* errorString, const String& id, double* currentTime)
diff --git a/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp index e3b0943..d5530be 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp
@@ -28,6 +28,7 @@ #include "core/frame/LocalFrame.h" #include "core/inspector/IdentifiersFactory.h" +#include "core/inspector/InspectedFrames.h" #include "core/inspector/InspectorPageAgent.h" #include "core/inspector/InspectorState.h" #include "core/inspector/InstrumentingAgents.h" @@ -94,20 +95,17 @@ { result = TypeBuilder::Array<TypeBuilder::ApplicationCache::FrameWithManifest>::create(); - LocalFrame* inspectedFrame = m_pageAgent->inspectedFrame(); - for (Frame* frame = inspectedFrame; frame; frame = frame->tree().traverseNext(inspectedFrame)) { - if (!frame->isLocalFrame()) - continue; - DocumentLoader* documentLoader = toLocalFrame(frame)->loader().documentLoader(); + for (LocalFrame* frame : InspectedFrames(m_pageAgent->inspectedFrame())) { + DocumentLoader* documentLoader = frame->loader().documentLoader(); if (!documentLoader) - continue; + return; ApplicationCacheHost* host = documentLoader->applicationCacheHost(); ApplicationCacheHost::CacheInfo info = host->applicationCacheInfo(); String manifestURL = info.m_manifest.string(); if (!manifestURL.isEmpty()) { RefPtr<TypeBuilder::ApplicationCache::FrameWithManifest> value = TypeBuilder::ApplicationCache::FrameWithManifest::create() - .setFrameId(IdentifiersFactory::frameId(toLocalFrame(frame))) + .setFrameId(IdentifiersFactory::frameId(frame)) .setManifestURL(manifestURL) .setStatus(static_cast<int>(host->status())); result->addItem(value);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp index 38f8be7..71742fce 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
@@ -68,6 +68,7 @@ #include "core/inspector/IdentifiersFactory.h" #include "core/inspector/InjectedScriptHost.h" #include "core/inspector/InjectedScriptManager.h" +#include "core/inspector/InspectedFrames.h" #include "core/inspector/InspectorHighlight.h" #include "core/inspector/InspectorHistory.h" #include "core/inspector/InspectorPageAgent.h" @@ -303,13 +304,11 @@ WillBeHeapVector<RawPtrWillBeMember<Document> > InspectorDOMAgent::documents() { WillBeHeapVector<RawPtrWillBeMember<Document> > result; - for (Frame* frame = m_document->frame(); frame; frame = frame->tree().traverseNext()) { - if (!frame->isLocalFrame()) - continue; - Document* document = toLocalFrame(frame)->document(); - if (!document) - continue; - result.append(document); + if (m_document) { + for (LocalFrame* frame : InspectedFrames(m_pageAgent->inspectedFrame())) { + if (Document* document = frame->document()) + result.append(document); + } } return result; }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp index 09772def..ed16c08d 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
@@ -207,7 +207,7 @@ PassRefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> > InspectorLayerTreeAgent::buildLayerTree() { - PaintLayerCompositor* compositor = deprecatedPaintLayerCompositor(); + PaintLayerCompositor* compositor = paintLayerCompositor(); if (!compositor || !compositor->inCompositingMode()) return nullptr; @@ -254,7 +254,7 @@ return DOMNodeIds::idForNode(node); } -PaintLayerCompositor* InspectorLayerTreeAgent::deprecatedPaintLayerCompositor() +PaintLayerCompositor* InspectorLayerTreeAgent::paintLayerCompositor() { LayoutView* layoutView = m_pageAgent->inspectedFrame()->contentLayoutObject(); PaintLayerCompositor* compositor = layoutView ? layoutView->compositor() : nullptr; @@ -289,7 +289,7 @@ *errorString = "Invalid layer id"; return nullptr; } - PaintLayerCompositor* compositor = deprecatedPaintLayerCompositor(); + PaintLayerCompositor* compositor = paintLayerCompositor(); if (!compositor) { *errorString = "Not in compositing mode"; return nullptr;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h index 4f758dd..fbd1b82b 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h
@@ -94,7 +94,7 @@ GraphicsLayer* rootGraphicsLayer(); - PaintLayerCompositor* deprecatedPaintLayerCompositor(); + PaintLayerCompositor* paintLayerCompositor(); GraphicsLayer* layerById(ErrorString*, const String& layerId); const PictureSnapshot* snapshotById(ErrorString*, const String& snapshotId);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorOverlayPage.html b/third_party/WebKit/Source/core/inspector/InspectorOverlayPage.html index 9b83ed24..4f473b03 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorOverlayPage.html +++ b/third_party/WebKit/Source/core/inspector/InspectorOverlayPage.html
@@ -1275,11 +1275,6 @@ </script> </head> <body class="fill"> -<div class="controls-line"> - <div class="message-box"><div id="paused-in-debugger"></div></div> - <div class="button" id="resume-button" title="Resume script execution (F8)."><div class="glyph"></div></div> - <div class="button" id="step-over-button" title="Step over next function call (F10)."><div class="glyph"></div></div> -</div> </body> <canvas id="canvas" class="fill"></canvas> <div id="element-title"> @@ -1288,5 +1283,10 @@ </div> <div id="tooltip-container"></div> <div id="editor" class="fill"></div> +<div class="controls-line"> + <div class="message-box"><div id="paused-in-debugger"></div></div> + <div class="button" id="resume-button" title="Resume script execution (F8)."><div class="glyph"></div></div> + <div class="button" id="step-over-button" title="Step over next function call (F10)."><div class="glyph"></div></div> +</div> <div id="log"></div> </html>
diff --git a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp index e2ac51b3..7926014 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
@@ -53,6 +53,7 @@ #include "core/inspector/ContentSearchUtils.h" #include "core/inspector/DOMPatchSupport.h" #include "core/inspector/IdentifiersFactory.h" +#include "core/inspector/InspectedFrames.h" #include "core/inspector/InspectorCSSAgent.h" #include "core/inspector/InspectorDebuggerAgent.h" #include "core/inspector/InspectorInstrumentation.h" @@ -652,12 +653,9 @@ LocalFrame* InspectorPageAgent::findFrameWithSecurityOrigin(const String& originRawString) { - for (Frame* frame = inspectedFrame(); frame; frame = frame->tree().traverseNext(inspectedFrame())) { - if (!frame->isLocalFrame()) - continue; - RefPtr<SecurityOrigin> documentOrigin = toLocalFrame(frame)->document()->securityOrigin(); - if (documentOrigin->toRawString() == originRawString) - return toLocalFrame(frame); + for (LocalFrame* frame : InspectedFrames(inspectedFrame())) { + if (frame->document()->securityOrigin()->toRawString() == originRawString) + return frame; } return nullptr; }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp index b4ada728..56a07c2 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp
@@ -50,6 +50,7 @@ #include "core/inspector/ConsoleMessage.h" #include "core/inspector/ConsoleMessageStorage.h" #include "core/inspector/IdentifiersFactory.h" +#include "core/inspector/InspectedFrames.h" #include "core/inspector/InspectorPageAgent.h" #include "core/inspector/InspectorState.h" #include "core/inspector/InstrumentingAgents.h" @@ -1024,10 +1025,8 @@ m_state->setBoolean(ResourceAgentState::cacheDisabled, cacheDisabled); if (cacheDisabled) memoryCache()->evictResources(); - for (Frame* frame = m_pageAgent->inspectedFrame(); frame; frame = frame->tree().traverseNext()) { - if (frame->isLocalFrame()) - toLocalFrame(frame)->document()->fetcher()->garbageCollectDocumentResources(); - } + for (LocalFrame* frame : InspectedFrames(m_pageAgent->inspectedFrame())) + frame->document()->fetcher()->garbageCollectDocumentResources(); } void InspectorResourceAgent::emulateNetworkConditions(ErrorString*, bool, double, double, double)
diff --git a/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp b/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp index 85c904b..c9a9f038 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp
@@ -16,6 +16,7 @@ #include "core/fetch/ResourcePtr.h" #include "core/fetch/StyleSheetResourceClient.h" #include "core/frame/LocalFrame.h" +#include "core/inspector/InspectedFrames.h" #include "core/inspector/InspectorCSSAgent.h" #include "core/inspector/InspectorPageAgent.h" #include "core/page/Page.h" @@ -84,12 +85,9 @@ { m_started = true; WillBeHeapVector<RawPtrWillBeMember<Document>> documents; - for (Frame* frame = m_inspectedFrame; frame; frame = frame->tree().traverseNext(m_inspectedFrame)) { - if (!frame->isLocalFrame()) - continue; - LocalFrame* localFrame = toLocalFrame(frame); - documents.append(localFrame->document()); - documents.appendVector(InspectorPageAgent::importsForFrame(localFrame)); + for (LocalFrame* frame : InspectedFrames(m_inspectedFrame)) { + documents.append(frame->document()); + documents.appendVector(InspectorPageAgent::importsForFrame(frame)); } for (Document* document : documents) { HashSet<String> urlsToFetch;
diff --git a/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp b/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp index be8b355..fcac1cd 100644 --- a/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp
@@ -39,6 +39,7 @@ #include "core/inspector/IdentifiersFactory.h" #include "core/inspector/InjectedScript.h" #include "core/inspector/InjectedScriptManager.h" +#include "core/inspector/InspectedFrames.h" #include "core/inspector/InspectorPageAgent.h" #include "core/inspector/InstrumentingAgents.h" #include "core/page/Page.h" @@ -154,20 +155,17 @@ void PageRuntimeAgent::reportExecutionContextCreation() { - Vector<std::pair<ScriptState*, SecurityOrigin*> > isolatedContexts; - for (Frame* frame = m_pageAgent->inspectedFrame(); frame; frame = frame->tree().traverseNext(m_pageAgent->inspectedFrame())) { - if (!frame->isLocalFrame()) + Vector<std::pair<ScriptState*, SecurityOrigin*>> isolatedContexts; + for (LocalFrame* frame : InspectedFrames(m_pageAgent->inspectedFrame())) { + if (!frame->script().canExecuteScripts(NotAboutToExecuteScript)) continue; - LocalFrame* localFrame = toLocalFrame(frame); - if (!localFrame->script().canExecuteScripts(NotAboutToExecuteScript)) - continue; - String frameId = IdentifiersFactory::frameId(localFrame); + String frameId = IdentifiersFactory::frameId(frame); // Ensure execution context is created. // If initializeMainWorld returns true, then is registered by didCreateScriptContext - if (!localFrame->script().initializeMainWorld()) - reportExecutionContext(ScriptState::forMainWorld(localFrame), true, "", frameId); - localFrame->script().collectIsolatedContexts(isolatedContexts); + if (!frame->script().initializeMainWorld()) + reportExecutionContext(ScriptState::forMainWorld(frame), true, "", frameId); + frame->script().collectIsolatedContexts(isolatedContexts); if (isolatedContexts.isEmpty()) continue; for (const auto& pair : isolatedContexts) {
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp index 44a9fa5..cc1ea91 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -2040,9 +2040,12 @@ LayoutUnit LayoutBox::fillAvailableMeasure(LayoutUnit availableLogicalWidth, LayoutUnit& marginStart, LayoutUnit& marginEnd) const { + ASSERT(availableLogicalWidth >= 0); marginStart = minimumValueForLength(style()->marginStart(), availableLogicalWidth); marginEnd = minimumValueForLength(style()->marginEnd(), availableLogicalWidth); - return availableLogicalWidth - marginStart - marginEnd; + LayoutUnit available = availableLogicalWidth - marginStart - marginEnd; + available = std::max(available, LayoutUnit()); + return available; } LayoutUnit LayoutBox::computeIntrinsicLogicalWidthUsing(const Length& logicalWidthLength, LayoutUnit availableLogicalWidth, LayoutUnit borderAndPadding) const
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.h b/third_party/WebKit/Source/core/layout/LayoutBox.h index c0998aa..7ec9481 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBox.h +++ b/third_party/WebKit/Source/core/layout/LayoutBox.h
@@ -80,6 +80,94 @@ LayoutUnit m_paginationStrut; }; +// LayoutBox implements the full CSS box model. +// +// LayoutBoxModelObject only introduces some abstractions for LayoutInline and +// LayoutBox. The logic for the model is in LayoutBox, e.g. the storage for the +// rectangle and offset forming the CSS box (m_frameRect) and the getters for +// the different boxes. +// +// LayoutBox is also the uppermost class to support scrollbars, however the +// logic is delegated to PaintLayerScrollableArea. +// Per the CSS specification, scrollbars should "be inserted between the inner +// border edge and the outer padding edge". +// (see http://www.w3.org/TR/CSS21/visufx.html#overflow) +// Also the scrollbar width / height are removed from the content box. Taking +// the following example: +// +// <!DOCTYPE html> +// <style> +// ::-webkit-scrollbar { +// /* Force non-overlay scrollbars */ +// width: 10px; +// height: 20px; +// } +// </style> +// <div style="overflow:scroll; width: 100px; height: 100px"> +// +// The <div>'s content box is not 100x100 as specified in the style but 90x80 as +// we remove the scrollbars from the box. +// +// The presence of scrollbars is determined by the 'overflow' property and can +// be conditioned on having layout overflow (see OverflowModel for more details +// on how we track overflow). +// +// There are 2 types of scrollbars: +// - non-overlay scrollbars take space from the content box. +// - overlay scrollbars don't and just overlay hang off from the border box, +// potentially overlapping with the padding box's content. +// +// +// ***** THE BOX MODEL ***** +// The CSS box model is based on a series of nested boxes: +// http://www.w3.org/TR/CSS21/box.html +// +// |----------------------------------------------------| +// | | +// | margin-top | +// | | +// | |-----------------------------------------| | +// | | | | +// | | border-top | | +// | | | | +// | | |--------------------------|----| | | +// | | | | | | | +// | | | padding-top |####| | | +// | | | |####| | | +// | | | |----------------| |####| | | +// | | | | | | | | | +// | ML | BL | PL | content box | PR | SW | BR | MR | +// | | | | | | | | | +// | | | |----------------| | | | | +// | | | | | | | +// | | | padding-bottom | | | | +// | | |--------------------------|----| | | +// | | | ####| | | | +// | | | scrollbar height ####| SC | | | +// | | | ####| | | | +// | | |-------------------------------| | | +// | | | | +// | | border-bottom | | +// | | | | +// | |-----------------------------------------| | +// | | +// | margin-bottom | +// | | +// |----------------------------------------------------| +// +// BL = border-left +// BR = border-right +// ML = margin-left +// MR = margin-right +// PL = padding-left +// PR = padding-right +// SC = scroll corner (contains UI for resizing (see the 'resize' property) +// SW = scrollbar width +// +// Those are just the boxes from the CSS model. Extra boxes are tracked by Blink +// (e.g. the overflows). Thus it is paramount to know which box a function is +// manipulating. Also of critical importance is the coordinate system used (see +// the COORDINATE SYSTEMS section in LayoutBoxModelObject). class CORE_EXPORT LayoutBox : public LayoutBoxModelObject { public: explicit LayoutBox(ContainerNode*);
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h index 1ee9b3d..04a47f3 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h +++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h
@@ -65,8 +65,8 @@ // This class is the base class for all CSS objects. // -// All CSS objects follow the box model object: -// http://www.w3.org/TR/CSS21/box.html +// All CSS objects follow the box model object. See THE BOX MODEL section in +// LayoutBox for more information. // // This class actually doesn't have the box model but it exposes some common // functions or concepts that sub-classes can extend upon. For example, there @@ -86,6 +86,9 @@ // design as it limits code sharing and prevents hardware accelerating SVG // (the current design require a PaintLayer for compositing). // +// +// ***** COORDINATE SYSTEMS ***** +// // In order to fully understand LayoutBoxModelObject and the inherited classes, // we need to introduce the concept of coordinate systems. // There is 3 main coordinate systems:
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp index 232d9ec..9a6b052 100644 --- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
@@ -869,6 +869,7 @@ LayoutUnit maxExtent = -1; if (max.isSpecifiedOrIntrinsic()) { maxExtent = computeMainAxisExtentForChild(child, MaxSize, max); + ASSERT(maxExtent >= -1); if (maxExtent != -1 && childSize > maxExtent) childSize = maxExtent; }
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp index 9187c5d3..f358ae92 100644 --- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp +++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -2144,8 +2144,7 @@ dirtyRect.intersect(paintInfo.localClipRectForSquashedLayer); { ASSERT(context->displayItemList()); - if (!context->displayItemList()->displayItemConstructionIsDisabled()) - context->displayItemList()->createAndAppend<ClipDisplayItem>(*this, DisplayItem::ClipLayerOverflowControls, dirtyRect); + context->displayItemList()->createAndAppend<ClipDisplayItem>(*this, DisplayItem::ClipLayerOverflowControls, dirtyRect); } PaintLayerPainter(*paintInfo.paintLayer).paintLayer(context, paintingInfo, paintLayerFlags); {
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp index 5c470ee..6cd6c80 100644 --- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
@@ -310,7 +310,7 @@ scrollbarGraphicsLayer->setDrawsContent(true); } -static void setupScrollbarLayer(GraphicsLayer* scrollbarGraphicsLayer, WebScrollbarLayer* scrollbarLayer, WebLayer* scrollLayer, WebLayer* containerLayer) +static void setupScrollbarLayer(GraphicsLayer* scrollbarGraphicsLayer, WebScrollbarLayer* scrollbarLayer, WebLayer* scrollLayer) { ASSERT(scrollbarGraphicsLayer); ASSERT(scrollbarLayer); @@ -320,7 +320,6 @@ return; } scrollbarLayer->setScrollLayer(scrollLayer); - scrollbarLayer->setClipLayer(containerLayer); scrollbarGraphicsLayer->setContentsToPlatformLayer(scrollbarLayer->layer()); scrollbarGraphicsLayer->setDrawsContent(false); } @@ -381,8 +380,7 @@ } WebLayer* scrollLayer = toWebLayer(scrollableArea->layerForScrolling()); - WebLayer* scrollbarContainerLayer = toWebLayer(scrollableArea->layerForContainer()); - setupScrollbarLayer(scrollbarGraphicsLayer, scrollbarLayer, scrollLayer, scrollbarContainerLayer); + setupScrollbarLayer(scrollbarGraphicsLayer, scrollbarLayer, scrollLayer); // Root layer non-overlay scrollbars should be marked opaque to disable // blending. @@ -431,13 +429,13 @@ if (WebScrollbarLayer* scrollbarLayer = getWebScrollbarLayer(scrollableArea, HorizontalScrollbar)) { GraphicsLayer* horizontalScrollbarLayer = scrollableArea->layerForHorizontalScrollbar(); if (horizontalScrollbarLayer) - setupScrollbarLayer(horizontalScrollbarLayer, scrollbarLayer, webLayer, containerLayer); + setupScrollbarLayer(horizontalScrollbarLayer, scrollbarLayer, webLayer); } if (WebScrollbarLayer* scrollbarLayer = getWebScrollbarLayer(scrollableArea, VerticalScrollbar)) { GraphicsLayer* verticalScrollbarLayer = scrollableArea->layerForVerticalScrollbar(); if (verticalScrollbarLayer) - setupScrollbarLayer(verticalScrollbarLayer, scrollbarLayer, webLayer, containerLayer); + setupScrollbarLayer(verticalScrollbarLayer, scrollbarLayer, webLayer); } // Update the viewport layer registration if the outer viewport may have changed.
diff --git a/third_party/WebKit/Source/core/paint/CompositingRecorder.cpp b/third_party/WebKit/Source/core/paint/CompositingRecorder.cpp index dea972f..0fb894e 100644 --- a/third_party/WebKit/Source/core/paint/CompositingRecorder.cpp +++ b/third_party/WebKit/Source/core/paint/CompositingRecorder.cpp
@@ -28,8 +28,6 @@ void CompositingRecorder::beginCompositing(GraphicsContext& graphicsContext, const DisplayItemClientWrapper& client, const SkXfermode::Mode xferMode, const float opacity, const FloatRect* bounds, ColorFilter colorFilter) { ASSERT(graphicsContext.displayItemList()); - if (graphicsContext.displayItemList()->displayItemConstructionIsDisabled()) - return; graphicsContext.displayItemList()->createAndAppend<BeginCompositingDisplayItem>(client, xferMode, opacity, bounds, colorFilter); }
diff --git a/third_party/WebKit/Source/core/paint/FloatClipRecorder.cpp b/third_party/WebKit/Source/core/paint/FloatClipRecorder.cpp index 22c079c..5e534ed 100644 --- a/third_party/WebKit/Source/core/paint/FloatClipRecorder.cpp +++ b/third_party/WebKit/Source/core/paint/FloatClipRecorder.cpp
@@ -17,8 +17,6 @@ , m_clipType(DisplayItem::paintPhaseToFloatClipType(paintPhase)) { ASSERT(m_context.displayItemList()); - if (m_context.displayItemList()->displayItemConstructionIsDisabled()) - return; m_context.displayItemList()->createAndAppend<FloatClipDisplayItem>(m_client, m_clipType, clipRect); }
diff --git a/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp b/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp index afd686d..91579e11 100644 --- a/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp +++ b/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp
@@ -29,8 +29,6 @@ } ASSERT(m_graphicsContext.displayItemList()); - if (m_graphicsContext.displayItemList()->displayItemConstructionIsDisabled()) - return; m_graphicsContext.displayItemList()->createAndAppend<ClipDisplayItem>(layoutObject, m_clipType, snappedClipRect, roundedRects); }
diff --git a/third_party/WebKit/Source/core/paint/LayerFixedPositionRecorder.cpp b/third_party/WebKit/Source/core/paint/LayerFixedPositionRecorder.cpp index 41c086e..8ef3fc1 100644 --- a/third_party/WebKit/Source/core/paint/LayerFixedPositionRecorder.cpp +++ b/third_party/WebKit/Source/core/paint/LayerFixedPositionRecorder.cpp
@@ -23,9 +23,6 @@ if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) return; - if (m_graphicsContext.displayItemList()->displayItemConstructionIsDisabled()) - return; - if (m_isFixedPosition) m_graphicsContext.displayItemList()->createAndAppend<BeginFixedPositionDisplayItem>(m_layoutObject);
diff --git a/third_party/WebKit/Source/core/paint/ObjectPaintProperties.h b/third_party/WebKit/Source/core/paint/ObjectPaintProperties.h new file mode 100644 index 0000000..5bce088 --- /dev/null +++ b/third_party/WebKit/Source/core/paint/ObjectPaintProperties.h
@@ -0,0 +1,49 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ObjectPaintProperties_h +#define ObjectPaintProperties_h + +#include "platform/graphics/paint/TransformPaintPropertyNode.h" +#include "wtf/PassRefPtr.h" +#include "wtf/RefPtr.h" + +namespace blink { + +// The minimal set of paint properties created by a |LayoutObject|. These +// properties encode a hierachy of transforms, clips, effects, etc, both between +// LayoutObjects (each property has a parent) and among the properties of a +// single LayoutObject (e.g., transform and perspective with the correct parent +// relationship to represent ordering). +// +// This differs from |PaintChunkProperties| because it can store multiple +// properties of the same type (e.g., transform and perspective which are both +// transforms). +class ObjectPaintProperties { + WTF_MAKE_NONCOPYABLE(ObjectPaintProperties); + WTF_MAKE_FAST_ALLOCATED(ObjectPaintProperties); +public: + static PassOwnPtr<ObjectPaintProperties> create() + { + return adoptPtr(new ObjectPaintProperties()); + } + + bool hasTransform() const { return m_transform; } + void setTransform(PassRefPtr<TransformPaintPropertyNode> transform) { m_transform = transform; } + const TransformPaintPropertyNode* transform() const { return m_transform.get(); } + + bool hasPerspective() const { return m_perspective; } + void setPerspective(PassRefPtr<TransformPaintPropertyNode> perspective) { m_perspective = perspective; } + const TransformPaintPropertyNode* perspective() const { return m_perspective.get(); } + +private: + ObjectPaintProperties() { } + + RefPtr<TransformPaintPropertyNode> m_transform; + RefPtr<TransformPaintPropertyNode> m_perspective; +}; + +} // namespace blink + +#endif // ObjectPaintProperties_h
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp index 7bdb7351..14d04fe 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -72,6 +72,7 @@ #include "core/page/Page.h" #include "core/page/scrolling/ScrollingCoordinator.h" #include "core/paint/FilterEffectBuilder.h" +#include "core/paint/ObjectPaintProperties.h" #include "platform/LengthFunctions.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/TraceEvent.h" @@ -2714,6 +2715,22 @@ } } +ObjectPaintProperties& PaintLayer::mutablePaintProperties() +{ + ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); + ASSERT(layoutObject()->document().lifecycle().state() == DocumentLifecycle::InUpdatePaintProperties); + if (!m_paintProperties) + m_paintProperties = ObjectPaintProperties::create(); + return *m_paintProperties; +} + +const ObjectPaintProperties* PaintLayer::paintProperties() const +{ + ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); + ASSERT(layoutObject()->document().lifecycle().state() == DocumentLifecycle::InPaint); + return m_paintProperties.get(); +} + DisableCompositingQueryAsserts::DisableCompositingQueryAsserts() : m_disabler(gCompositingQueryMode, CompositingQueriesAreAllowed) { }
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.h b/third_party/WebKit/Source/core/paint/PaintLayer.h index 57a380e..a9a83600 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayer.h +++ b/third_party/WebKit/Source/core/paint/PaintLayer.h
@@ -66,6 +66,7 @@ class HitTestRequest; class HitTestResult; class HitTestingTransformState; +class ObjectPaintProperties; class PaintLayerCompositor; class CompositedLayerMapping; class ComputedStyle; @@ -89,28 +90,21 @@ }; // PaintLayer is an old object that handles lots of unrelated operations. -// We want it to die at some point and be replaced by more focused objects. Removing -// a lot of unneeded complexity. -// Complex painting operations (opacity, clipping, filters, reflections, ...), -// hardware acceleration (through PaintLayerCompositor), -// scrolling (through PaintLayerScrollableArea) -// along with some optimizations are all handled by PaintLayer. +// We want it to die at some point and be replaced by more focused objects. +// Removing a lot of unneeded complexity. Complex painting operations (opacity, +// clipping, filters, reflections, ...), hardware acceleration (through +// PaintLayerCompositor), scrolling (through PaintLayerScrollableArea) along +// with some optimizations are all handled by PaintLayer. // // The class is central to painting and hit-testing: it implements the painting -// order through PaintLayerStackingNode and handle lots of complex -// graphics operations LayoutObjects don't handle (e.g. 'filter' and 'opacity'). +// order through PaintLayerStackingNode and handle lots of complex graphics +// operations LayoutObjects don't handle (e.g. 'filter' and 'opacity'). // -// The compositing code is also based on PaintLayer. The entry to it -// is the PaintLayerCompositor, which fills -// |m_compositedLayerMapping| for hardware accelerated layers. +// The compositing code is also based on PaintLayer. The entry to it is the +// PaintLayerCompositor, which fills |m_compositedLayerMapping| for hardware +// accelerated layers. // // TODO(jchaffraix): Expand the documentation about hardware acceleration. -// -// The class is DEPRECATED, which means that we would like to remove it. The -// reason for removal is that it has been a dumping ground for features for too -// long and is the wrong level of abstraction, bearing no correspondence to any -// CSS concept. Its associated objects and some of its feature need to be -// migrated to LayoutObject (or the appropriate sub-class). class CORE_EXPORT PaintLayer { WTF_MAKE_NONCOPYABLE(PaintLayer); public: @@ -575,6 +569,12 @@ // For subsequence display items. DisplayItemClient displayItemClient() const { return toDisplayItemClient(this); } + // Paint properties encode the hierarchical transform, clip, scroll, and + // effect information used for painting. Properties should only be changed + // during UpdatePaintProperties, and should only be used during Paint. + ObjectPaintProperties& mutablePaintProperties(); + const ObjectPaintProperties* paintProperties() const; + private: // Bounding box in the coordinates of this layer. LayoutRect logicalBoundingBox() const; @@ -759,6 +759,11 @@ OwnPtr<PaintLayerStackingNode> m_stackingNode; OwnPtr<PaintLayerReflectionInfo> m_reflectionInfo; + // Lazily-allocated paint properties for m_layoutObject, stored here to + // reduce memory usage as PaintLayers are created for all paint property + // layout objects. + OwnPtr<ObjectPaintProperties> m_paintProperties; + LayoutSize m_subpixelAccumulation; // The accumulated subpixel offset of a composited layer's composited bounds compared to absolute coordinates. IntSize m_previousScrollOffsetAccumulationForPainting;
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerClipper.h b/third_party/WebKit/Source/core/paint/PaintLayerClipper.h index 5e5c494..44d2eef6 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerClipper.h +++ b/third_party/WebKit/Source/core/paint/PaintLayerClipper.h
@@ -152,9 +152,6 @@ // #container and #fixed are siblings in the paint tree but #container does // clip #fixed. This is the reason why we compute the painting clip rects during // a layout tree walk and cache them for painting. -// -// This class is NOT DEPRECATED, PaintLayer is and we match its -// naming. class PaintLayerClipper { DISALLOW_ALLOCATION(); WTF_MAKE_NONCOPYABLE(PaintLayerClipper);
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerStackingNode.h b/third_party/WebKit/Source/core/paint/PaintLayerStackingNode.h index 1c548212..b1d794f8 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerStackingNode.h +++ b/third_party/WebKit/Source/core/paint/PaintLayerStackingNode.h
@@ -82,9 +82,6 @@ // To implement any z-order list iterations, use // PaintLayerStackingNodeIterator and // PaintLayerStackingNodeReverseIterator. -// -// This class is NOT DEPRECATED, PaintLayer is and we match its -// naming. class CORE_EXPORT PaintLayerStackingNode { WTF_MAKE_FAST_ALLOCATED(PaintLayerStackingNode); WTF_MAKE_NONCOPYABLE(PaintLayerStackingNode);
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerStackingNodeIterator.cpp b/third_party/WebKit/Source/core/paint/PaintLayerStackingNodeIterator.cpp index d1fbff76..ebce038 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerStackingNodeIterator.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerStackingNodeIterator.cpp
@@ -32,7 +32,7 @@ #include "core/paint/PaintLayerStackingNodeIterator.h" // FIXME: We should build our primitive on top of -// DeprecatedLayerStackingNode and remove this include. +// PaintLayerStackingNode and remove this include. #include "core/paint/PaintLayer.h" #include "core/paint/PaintLayerStackingNode.h"
diff --git a/third_party/WebKit/Source/core/paint/RoundedInnerRectClipper.cpp b/third_party/WebKit/Source/core/paint/RoundedInnerRectClipper.cpp index e7b454d..d8ed29b 100644 --- a/third_party/WebKit/Source/core/paint/RoundedInnerRectClipper.cpp +++ b/third_party/WebKit/Source/core/paint/RoundedInnerRectClipper.cpp
@@ -50,8 +50,6 @@ if (m_useDisplayItemList) { ASSERT(m_paintInfo.context->displayItemList()); - if (m_paintInfo.context->displayItemList()->displayItemConstructionIsDisabled()) - return; m_paintInfo.context->displayItemList()->createAndAppend<ClipDisplayItem>(layoutObject, m_clipType, LayoutRect::infiniteIntRect(), roundedRectClips); } else { ClipDisplayItem clipDisplayItem(layoutObject, m_clipType, LayoutRect::infiniteIntRect(), roundedRectClips);
diff --git a/third_party/WebKit/Source/core/paint/SVGClipPainter.cpp b/third_party/WebKit/Source/core/paint/SVGClipPainter.cpp index a34eb298..5738e22 100644 --- a/third_party/WebKit/Source/core/paint/SVGClipPainter.cpp +++ b/third_party/WebKit/Source/core/paint/SVGClipPainter.cpp
@@ -60,8 +60,7 @@ if (m_clip.asPath(animatedLocalTransform, targetBoundingBox, clipPath)) { clipperState = ClipperAppliedPath; ASSERT(context->displayItemList()); - if (!context->displayItemList()->displayItemConstructionIsDisabled()) - context->displayItemList()->createAndAppend<BeginClipPathDisplayItem>(target, clipPath); + context->displayItemList()->createAndAppend<BeginClipPathDisplayItem>(target, clipPath); return true; }
diff --git a/third_party/WebKit/Source/core/paint/SVGMaskPainter.cpp b/third_party/WebKit/Source/core/paint/SVGMaskPainter.cpp index f8494be..6beb4ca 100644 --- a/third_party/WebKit/Source/core/paint/SVGMaskPainter.cpp +++ b/third_party/WebKit/Source/core/paint/SVGMaskPainter.cpp
@@ -29,10 +29,7 @@ return false; ASSERT(context->displayItemList()); - if (context->displayItemList()->displayItemConstructionIsDisabled()) - return true; context->displayItemList()->createAndAppend<BeginCompositingDisplayItem>(object, SkXfermode::kSrcOver_Mode, 1, &paintInvalidationRect); - return true; }
diff --git a/third_party/WebKit/Source/core/paint/ScrollRecorder.cpp b/third_party/WebKit/Source/core/paint/ScrollRecorder.cpp index 323b89f..ad539ee2 100644 --- a/third_party/WebKit/Source/core/paint/ScrollRecorder.cpp +++ b/third_party/WebKit/Source/core/paint/ScrollRecorder.cpp
@@ -17,8 +17,6 @@ , m_context(context) { ASSERT(m_context.displayItemList()); - if (m_context.displayItemList()->displayItemConstructionIsDisabled()) - return; m_context.displayItemList()->createAndAppend<BeginScrollDisplayItem>(m_client, m_beginItemType, currentOffset); }
diff --git a/third_party/WebKit/Source/core/paint/Transform3DRecorder.cpp b/third_party/WebKit/Source/core/paint/Transform3DRecorder.cpp index 3ac856e4..d8de8e1 100644 --- a/third_party/WebKit/Source/core/paint/Transform3DRecorder.cpp +++ b/third_party/WebKit/Source/core/paint/Transform3DRecorder.cpp
@@ -28,8 +28,6 @@ return; ASSERT(m_context.displayItemList()); - if (m_context.displayItemList()->displayItemConstructionIsDisabled()) - return; m_context.displayItemList()->createAndAppend<BeginTransform3DDisplayItem>(m_client, m_type, transform, transformOrigin); }
diff --git a/third_party/WebKit/Source/core/paint/TransformRecorder.cpp b/third_party/WebKit/Source/core/paint/TransformRecorder.cpp index e8f27f1..4f66ea3 100644 --- a/third_party/WebKit/Source/core/paint/TransformRecorder.cpp +++ b/third_party/WebKit/Source/core/paint/TransformRecorder.cpp
@@ -21,8 +21,6 @@ return; ASSERT(m_context.displayItemList()); - if (m_context.displayItemList()->displayItemConstructionIsDisabled()) - return; m_context.displayItemList()->createAndAppend<BeginTransformDisplayItem>(m_client, transform); }
diff --git a/third_party/WebKit/Source/core/streams/ByteLengthQueuingStrategy.js b/third_party/WebKit/Source/core/streams/ByteLengthQueuingStrategy.js new file mode 100644 index 0000000..5fdb7c9 --- /dev/null +++ b/third_party/WebKit/Source/core/streams/ByteLengthQueuingStrategy.js
@@ -0,0 +1,24 @@ +(function(global, binding, v8) { + 'use strict'; + + const defineProperty = global.Object.defineProperty; + + class ByteLengthQueuingStrategy { + constructor(options) { + defineProperty(this, 'highWaterMark', { + value: options.highWaterMark, + enumerable: true, + configurable: true, + writable: true + }); + } + size(chunk) { return chunk.byteLength; } + } + + defineProperty(global, 'ByteLengthQueuingStrategy', { + value: ByteLengthQueuingStrategy, + enumerable: false, + configurable: true, + writable: true + }); +});
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js index cf767943..af35e20 100644 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js
@@ -132,6 +132,18 @@ }; /** + * @param {string} tooltip + * @return {!Element} + */ +WebInspector.AccessibilitySidebarView.createExclamationMark = function(tooltip) +{ + var exclamationElement = createElement("label", "dt-icon-label"); + exclamationElement.type = "warning-icon"; + exclamationElement.title = tooltip; + return exclamationElement; +}; + +/** * @constructor * @extends {WebInspector.SidebarPane} * @param {string} name @@ -177,9 +189,7 @@ createInfo: function(textContent, className) { var classNameOrDefault = className || "info"; - var info = createElementWithClass("div", classNameOrDefault); - info.textContent = textContent; - this.element.appendChild(info); + this.element.createChild("div", classNameOrDefault).textContent = info; return info; }, @@ -192,6 +202,7 @@ var treeOutline = new TreeOutlineInShadow(className); treeOutline.registerRequiredCSS("accessibility/accessibilityNode.css"); treeOutline.registerRequiredCSS("components/objectValue.css"); + treeOutline.element.classList.add("hidden"); this.element.appendChild(treeOutline.element); return treeOutline; @@ -251,10 +262,10 @@ function addProperty(property) { foundProperty = true; - treeOutline.appendChild(new WebInspector.AXNodePropertyTreeElement(property, target)); + treeOutline.appendChild(new WebInspector.AXNodePropertyTreePropertyElement(property, target)); } - if ("value" in axNode && axNode.value.type === "string") + if (axNode.value && axNode.value.type === AccessibilityAgent.AXValueType.String) addProperty(/** @type {!AccessibilityAgent.AXProperty} */ ({name: "value", value: axNode.value})); var propertiesArray = /** @type {!Array.<!AccessibilityAgent.AXProperty> } */ (axNode.properties); @@ -348,7 +359,7 @@ */ function addProperty(property) { - treeOutline.appendChild(new WebInspector.AXNodePropertyTreeElement(property, target)); + treeOutline.appendChild(new WebInspector.AXNodePropertyTreePropertyElement(property, target)); } for (var propertyName of ["name", "description", "help", "value"]) { @@ -379,139 +390,29 @@ }; /** - * @constructor - * @extends {TreeElement} - * @param {!AccessibilityAgent.AXProperty} property - * @param {!WebInspector.Target} target - */ -WebInspector.AXNodePropertyTreeElement = function(property, target) -{ - this._property = property; - this._target = target; - - // Pass an empty title, the title gets made later in onattach. - TreeElement.call(this, ""); - this.toggleOnClick = true; - this.selectable = false; -} - -WebInspector.AXNodePropertyTreeElement.prototype = { - /** - * @override - */ - onattach: function() - { - this._update(); - }, - - - _update: function() - { - this._nameElement = WebInspector.AXNodePropertyTreeElement.createNameElement(this._property.name); - - var value = this._property.value; - if (value.type === "idref") { - this._valueElement = WebInspector.AXNodePropertyTreeElement.createRelationshipValueElement(value, this._target); - } else if (value.type === "idrefList") { - var relatedNodes = value.relatedNodeArrayValue; - var numNodes = relatedNodes.length; - var description = "(" + numNodes + (numNodes == 1 ? " node" : " nodes") + ")"; - value.value = description; - for (var i = 0; i < relatedNodes.length; i++) { - var backendId = relatedNodes[i].backendNodeId; - var deferredNode = new WebInspector.DeferredDOMNode(this._target, relatedNodes[i].backendNodeId); - var child = new WebInspector.AXRelatedNodeTreeElement(deferredNode); - this.appendChild(child); - } - this._valueElement = WebInspector.AXNodePropertyTreeElement.createValueElement(value, this.listItemElement); - if (relatedNodes.length <= 3) - this.expand(); - else - this.collapse(); - } else { - this._valueElement = WebInspector.AXNodePropertyTreeElement.createValueElement(value, this.listItemElement); - } - - var separatorElement = createElementWithClass("span", "separator"); - separatorElement.textContent = ": "; - - this.listItemElement.removeChildren(); - this.listItemElement.appendChildren(this._nameElement, separatorElement, this._valueElement); - }, - - __proto__: TreeElement.prototype -} - -/** - * @param {!TreeElement} treeNode - * @param {?AccessibilityAgent.AXNode} axNode - * @param {!WebInspector.Target} target - */ -WebInspector.AXNodePropertyTreeElement.populateWithNode = function(treeNode, axNode, target) -{ -} - -/** - * @param {?string} name + * @param {!AccessibilityAgent.AXValueType} type + * @param {string} value * @return {!Element} */ -WebInspector.AXNodePropertyTreeElement.createNameElement = function(name) +WebInspector.AccessibilitySidebarView.createSimpleValueElement = function(type, value) { - var nameElement = createElement("span"); - var AXAttributes = WebInspector.AccessibilityStrings.AXAttributes; - if (name in AXAttributes) { - nameElement.textContent = WebInspector.UIString(AXAttributes[name].name); - nameElement.title = AXAttributes[name].description; - nameElement.classList.add("ax-readable-name"); - } else { - nameElement.textContent = name; - nameElement.classList.add("ax-name"); - } - return nameElement; -} - -/** - * @param {!AccessibilityAgent.AXValue} value - * @param {!WebInspector.Target} target - * @return {?Element} - */ -WebInspector.AXNodePropertyTreeElement.createRelationshipValueElement = function(value, target) -{ - var deferredNode = new WebInspector.DeferredDOMNode(target, value.relatedNodeValue.backendNodeId); - var valueElement = createElement("span"); - - /** - * @param {?WebInspector.DOMNode} node - */ - function onNodeResolved(node) - { - valueElement.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(node)); - } - deferredNode.resolve(onNodeResolved); - - return valueElement; -} - -/** - * @param {!AccessibilityAgent.AXValue} value - * @param {!Element} parentElement - * @return {!Element} - */ -WebInspector.AXNodePropertyTreeElement.createValueElement = function(value, parentElement) -{ - var valueElement = createElementWithClass("span", "monospace"); - var type = value.type; + var valueElement; + var AXValueType = AccessibilityAgent.AXValueType; + if (type === AXValueType.ValueUndefined || type === AXValueType.ComputedString) + valueElement = createElement("span"); + else + valueElement = createElementWithClass("span", "monospace"); var prefix; var valueText; var suffix; - if (type === "string") { - // Render \n as a nice unicode cr symbol. + if (type === AXValueType.String || type === AXValueType.ComputedString || type === AXValueType.IdrefList || type === AXValueType.Idref) { prefix = "\""; - valueText = value.value.replace(/\n/g, "\u21B5"); + // Render \n as a nice unicode cr symbol. + valueText = value.replace(/\n/g, "\u21B5"); suffix = "\""; - valueElement._originalTextContent = "\"" + value.value + "\""; + valueElement._originalTextContent = "\"" + value + "\""; } else { - valueText = String(value.value); + valueText = String(value); } if (type in WebInspector.AXNodePropertyTreeElement.TypeStyles) @@ -523,7 +424,7 @@ if (suffix) valueElement.createTextChild(suffix); - valueElement.title = String(value.value) || ""; + valueElement.title = String(value) || ""; return valueElement; } @@ -531,11 +432,277 @@ /** * @constructor * @extends {TreeElement} - * @param {!WebInspector.DeferredDOMNode} deferredNode + * @param {!WebInspector.Target} target */ -WebInspector.AXRelatedNodeTreeElement = function(deferredNode) +WebInspector.AXNodePropertyTreeElement = function(target) { - this._deferredNode = deferredNode; + this._target = target; + + // Pass an empty title, the title gets made later in onattach. + TreeElement.call(this, ""); +} + +WebInspector.AXNodePropertyTreeElement.prototype = { + /** + * @param {string} name + */ + appendNameElement: function(name) + { + var nameElement = createElement("span"); + var AXAttributes = WebInspector.AccessibilityStrings.AXAttributes; + if (name in AXAttributes) { + nameElement.textContent = WebInspector.UIString(AXAttributes[name].name); + nameElement.title = AXAttributes[name].description; + nameElement.classList.add("ax-readable-name"); + } else { + nameElement.textContent = name; + nameElement.classList.add("ax-name"); + nameElement.classList.add("monospace"); + } + this.listItemElement.appendChild(nameElement); + }, + + /** + * @param {!AccessibilityAgent.AXValue} value + */ + appendValueElement: function(value) + { + var AXValueType = AccessibilityAgent.AXValueType; + if (value.type === AXValueType.Idref || value.type === AXValueType.Node) { + this.appendRelationshipValueElement(value); + return; + } + if (value.type === AXValueType.IdrefList || value.type === AXValueType.NodeList) { + this.appendRelatedNodeListValueElement(value); + return; + } + if (value.sources) { + var sources = value.sources; + for (var i = 0; i < sources.length; i++) { + var source = sources[i]; + var child = new WebInspector.AXValueSourceTreeElement(source, this._target); + this.appendChild(child); + } + } + var valueElement = WebInspector.AccessibilitySidebarView.createSimpleValueElement(value.type, value.value); + this.listItemElement.appendChild(valueElement); + }, + + /** + * @param {!AccessibilityAgent.AXValue} value + */ + appendRelationshipValueElement: function(value) + { + var deferredNode = new WebInspector.DeferredDOMNode(this._target, value.relatedNodeValue.backendNodeId); + var valueElement = createElement("span"); + + /** + * @param {?WebInspector.DOMNode} node + */ + function onNodeResolved(node) + { + valueElement.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(node)); + if (value.relatedNodeValue.text) { + var textElement = WebInspector.AccessibilitySidebarView.createSimpleValueElement(AccessibilityAgent.AXValueType.ComputedString, value.relatedNodeValue.text); + valueElement.appendChild(textElement); + } + } + deferredNode.resolve(onNodeResolved); + + this.listItemElement.appendChild(valueElement); + }, + + /** + * @param {!AccessibilityAgent.AXValue} value + * @return {!Element} + */ + appendRelatedNodeListValueElement: function(value) + { + var relatedNodes = value.relatedNodeArrayValue; + var numNodes = relatedNodes.length; + var valueElement; + if (value.type === AccessibilityAgent.AXValueType.IdrefList) { + var idrefs = value.value.split(/\s/); + for (var idref of idrefs) { + var matchingNode = null; + /** + * @param {!AccessibilityAgent.AXRelatedNode} relatedNode + * @return {boolean} + */ + function matchesIDRef(relatedNode) + { + if (relatedNode.idref !== idref) + return false; + matchingNode = relatedNode; + return true; + } + relatedNodes.some(matchesIDRef); + if (matchingNode) { + var deferredNode = new WebInspector.DeferredDOMNode(this._target, matchingNode.backendNodeId); + var child = new WebInspector.AXRelatedNodeTreeElement({ deferredNode: deferredNode }, matchingNode); + this.appendChild(child); + } else { + this.appendChild(new WebInspector.AXRelatedNodeTreeElement({ idref: idref })); + } + } + valueElement = WebInspector.AccessibilitySidebarView.createSimpleValueElement(value.type, value.value); + } else { + for (var i = 0; i < numNodes; i++) { + var relatedNode = relatedNodes[i]; + var deferredNode = new WebInspector.DeferredDOMNode(this._target, relatedNode.backendNodeId); + var child = new WebInspector.AXRelatedNodeTreeElement({ deferredNode: deferredNode }, relatedNode); + this.appendChild(child); + } + var numNodesString = "(" + numNodes + (numNodes === 1 ? " node" : " nodes") + ")"; + valueElement = WebInspector.AccessibilitySidebarView.createSimpleValueElement("pseudo", numNodesString); + } + if (relatedNodes.length <= 3) + this.expand(); + else + this.collapse(); + this.listItemElement.appendChild(valueElement); + }, + + __proto__: TreeElement.prototype +} + +/** + * @constructor + * @extends {WebInspector.AXNodePropertyTreeElement} + * @param {!AccessibilityAgent.AXProperty} property + * @param {!WebInspector.Target} target + */ +WebInspector.AXNodePropertyTreePropertyElement = function(property, target) +{ + this._property = property; + this.toggleOnClick = true; + this.selectable = false; + + WebInspector.AXNodePropertyTreeElement.call(this, target); +} + +WebInspector.AXNodePropertyTreePropertyElement.prototype = { + /** + * @override + */ + onattach: function() + { + this._update(); + }, + + _update: function() + { + this.listItemElement.removeChildren(); + + this.appendNameElement(this._property.name); + + this.listItemElement.createChild("span", "separator").textContent = ": "; + + this.appendValueElement(this._property.value); + }, + + __proto__: WebInspector.AXNodePropertyTreeElement.prototype +} + +/** + * @constructor + * @extends {WebInspector.AXNodePropertyTreeElement} + * @param {!AccessibilityAgent.AXValueSource} + */ +WebInspector.AXValueSourceTreeElement = function(source, target) +{ + this._source = source; + WebInspector.AXNodePropertyTreeElement.call(this, target); +} + +WebInspector.AXValueSourceTreeElement.prototype = { + /** + * @override + */ + onattach: function() + { + this._update(); + }, + + /** + * @param {!AccessibilityAgent.AXValueSource} source + */ + appendSourceNameElement: function(source) + { + var nameElement = createElement("span"); + var AXValueSourceType = AccessibilityAgent.AXValueSourceType; + var type = source.type; + var name; + switch (type) { + case AXValueSourceType.Attribute: + case AXValueSourceType.Placeholder: + case AXValueSourceType.RelatedElement: + if (source.nativeSource) { + var AXNativeSourceTypes = WebInspector.AccessibilityStrings.AXNativeSourceTypes; + var nativeSource = source.nativeSource; + nameElement.textContent = WebInspector.UIString(AXNativeSourceTypes[nativeSource].name); + nameElement.title = WebInspector.UIString(AXNativeSourceTypes[nativeSource].description); + nameElement.classList.add("ax-readable-name"); + break; + } + nameElement.textContent = source.attribute; + nameElement.classList.add("ax-name"); + nameElement.classList.add("monospace"); + break; + default: + var AXSourceTypes = WebInspector.AccessibilityStrings.AXSourceTypes; + if (type in AXSourceTypes) { + nameElement.textContent = WebInspector.UIString(AXSourceTypes[type].name); + nameElement.title = WebInspector.UIString(AXSourceTypes[type].description); + nameElement.classList.add("ax-readable-name"); + } else { + console.warn(type, "not in AXSourceTypes"); + nameElement.textContent = WebInspector.UIString(type); + } + } + this.listItemElement.appendChild(nameElement); + }, + + /** @override */ + _update: function() { + this.listItemElement.removeChildren(); + + this.appendSourceNameElement(this._source); + + if (this._source.invalid) { + this.listItemElement.appendChild(WebInspector.AccessibilitySidebarView.createExclamationMark()); + this.listItemElement.classList.add("ax-value-source-invalid"); + } else if (this._source.superseded) { + this.listItemElement.classList.add("ax-value-source-unused"); + } + + this.listItemElement.createChild("span", "separator").textContent = ": "; + + if (this._source.value) { + this.appendValueElement(this._source.value); + if (this._source.superseded) + this.listItemElement.classList.add("ax-value-source-superseded"); + } else { + var valueElement = WebInspector.AccessibilitySidebarView.createSimpleValueElement(AccessibilityAgent.AXValueType.ValueUndefined, WebInspector.UIString("Not specified")); + this.listItemElement.appendChild(valueElement); + this.listItemElement.classList.add("ax-value-source-unused"); + } + }, + + __proto__: WebInspector.AXNodePropertyTreeElement.prototype +} + +/** + * @constructor + * @extends {TreeElement} + * @param {{deferredNode: !WebInspector.DeferredDOMNode, idref: string}} node + * @param {!AXRelatedNode=} value + */ +WebInspector.AXRelatedNodeTreeElement = function(node, value) +{ + this._deferredNode = node.deferredNode; + this._idref = node.idref; + this._value = value; TreeElement.call(this, ""); }; @@ -548,8 +715,7 @@ _update: function() { - var valueElement = createElement("div"); - this.listItemElement.appendChild(valueElement); + var valueElement; /** * @param {?WebInspector.DOMNode} node @@ -558,7 +724,21 @@ { valueElement.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(node)); } - this._deferredNode.resolve(onNodeResolved); + if (this._deferredNode) { + valueElement = createElement("span"); + this.listItemElement.appendChild(valueElement); + this._deferredNode.resolve(onNodeResolved); + } else { + this.listItemElement.classList.add("invalid"); + valueElement = WebInspector.AccessibilitySidebarView.createExclamationMark(WebInspector.UIString("No node with this ID.")); + valueElement.createTextChild(this._idref); + } + this.listItemElement.appendChild(valueElement); + if (this._value && this._value.text) { + var textElement = WebInspector.AccessibilitySidebarView.createSimpleValueElement(AccessibilityAgent.AXValueType.ComputedString, this._value.text); + this.listItemElement.appendChild(document.createTextNode(" ")); + this.listItemElement.appendChild(textElement); + } }, __proto__: TreeElement.prototype @@ -566,19 +746,24 @@ /** @type {!Object<string, string>} */ WebInspector.AXNodePropertyTreeElement.TypeStyles = { + attribute: "object-value-string", boolean: "object-value-boolean", booleanOrUndefined: "object-value-boolean", - tristate: "object-value-boolean", - number: "object-value-number", + computedString: "ax-readable-string", + idref: "object-value-string", + idrefList: "object-value-string", integer: "object-value-number", - string: "object-value-string", + internalRole: "ax-internal-role", + number: "object-value-number", role: "ax-role", - internalRole: "ax-internal-role" + string: "object-value-string", + tristate: "object-value-boolean", + valueUndefined: "ax-value-undefined" }; /** * @constructor - * @extends {TreeElement} + * @extends {WebInspector.AXNodePropertyTreeElement} * @param {!AccessibilityAgent.AXProperty} property * @param {?AccessibilityAgent.AXNode} axNode * @param {!WebInspector.Target} target @@ -587,10 +772,8 @@ { this._property = property; this._axNode = axNode; - this._target = target; - // Pass an empty title, the title gets made later in onattach. - TreeElement.call(this, ""); + WebInspector.AXNodePropertyTreeElement.call(this, target); this.toggleOnClick = true; this.selectable = false; } @@ -607,13 +790,11 @@ this.listItemElement.appendChild(this._reasonElement); var value = this._property.value; - if (value.type === "idref") { - this._valueElement = WebInspector.AXNodePropertyTreeElement.createRelationshipValueElement(value, this._target); - this.listItemElement.appendChild(this._valueElement); - } + if (value.type === AccessibilityAgent.AXValueType.Idref) + this._valueElement = this.appendRelationshipValueElement(value, this._target); }, - __proto__: TreeElement.prototype + __proto__: WebInspector.AXNodePropertyTreeElement.prototype }; /**
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityStrings.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityStrings.js index 48e5070..fb9b570 100644 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityStrings.js +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityStrings.js
@@ -162,7 +162,67 @@ }, "help": { name: "Help", - descrption: "The computed help text for this element.", + description: "The computed help text for this element.", + group: "Default" + }, + "description": { + name: "Description", + description: "The accessible description for this element.", group: "Default" } }; + +WebInspector.AccessibilityStrings.AXSourceTypes = { + "attribute": { + name: "From attribute", + description: "Value from attribute." + }, + "implicit": { + name: "Implicit", + description: "Implicit value.", + }, + "style": { + name: "From style", + description: "Value from style." + }, + "contents": { + name: "Contents", + description: "Value from element contents." + }, + "placeholder": { + name: "From placeholder attribute", + description: "Value from placeholder attribute." + }, + "relatedElement": { + name: "Related element", + description: "Value from related element." + } +} + +WebInspector.AccessibilityStrings.AXNativeSourceTypes = { + "figcaption": { + name: "From caption", + description: "Value from figcaption element." + }, + "label": { + name: "From label", + description: "Value from label element." + }, + "labelfor": { + name: "From label (for)", + description: "Value from label element with for= attribute." + }, + "labelwrapped": { + name: "From label (wrapped)", + description: "Value from label element wrapped." + }, + "tablecaption": { + name: "From caption", + description: "Value from table caption." + }, + "other": { + name: "From native HTML", + description: "Value from native HTML (unknown source)." + }, + +}
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/accessibilityNode.css b/third_party/WebKit/Source/devtools/front_end/accessibility/accessibilityNode.css index f6511690..e249233 100644 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/accessibilityNode.css +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/accessibilityNode.css
@@ -38,6 +38,10 @@ flex-shrink: 0; } +.ax-readable-string { + font-style: italic; +} + span.ax-role { font-weight: bold; } @@ -57,3 +61,31 @@ .tree-outline li { padding-top: 5px; } + +.tree-outline li.invalid { + position: relative; + left: -2px; + text-decoration: line-through; +} + +.tree-outline label[is=dt-icon-label] { + position: relative; + left: -11px; +} + +span.ax-value-undefined { + font-style: italic; +} + +.ax-value-source-unused { + opacity: 0.5; +} + +.ax-value-source-superseded, +.ax-value-source-invalid { + text-decoration: line-through; +} + +.tree-outline label[is=dt-icon-label] + .ax-name { + margin-left: -11px; +}
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js index ea25a42..e9beaa2b 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
@@ -298,6 +298,8 @@ wasShown: function() { + WebInspector.context.setFlavor(WebInspector.ElementsPanel, this); + for (var i = 0; i < this._treeOutlines.length; ++i) { var treeOutline = this._treeOutlines[i]; // Attach heavy component lazily @@ -323,6 +325,8 @@ willHide: function() { + WebInspector.context.setFlavor(WebInspector.ElementsPanel, null); + WebInspector.DOMModel.hideDOMNodeHighlight(); for (var i = 0; i < this._treeOutlines.length; ++i) { var treeOutline = this._treeOutlines[i];
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/Spectrum.js b/third_party/WebKit/Source/devtools/front_end/elements/Spectrum.js index 67ed818f..12b5e94a 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/Spectrum.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/Spectrum.js
@@ -110,6 +110,7 @@ this._palettePanelShowing = false; this._paletteContainer = this.contentElement.createChild("div", "spectrum-palette"); this._paletteContainer.addEventListener("contextmenu", this._showPaletteColorContextMenu.bind(this, -1)); + this._shadesContainer = this.contentElement.createChild("div", "palette-color-shades hidden"); WebInspector.installDragHandle(this._paletteContainer, this._paletteDragStart.bind(this), this._paletteDrag.bind(this), this._paletteDragEnd.bind(this), "default"); var paletteSwitcher = this.contentElement.createChild("div", "spectrum-palette-switcher spectrum-switcher"); appendSwitcherIcon(paletteSwitcher); @@ -259,6 +260,15 @@ colorElement.__mutable = true; colorElement.__color = palette.colors[i]; colorElement.addEventListener("contextmenu", this._showPaletteColorContextMenu.bind(this, i)); + } else if (palette === WebInspector.Spectrum.MaterialPalette) { + colorElement.classList.add("has-material-shades"); + var shadow = colorElement.createChild("div", "spectrum-palette-color spectrum-palette-color-shadow"); + shadow.style.background = palette.colors[i]; + shadow = colorElement.createChild("div", "spectrum-palette-color spectrum-palette-color-shadow"); + shadow.style.background = palette.colors[i]; + var controller = new WebInspector.LongClickController(colorElement); + controller.enable(); + controller.addEventListener(WebInspector.LongClickController.Events.LongClick, this._showLightnessShades.bind(this, colorElement, palette.colors[i])); } this._paletteContainer.appendChild(colorElement); } @@ -279,6 +289,48 @@ }, /** + * @param {!Element} colorElement + * @param {string} colorText + * @param {!WebInspector.Event} event + */ + _showLightnessShades: function(colorElement, colorText, event) + { + /** + * @param {!Element} element + * @this {!WebInspector.Spectrum} + */ + function closeLightnessShades(element) + { + this._shadesContainer.classList.add("hidden"); + element.classList.remove("spectrum-shades-shown"); + this._shadesContainer.ownerDocument.removeEventListener("mousedown", this._shadesCloseHandler, true); + delete this._shadesCloseHandler; + } + + if (this._shadesCloseHandler) + this._shadesCloseHandler(); + + this._shadesContainer.classList.remove("hidden"); + this._shadesContainer.removeChildren(); + this._shadesContainer.animate([{ transform: "scaleY(0)", opacity: "0" }, { transform: "scaleY(1)", opacity: "1" }], { duration: 200, easing: "cubic-bezier(0.4, 0, 0.2, 1)" }); + var anchorBox = colorElement.boxInWindow(); + this._shadesContainer.style.top = colorElement.offsetTop + "px"; + this._shadesContainer.style.left = colorElement.offsetLeft + "px"; + colorElement.classList.add("spectrum-shades-shown"); + + var shades = WebInspector.Spectrum.MaterialPaletteShades[colorText]; + for (var i = shades.length - 1; i >= 0; i--) { + var shadeElement = this._createPaletteColor(shades[i], i * 200 / shades.length + 100); + shadeElement.addEventListener("mousedown", this._paletteColorSelected.bind(this, shades[i], false)); + this._shadesContainer.appendChild(shadeElement); + } + + WebInspector.setCurrentFocusElement(this._shadesContainer); + this._shadesCloseHandler = closeLightnessShades.bind(this, colorElement); + this._shadesContainer.ownerDocument.addEventListener("mousedown", this._shadesCloseHandler, true); + }, + + /** * @param {!Event} e * @return {number} */ @@ -949,24 +1001,26 @@ } } -WebInspector.Spectrum.MaterialPalette = { title: "Material", mutable: false, matchUserFormat: true, colors: [ - "#F44336", - "#E91E63", - "#9C27B0", - "#673AB7", - "#3F51B5", - "#2196F3", - "#03A9F4", - "#00BCD4", - "#009688", - "#4CAF50", - "#8BC34A", - "#CDDC39", - "#FFEB3B", - "#FFC107", - "#FF9800", - "#FF5722", - "#795548", - "#9E9E9E", - "#607D8B" -]}; \ No newline at end of file +WebInspector.Spectrum.MaterialPaletteShades = { + "#F44336": ["#FFEBEE", "#FFCDD2", "#EF9A9A", "#E57373", "#EF5350", "#F44336", "#E53935", "#D32F2F", "#C62828", "#B71C1C"], + "#E91E63": ["#FCE4EC", "#F8BBD0", "#F48FB1", "#F06292", "#EC407A", "#E91E63", "#D81B60", "#C2185B", "#AD1457", "#880E4F"], + "#9C27B0": ["#F3E5F5", "#E1BEE7", "#CE93D8", "#BA68C8", "#AB47BC", "#9C27B0", "#8E24AA", "#7B1FA2", "#6A1B9A", "#4A148C"], + "#673AB7": ["#EDE7F6", "#D1C4E9", "#B39DDB", "#9575CD", "#7E57C2", "#673AB7", "#5E35B1", "#512DA8", "#4527A0", "#311B92"], + "#3F51B5": ["#E8EAF6", "#C5CAE9", "#9FA8DA", "#7986CB", "#5C6BC0", "#3F51B5", "#3949AB", "#303F9F", "#283593", "#1A237E"], + "#2196F3": ["#E3F2FD", "#BBDEFB", "#90CAF9", "#64B5F6", "#42A5F5", "#2196F3", "#1E88E5", "#1976D2", "#1565C0", "#0D47A1"], + "#03A9F4": ["#E1F5FE", "#B3E5FC", "#81D4FA", "#4FC3F7", "#29B6F6", "#03A9F4", "#039BE5", "#0288D1", "#0277BD", "#01579B"], + "#00BCD4": ["#E0F7FA", "#B2EBF2", "#80DEEA", "#4DD0E1", "#26C6DA", "#00BCD4", "#00ACC1", "#0097A7", "#00838F", "#006064"], + "#009688": ["#E0F2F1", "#B2DFDB", "#80CBC4", "#4DB6AC", "#26A69A", "#009688", "#00897B", "#00796B", "#00695C", "#004D40"], + "#4CAF50": ["#E8F5E9", "#C8E6C9", "#A5D6A7", "#81C784", "#66BB6A", "#4CAF50", "#43A047", "#388E3C", "#2E7D32", "#1B5E20"], + "#8BC34A": ["#F1F8E9", "#DCEDC8", "#C5E1A5", "#AED581", "#9CCC65", "#8BC34A", "#7CB342", "#689F38", "#558B2F", "#33691E"], + "#CDDC39": ["#F9FBE7", "#F0F4C3", "#E6EE9C", "#DCE775", "#D4E157", "#CDDC39", "#C0CA33", "#AFB42B", "#9E9D24", "#827717"], + "#FFEB3B": ["#FFFDE7", "#FFF9C4", "#FFF59D", "#FFF176", "#FFEE58", "#FFEB3B", "#FDD835", "#FBC02D", "#F9A825", "#F57F17"], + "#FFC107": ["#FFF8E1", "#FFECB3", "#FFE082", "#FFD54F", "#FFCA28", "#FFC107", "#FFB300", "#FFA000", "#FF8F00", "#FF6F00"], + "#FF9800": ["#FFF3E0", "#FFE0B2", "#FFCC80", "#FFB74D", "#FFA726", "#FF9800", "#FB8C00", "#F57C00", "#EF6C00", "#E65100"], + "#FF5722": ["#FBE9E7", "#FFCCBC", "#FFAB91", "#FF8A65", "#FF7043", "#FF5722", "#F4511E", "#E64A19", "#D84315", "#BF360C"], + "#795548": ["#EFEBE9", "#D7CCC8", "#BCAAA4", "#A1887F", "#8D6E63", "#795548", "#6D4C41", "#5D4037", "#4E342E", "#3E2723"], + "#9E9E9E": ["#FAFAFA", "#F5F5F5", "#EEEEEE", "#E0E0E0", "#BDBDBD", "#9E9E9E", "#757575", "#616161", "#424242", "#212121"], + "#607D8B": ["#ECEFF1", "#CFD8DC", "#B0BEC5", "#90A4AE", "#78909C", "#607D8B", "#546E7A", "#455A64", "#37474F", "#263238"] +}; + +WebInspector.Spectrum.MaterialPalette = { title: "Material", mutable: false, matchUserFormat: true, colors: Object.keys(WebInspector.Spectrum.MaterialPaletteShades) }; \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/module.json b/third_party/WebKit/Source/devtools/front_end/elements/module.json index 8a2fbd1..04fa293 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/module.json +++ b/third_party/WebKit/Source/devtools/front_end/elements/module.json
@@ -69,6 +69,7 @@ { "type": "@WebInspector.ActionDelegate", "actionId": "elements.hide-element", + "contextTypes": ["WebInspector.ElementsPanel"], "className": "WebInspector.ElementsActionDelegate", "bindings": [ { @@ -79,6 +80,7 @@ { "type": "@WebInspector.ActionDelegate", "actionId": "elements.edit-as-html", + "contextTypes": ["WebInspector.ElementsPanel"], "className": "WebInspector.ElementsActionDelegate", "bindings": [ {
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/spectrum.css b/third_party/WebKit/Source/devtools/front_end/elements/spectrum.css index 0f16172..7fde4b3 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/spectrum.css +++ b/third_party/WebKit/Source/devtools/front_end/elements/spectrum.css
@@ -203,6 +203,48 @@ border-radius: 2px; margin: 6px; cursor: pointer; + position: relative; +} + +.spectrum-palette-color:hover:not(.spectrum-shades-shown) > .spectrum-palette-color-shadow { + opacity: 0.2; +} + +.spectrum-palette-color:hover:not(.spectrum-shades-shown) > .spectrum-palette-color-shadow:first-child { + opacity: 0.6; + top: -3px; + left: 1px; +} + +.spectrum-palette-color-shadow { + position: absolute; + opacity: 0; + margin: 0; + top: -5px; + left: 3px; +} + +.palette-color-shades { + position: absolute; + background-color: white; + height: 237px; + width: 28px; + box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.4); + z-index: 14; + border-radius: 2px; + transform-origin: 0px 237px; + margin-top: 18px; + margin-left: -8px; +} + +.spectrum-palette > .spectrum-palette-color.spectrum-shades-shown { + z-index: 15; +} + +.palette-color-shades > .spectrum-palette-color { + margin: 8px 0 0 0; + margin-left: 8px; + width: 12px; } .spectrum-palette > .spectrum-palette-color { @@ -216,7 +258,8 @@ border-color: transparent; } -.spectrum-palette > .spectrum-palette-color:not(.empty-color):hover { +.spectrum-palette > .spectrum-palette-color:not(.empty-color):not(.has-material-shades):hover, +.palette-color-shades > .spectrum-palette-color:not(.empty-color):hover { transform: scale(1.15); }
diff --git a/third_party/WebKit/Source/devtools/front_end/main/FrontendWebSocketAPI.js b/third_party/WebKit/Source/devtools/front_end/main/FrontendWebSocketAPI.js index bbe8c1c..6c7e5c00 100644 --- a/third_party/WebKit/Source/devtools/front_end/main/FrontendWebSocketAPI.js +++ b/third_party/WebKit/Source/devtools/front_end/main/FrontendWebSocketAPI.js
@@ -11,6 +11,8 @@ InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.DispatchFrontendAPIMessage, this._onFrontendAPIMessage, this); InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.FrontendAPIAttached, this._onAttach, this); InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.FrontendAPIDetached, this._onDetach, this); + /** @type {!Set<string>} */ + this._suggestedFolders = new Set(); } WebInspector.FrontendWebSocketAPI.prototype = { @@ -76,11 +78,22 @@ if (saved) uiSourceCode.checkContentUpdated(); } - this._issueResponse(id); + break; + case "Frontend.addFileSystem": + for (var path of params["paths"]) { + var fileSystem = WebInspector.isolatedFileSystemManager.fileSystem(path); + if (fileSystem) + continue; + if (this._suggestedFolders.has(path)) + continue; + this._suggestedFolders.add(path); + WebInspector.isolatedFileSystemManager.addFileSystem(path); + } break; default: WebInspector.console.log("Unhandled API message: " + method); } + this._issueResponse(id); this._dispatchingFrontendMessage = false; },
diff --git a/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js b/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js index e6b9467..6f3a47a 100644 --- a/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js +++ b/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js
@@ -470,7 +470,7 @@ _addFileSystemClicked: function() { - WebInspector.isolatedFileSystemManager.addFileSystem(); + WebInspector.isolatedFileSystemManager.addFileSystem(""); }, _fileSystemAdded: function(event)
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js b/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js index 67ab24d..cf00c39 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js
@@ -88,7 +88,7 @@ { function addFolder() { - WebInspector.isolatedFileSystemManager.addFileSystem(); + WebInspector.isolatedFileSystemManager.addFileSystem(""); } var addFolderLabel = WebInspector.UIString.capitalize("Add ^folder to ^workspace");
diff --git a/third_party/WebKit/Source/devtools/front_end/workspace/IsolatedFileSystemManager.js b/third_party/WebKit/Source/devtools/front_end/workspace/IsolatedFileSystemManager.js index 78030c6e..f26ac30 100644 --- a/third_party/WebKit/Source/devtools/front_end/workspace/IsolatedFileSystemManager.js +++ b/third_party/WebKit/Source/devtools/front_end/workspace/IsolatedFileSystemManager.js
@@ -65,9 +65,12 @@ InspectorFrontendHost.requestFileSystems(); }, - addFileSystem: function() + /** + * @param {string} fileSystemPath + */ + addFileSystem: function(fileSystemPath) { - InspectorFrontendHost.addFileSystem(""); + InspectorFrontendHost.addFileSystem(fileSystemPath); }, /**
diff --git a/third_party/WebKit/Source/devtools/protocol.json b/third_party/WebKit/Source/devtools/protocol.json index f106c857..0c32c620 100644 --- a/third_party/WebKit/Source/devtools/protocol.json +++ b/third_party/WebKit/Source/devtools/protocol.json
@@ -5186,23 +5186,29 @@ { "id": "AXValueType", "type": "string", - "enum": [ "boolean", "tristate", "booleanOrUndefined", "idref", "idrefList", "integer", "number", "string", "token", "tokenList", "domRelation", "role", "internalRole" ], + "enum": [ "boolean", "tristate", "booleanOrUndefined", "idref", "idrefList", "integer", "node", "nodeList", "number", "string", "computedString", "token", "tokenList", "domRelation", "role", "internalRole", "valueUndefined" ], "description": "Enum of possible property types." }, { - "id": "AXPropertySourceType", + "id": "AXValueSourceType", "type": "string", - "enum": [ "attribute", "implicit", "style" ], + "enum": [ "attribute", "implicit", "style", "contents", "placeholder", "relatedElement" ], "description": "Enum of possible property sources." }, + { "id": "AXValueNativeSourceType", + "type": "string", + "enum": [ "figcaption", "label", "labelfor", "labelwrapped", "tablecaption", "other" ], + "description": "Enum of possible native property sources (as a subtype of a particular AXValueSourceType)." + }, { - "id": "AXPropertySource", + "id": "AXValueSource", "type": "object", "properties": [ - { "name": "name", "type": "string", "description": "The name/label of this source." }, - { "name": "sourceType", "$ref": "AXPropertySourceType", "description": "What type of source this is." }, - { "name": "value", "type": "any", "description": "The value of this property source." }, - { "name": "type", "$ref": "AXValueType", "description": "What type the value should be interpreted as." }, + { "name": "type", "$ref": "AXValueSourceType", "description": "What type of source this is." }, + { "name": "value", "$ref": "AXValue", "description": "The value of this property source.", "optional": true }, + { "name": "attribute", "type": "string", "description": "The attribute, if any.", "optional": true }, + { "name": "superseded", "type": "boolean", "description": "Whether this source is superseded by a higher priority source.", "optional": true }, + { "name": "nativeSource", "$ref": "AXValueNativeSourceType", "description": "The native markup source for this value, e.g. a <label> element.", "optional": true }, { "name": "invalid", "type": "boolean", "description": "Whether the value for this property is invalid.", "optional": true }, { "name": "invalidReason", "type": "string", "description": "Reason for the value being invalid, if it is.", "optional": true } ], @@ -5212,8 +5218,9 @@ "id": "AXRelatedNode", "type": "object", "properties": [ + { "name": "backendNodeId", "$ref": "DOM.BackendNodeId", "description": "The BackendNodeId of the related node." }, { "name": "idref", "type": "string", "description": "The IDRef value provided, if any.", "optional": true }, - { "name": "backendNodeId", "$ref": "DOM.BackendNodeId", "description": "The BackendNodeId of the related node." } + { "name": "text", "type": "string", "description": "The text alternative of this node in the current context.", "optional": true } ] }, { @@ -5233,7 +5240,7 @@ { "name": "value", "type": "any", "description": "The computed value of this property.", "optional": true }, { "name": "relatedNodeValue", "$ref": "AXRelatedNode", "description": "The related node value, if any.", "optional": true }, { "name": "relatedNodeArrayValue", "type": "array", "items": { "$ref": "AXRelatedNode" }, "description": "Multiple relted nodes, if applicable.", "optional": true }, - { "name": "sources", "type": "array", "items": { "$ref": "AXPropertySource" }, "description": "The sources which contributed to the computation of this property.", "optional": true } + { "name": "sources", "type": "array", "items": { "$ref": "AXValueSource" }, "description": "The sources which contributed to the computation of this property.", "optional": true } ], "description": "A single computed AX property." },
diff --git a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp index 9c0d892..2db9efc 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
@@ -578,7 +578,7 @@ } } -void AXNodeObject::accessibilityChildrenFromAttribute(QualifiedName attr, AccessibilityChildrenVector& children) const +void AXNodeObject::accessibilityChildrenFromAttribute(QualifiedName attr, AXObject::AccessibilityChildrenVector& children) const { WillBeHeapVector<RawPtrWillBeMember<Element>> elements; elementsFromAttribute(elements, attr); @@ -1843,11 +1843,11 @@ // New AX name calculation. // -String AXNodeObject::textAlternative(bool recursive, bool inAriaLabelledByTraversal, AXObjectSet& visited, AXNameFrom& nameFrom, AXObjectVector* nameObjects, NameSources* nameSources) const +String AXNodeObject::textAlternative(bool recursive, bool inAriaLabelledByTraversal, AXObjectSet& visited, AXNameFrom& nameFrom, AXRelatedObjectVector* relatedObjects, NameSources* nameSources) const { - // If nameSources is non-null, nameObjects is used in filling it in, so it must be non-null as well. + // If nameSources is non-null, relatedObjects is used in filling it in, so it must be non-null as well. if (nameSources) - ASSERT(nameObjects); + ASSERT(relatedObjects); bool alreadyVisited = visited.contains(this); bool foundTextAlternative = false; @@ -1878,13 +1878,13 @@ if (nameSources) nameSources->last().attributeValue = ariaLabelledby; - textAlternative = textFromAriaLabelledby(visited, nameObjects); + textAlternative = textFromAriaLabelledby(visited, relatedObjects); if (!textAlternative.isNull()) { if (nameSources) { NameSource& source = nameSources->last(); source.type = nameFrom; - source.nameObjects = *nameObjects; + source.relatedObjects = *relatedObjects; source.text = textAlternative; foundTextAlternative = true; } else { @@ -1917,7 +1917,7 @@ } // Step 2D from: http://www.w3.org/TR/accname-aam-1.1 - textAlternative = nativeTextAlternative(visited, nameFrom, nameObjects, nameSources, &foundTextAlternative); + textAlternative = nativeTextAlternative(visited, nameFrom, relatedObjects, nameSources, &foundTextAlternative); if (!textAlternative.isNull() && !nameSources) return textAlternative; @@ -1982,8 +1982,8 @@ if (!(*nameSources)[i].text.isNull() && !(*nameSources)[i].superseded) { NameSource& nameSource = (*nameSources)[i]; nameFrom = nameSource.type; - if (!nameSource.nameObjects.isEmpty()) - *nameObjects = nameSource.nameObjects; + if (!nameSource.relatedObjects.isEmpty()) + *relatedObjects = nameSource.relatedObjects; return nameSource.text; } } @@ -2015,19 +2015,19 @@ return accumulatedText.toString(); } -String AXNodeObject::textFromElements(bool inAriaLabelledbyTraversal, AXObjectSet& visited, WillBeHeapVector<RawPtrWillBeMember<Element>>& elements, AXObjectVector* nameObjects) const +String AXNodeObject::textFromElements(bool inAriaLabelledbyTraversal, AXObjectSet& visited, WillBeHeapVector<RawPtrWillBeMember<Element>>& elements, AXRelatedObjectVector* relatedObjects) const { StringBuilder accumulatedText; bool foundValidElement = false; - AXObjectVector localNameObjects; + AXRelatedObjectVector localRelatedObjects; for (const auto& element : elements) { AXObject* axElement = axObjectCache().getOrCreate(element); if (axElement) { foundValidElement = true; - localNameObjects.append(axElement); String result = recursiveTextAlternative(*axElement, inAriaLabelledbyTraversal, visited); + localRelatedObjects.append(new NameSourceRelatedObject(axElement, result)); if (!result.isEmpty()) { if (!accumulatedText.isEmpty()) accumulatedText.append(" "); @@ -2037,16 +2037,16 @@ } if (!foundValidElement) return String(); - if (nameObjects) - *nameObjects = localNameObjects; + if (relatedObjects) + *relatedObjects = localRelatedObjects; return accumulatedText.toString(); } -String AXNodeObject::textFromAriaLabelledby(AXObjectSet& visited, AXObjectVector* nameObjects) const +String AXNodeObject::textFromAriaLabelledby(AXObjectSet& visited, AXRelatedObjectVector* relatedObjects) const { WillBeHeapVector<RawPtrWillBeMember<Element>> elements; ariaLabelledbyElements(elements); - return textFromElements(true, visited, elements, nameObjects); + return textFromElements(true, visited, elements, relatedObjects); } LayoutRect AXNodeObject::elementRect() const @@ -2551,17 +2551,17 @@ } // Based on http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-name-and-description-calculation -String AXNodeObject::nativeTextAlternative(AXObjectSet& visited, AXNameFrom& nameFrom, AXObjectVector* nameObjects, NameSources* nameSources, bool* foundTextAlternative) const +String AXNodeObject::nativeTextAlternative(AXObjectSet& visited, AXNameFrom& nameFrom, AXRelatedObjectVector* relatedObjects, NameSources* nameSources, bool* foundTextAlternative) const { if (!node()) return String(); - // If nameSources is non-null, nameObjects is used in filling it in, so it must be non-null as well. + // If nameSources is non-null, relatedObjects is used in filling it in, so it must be non-null as well. if (nameSources) - ASSERT(nameObjects); + ASSERT(relatedObjects); String textAlternative; - AXObjectVector localNameObjects; + AXRelatedObjectVector localRelatedObjects; const HTMLInputElement* inputElement = nullptr; if (isHTMLInputElement(node())) @@ -2584,16 +2584,17 @@ AXObject* labelAXObject = axObjectCache().getOrCreate(label); // Avoid an infinite loop for label wrapped if (labelAXObject && !visited.contains(labelAXObject)) { - if (nameObjects) { - localNameObjects.append(labelAXObject); - *nameObjects = localNameObjects; - localNameObjects.clear(); - } textAlternative = recursiveTextAlternative(*labelAXObject, false, visited); + if (relatedObjects) { + localRelatedObjects.append(new NameSourceRelatedObject(labelAXObject, textAlternative)); + *relatedObjects = localRelatedObjects; + localRelatedObjects.clear(); + } + if (nameSources) { NameSource& source = nameSources->last(); - source.nameObjects = *nameObjects; + source.relatedObjects = *relatedObjects; source.text = textAlternative; if (label->getAttribute(forAttr).isNull()) source.nativeSource = AXTextFromNativeHTMLLabelWrapped; @@ -2726,18 +2727,19 @@ if (figcaption) { AXObject* figcaptionAXObject = axObjectCache().getOrCreate(figcaption); if (figcaptionAXObject) { - if (nameObjects) { - localNameObjects.append(figcaptionAXObject); - *nameObjects = localNameObjects; - localNameObjects.clear(); - } - textAlternative = recursiveTextAlternative(*figcaptionAXObject, false, visited); + if (relatedObjects) { + localRelatedObjects.append(new NameSourceRelatedObject(figcaptionAXObject, textAlternative)); + *relatedObjects = localRelatedObjects; + localRelatedObjects.clear(); + } + if (nameSources) { NameSource& source = nameSources->last(); - source.nameObjects = *nameObjects; + source.relatedObjects = *relatedObjects; source.text = textAlternative; + *foundTextAlternative = true; } else { return textAlternative; } @@ -2784,17 +2786,18 @@ if (caption) { AXObject* captionAXObject = axObjectCache().getOrCreate(caption); if (captionAXObject) { - if (nameObjects) { - localNameObjects.append(captionAXObject); - *nameObjects = localNameObjects; - localNameObjects.clear(); + textAlternative = recursiveTextAlternative(*captionAXObject, false, visited); + if (relatedObjects) { + localRelatedObjects.append(new NameSourceRelatedObject(captionAXObject, textAlternative)); + *relatedObjects = localRelatedObjects; + localRelatedObjects.clear(); } - textAlternative = recursiveTextAlternative(*captionAXObject, false, visited); if (nameSources) { NameSource& source = nameSources->last(); - source.nameObjects = *nameObjects; + source.relatedObjects = *relatedObjects; source.text = textAlternative; + *foundTextAlternative = true; } else { return textAlternative; } @@ -2804,7 +2807,7 @@ // summary nameFrom = AXNameFromAttribute; if (nameSources) { - nameSources->append(NameSource(*foundTextAlternative)); + nameSources->append(NameSource(*foundTextAlternative, summaryAttr)); nameSources->last().type = nameFrom; } const AtomicString& summary = getAttribute(summaryAttr);
diff --git a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.h b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.h index 79c0765c7..b4614f3 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.h +++ b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.h
@@ -70,7 +70,7 @@ AccessibilityRole determineAriaRoleAttribute() const; void tokenVectorFromAttribute(Vector<String>&, const QualifiedName&) const; void elementsFromAttribute(WillBeHeapVector<RawPtrWillBeMember<Element>>& elements, const QualifiedName&) const; - void accessibilityChildrenFromAttribute(QualifiedName attr, AccessibilityChildrenVector&) const; + void accessibilityChildrenFromAttribute(QualifiedName attr, AXObject::AccessibilityChildrenVector&) const; bool hasContentEditableAttributeSet() const; bool isTextControl() const override; @@ -171,7 +171,7 @@ String computedName() const override; // New AX name calculation. - String textAlternative(bool recursive, bool inAriaLabelledByTraversal, AXObjectSet& visited, AXNameFrom&, AXObjectVector* nameObjects, NameSources*) const override; + String textAlternative(bool recursive, bool inAriaLabelledByTraversal, AXObjectSet& visited, AXNameFrom&, AXRelatedObjectVector*, NameSources*) const override; // Location and click point in frame-relative coordinates. LayoutRect elementRect() const override; @@ -220,9 +220,9 @@ void deprecatedAriaLabelledbyText(HeapVector<Member<AccessibilityText>>&) const; String textFromDescendants(AXObjectSet& visited) const; - String textFromElements(bool inAriaLabelledByTraversal, AXObjectSet& visited, WillBeHeapVector<RawPtrWillBeMember<Element>>& elements, AXObjectVector* nameObjects) const; - String textFromAriaLabelledby(AXObjectSet& visited, AXObjectVector* nameObjects) const; - String nativeTextAlternative(AXObjectSet& visited, AXNameFrom&, AXObjectVector* nameObjects, NameSources*, bool* foundTextAlternative) const; + String textFromElements(bool inAriaLabelledByTraversal, AXObjectSet& visited, WillBeHeapVector<RawPtrWillBeMember<Element>>& elements, AXRelatedObjectVector* relatedObjects) const; + String textFromAriaLabelledby(AXObjectSet& visited, AXRelatedObjectVector* relatedObjects) const; + String nativeTextAlternative(AXObjectSet& visited, AXNameFrom&, AXRelatedObjectVector*, NameSources*, bool* foundTextAlternative) const; float stepValueForRange() const; AXObject* findChildWithTagName(const HTMLQualifiedName&) const; bool isDescendantOfElementType(const HTMLQualifiedName& tagName) const;
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXObject.cpp index 98e2ce4..c6b9701 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXObject.cpp
@@ -673,18 +673,23 @@ return m_cachedIsPresentationalChild; } -String AXObject::name(AXNameFrom& nameFrom, AXObjectVector* nameObjects) const +String AXObject::name(AXNameFrom& nameFrom, AXObject::AccessibilityChildrenVector* nameObjects) const { HeapHashSet<Member<const AXObject>> visited; - return textAlternative(false, false, visited, nameFrom, nameObjects, nullptr); + AXRelatedObjectVector relatedObjects; + String text = textAlternative(false, false, visited, nameFrom, &relatedObjects, nullptr); + nameObjects->clear(); + for (size_t i = 0; i < relatedObjects.size(); i++) + nameObjects->append(relatedObjects[i]->object); + return text; } String AXObject::name(NameSources* nameSources) const { AXObjectSet visited; AXNameFrom tmpNameFrom; - AXObjectVector tmpNameObjects; - return textAlternative(false, false, visited, tmpNameFrom, &tmpNameObjects, nameSources); + AXRelatedObjectVector tmpRelatedObjects; + return textAlternative(false, false, visited, tmpNameFrom, &tmpRelatedObjects, nameSources); } String AXObject::recursiveTextAlternative(const AXObject& axObj, bool inAriaLabelledByTraversal, AXObjectSet& visited)
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObject.h b/third_party/WebKit/Source/modules/accessibility/AXObject.h index 28138ed..edcf525 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObject.h +++ b/third_party/WebKit/Source/modules/accessibility/AXObject.h
@@ -385,7 +385,24 @@ } }; -typedef HeapVector<Member<AXObject>> AXObjectVector; +class NameSourceRelatedObject : public GarbageCollectedFinalized<NameSourceRelatedObject> { +public: + WeakMember<AXObject> object; + String text; + + NameSourceRelatedObject(AXObject* object, String text) + : object(object) + , text(text) + { + } + + DEFINE_INLINE_TRACE() + { + visitor->trace(object); + } +}; + +typedef HeapVector<Member<NameSourceRelatedObject>> AXRelatedObjectVector; class NameSource { ALLOW_ONLY_INLINE_ALLOCATION(); public: @@ -396,9 +413,9 @@ const QualifiedName& attribute; AtomicString attributeValue; AXTextFromNativeHTML nativeSource = AXTextFromNativeHTMLUninitialized; - AXObjectVector nameObjects; + AXRelatedObjectVector relatedObjects; - explicit NameSource(bool superseded, const QualifiedName& attr) + NameSource(bool superseded, const QualifiedName& attr) : superseded(superseded) , attribute(attr) { @@ -412,7 +429,7 @@ DEFINE_INLINE_TRACE() { - visitor->trace(nameObjects); + visitor->trace(relatedObjects); } }; @@ -634,7 +651,7 @@ // Retrieves the accessible name of the object, an enum indicating where the name // was derived from, and a list of objects that were used to derive the name, if any. - virtual String name(AXNameFrom&, AXObjectVector* nameObjects) const; + virtual String name(AXNameFrom&, AccessibilityChildrenVector* nameObjects) const; typedef HeapVector<NameSource> NameSources; // Retrieves the accessible name of the object and a list of all potential sources @@ -645,7 +662,7 @@ // accessible description of the object, which is secondary to |name|, an enum indicating // where the description was derived from, and a list of objects that were used to // derive the description, if any. - virtual String description(AXNameFrom, AXDescriptionFrom&, AXObjectVector* descriptionObjects) { return String(); } + virtual String description(AXNameFrom, AXDescriptionFrom&, AccessibilityChildrenVector* descriptionObjects) { return String(); } // Takes the result of nameFrom and descriptionFrom from calling |name| and |description|, // above, and retrieves the placeholder of the object, if present and if it wasn't already @@ -654,7 +671,7 @@ // Internal function used by name and description, above. typedef HeapHashSet<Member<const AXObject>> AXObjectSet; - virtual String textAlternative(bool recursive, bool inAriaLabelledByTraversal, AXObjectSet& visited, AXNameFrom& nameFrom, AXObjectVector* nameObjects, NameSources* nameSources) const { return String(); } + virtual String textAlternative(bool recursive, bool inAriaLabelledByTraversal, AXObjectSet& visited, AXNameFrom& nameFrom, AXRelatedObjectVector* relatedObjects, NameSources* nameSources) const { return String(); } // Returns result of Accessible Name Calculation algorithm. // This is a simpler high-level interface to |name| used by Inspector.
diff --git a/third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp b/third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp index e33ccf2..dcc789c 100644 --- a/third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp +++ b/third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp
@@ -6,6 +6,7 @@ #include "modules/accessibility/InspectorAccessibilityAgent.h" +#include "core/HTMLNames.h" #include "core/dom/AXObjectCache.h" #include "core/dom/DOMNodeIds.h" #include "core/dom/Element.h" @@ -25,6 +26,7 @@ using TypeBuilder::Accessibility::AXNode; using TypeBuilder::Accessibility::AXNodeId; using TypeBuilder::Accessibility::AXProperty; +using TypeBuilder::Accessibility::AXValueSource; using TypeBuilder::Accessibility::AXValueType; using TypeBuilder::Accessibility::AXRelatedNode; using TypeBuilder::Accessibility::AXRelationshipAttributes; @@ -32,6 +34,8 @@ using TypeBuilder::Accessibility::AXWidgetAttributes; using TypeBuilder::Accessibility::AXWidgetStates; +using namespace HTMLNames; + namespace { void fillCoreProperties(AXObject* axObject, PassRefPtr<AXNode> nodeObject) @@ -39,7 +43,7 @@ // core properties String description = axObject->deprecatedAccessibilityDescription(); if (!description.isEmpty()) - nodeObject->setDescription(createValue(description)); + nodeObject->setDescription(createValue(description, AXValueType::ComputedString)); if (axObject->supportsRangeValue()) { nodeObject->setValue(createValue(axObject->valueForRange())); @@ -51,7 +55,7 @@ String help = axObject->deprecatedHelpText(); if (!help.isEmpty()) - nodeObject->setHelp(createValue(help)); + nodeObject->setHelp(createValue(help, AXValueType::ComputedString)); } void fillLiveRegionProperties(AXObject* axObject, PassRefPtr<TypeBuilder::Array<AXProperty>> properties) @@ -243,6 +247,14 @@ } } +PassRefPtr<AXProperty> createRelatedNodeListProperty(AXRelationshipAttributes::Enum key, AXObject::AccessibilityChildrenVector& nodes, const QualifiedName& attr, AXObject* axObject) +{ + RefPtr<AXValue> nodeListValue = createRelatedNodeListValue(nodes); + const AtomicString& attrValue = axObject->getAttribute(attr); + nodeListValue->setValue(JSONString::create(attrValue)); + return createProperty(key, nodeListValue); +} + void fillRelationships(AXObject* axObject, PassRefPtr<TypeBuilder::Array<AXProperty>> properties) { if (AXObject* activeDescendant = axObject->activeDescendant()) { @@ -252,27 +264,27 @@ AXObject::AccessibilityChildrenVector results; axObject->ariaFlowToElements(results); if (!results.isEmpty()) - properties->addItem(createProperty(AXRelationshipAttributes::Flowto, createRelatedNodeListValue(results))); + properties->addItem(createRelatedNodeListProperty(AXRelationshipAttributes::Flowto, results, aria_flowtoAttr, axObject)); results.clear(); axObject->ariaControlsElements(results); if (!results.isEmpty()) - properties->addItem(createProperty(AXRelationshipAttributes::Controls, createRelatedNodeListValue(results))); + properties->addItem(createRelatedNodeListProperty(AXRelationshipAttributes::Controls, results, aria_controlsAttr, axObject)); results.clear(); axObject->deprecatedAriaDescribedbyElements(results); if (!results.isEmpty()) - properties->addItem(createProperty(AXRelationshipAttributes::Describedby, createRelatedNodeListValue(results))); + properties->addItem(createRelatedNodeListProperty(AXRelationshipAttributes::Describedby, results, aria_describedbyAttr, axObject)); results.clear(); axObject->deprecatedAriaLabelledbyElements(results); if (!results.isEmpty()) - properties->addItem(createProperty(AXRelationshipAttributes::Labelledby, createRelatedNodeListValue(results))); + properties->addItem(createRelatedNodeListProperty(AXRelationshipAttributes::Labelledby, results, aria_labelledbyAttr, axObject)); results.clear(); axObject->ariaOwnsElements(results); if (!results.isEmpty()) - properties->addItem(createProperty(AXRelationshipAttributes::Owns, createRelatedNodeListValue(results))); + properties->addItem(createRelatedNodeListProperty(AXRelationshipAttributes::Owns, results, aria_ownsAttr, axObject)); results.clear(); } @@ -317,9 +329,19 @@ RefPtr<AXNode> nodeObject = AXNode::create().setNodeId(String::number(axObject->axObjectID())).setIgnored(false); nodeObject->setRole(createRoleNameValue(role)); nodeObject->setProperties(properties); - String computedName = cacheImpl->computedNameForNode(node); - if (!computedName.isEmpty()) - nodeObject->setName(createValue(computedName)); + + AXObject::NameSources nameSources; + String computedName = axObject->name(&nameSources); + if (!nameSources.isEmpty()) { + RefPtr<AXValue> name = createValue(computedName, AXValueType::ComputedString); + if (!nameSources.isEmpty()) { + RefPtr<TypeBuilder::Array<AXValueSource>> nameSourceProperties = TypeBuilder::Array<AXValueSource>::create(); + for (size_t i = 0; i < nameSources.size(); ++i) + nameSourceProperties->addItem(createValueSource(nameSources[i])); + name->setSources(nameSourceProperties); + } + nodeObject->setName(name); + } fillCoreProperties(axObject, nodeObject); return nodeObject;
diff --git a/third_party/WebKit/Source/modules/accessibility/InspectorTypeBuilderHelper.cpp b/third_party/WebKit/Source/modules/accessibility/InspectorTypeBuilderHelper.cpp index a280294..03435da 100644 --- a/third_party/WebKit/Source/modules/accessibility/InspectorTypeBuilderHelper.cpp +++ b/third_party/WebKit/Source/modules/accessibility/InspectorTypeBuilderHelper.cpp
@@ -12,7 +12,9 @@ namespace blink { +using TypeBuilder::Accessibility::AXValueNativeSourceType; using TypeBuilder::Accessibility::AXRelatedNode; +using TypeBuilder::Accessibility::AXValueSourceType; PassRefPtr<AXProperty> createProperty(String name, PassRefPtr<AXValue> value) { @@ -90,7 +92,7 @@ PassRefPtr<AXProperty> createProperty(IgnoredReason reason) { if (reason.relatedObject) - return createProperty(ignoredReasonName(reason.reason), createRelatedNodeValue(reason.relatedObject)); + return createProperty(ignoredReasonName(reason.reason), createRelatedNodeValue(reason.relatedObject, nullptr, AXValueType::Idref)); return createProperty(ignoredReasonName(reason.reason), createBooleanValue(true)); } @@ -122,7 +124,7 @@ return axValue; } -PassRefPtr<AXRelatedNode> relatedNodeForAXObject(const AXObject* axObject) +PassRefPtr<AXRelatedNode> relatedNodeForAXObject(const AXObject* axObject, String* name = nullptr) { Node* node = axObject->node(); if (!node) @@ -138,27 +140,107 @@ const AtomicString& idref = element->getIdAttribute(); if (!idref.isEmpty()) relatedNode->setIdref(idref); + + if (name) + relatedNode->setText(*name); return relatedNode; } -PassRefPtr<AXValue> createRelatedNodeValue(const AXObject* axObject) +PassRefPtr<AXValue> createRelatedNodeValue(const AXObject* axObject, String* name, AXValueType::Enum valueType) { - RefPtr<AXValue> axValue = AXValue::create().setType(AXValueType::Idref); - RefPtr<AXRelatedNode> relatedNode = relatedNodeForAXObject(axObject); + RefPtr<AXValue> axValue = AXValue::create().setType(valueType); + RefPtr<AXRelatedNode> relatedNode = relatedNodeForAXObject(axObject, name); axValue->setRelatedNodeValue(relatedNode); return axValue; } -PassRefPtr<AXValue> createRelatedNodeListValue(AXObject::AccessibilityChildrenVector axObjects) +PassRefPtr<AXValue> createRelatedNodeListValue(AXRelatedObjectVector& relatedObjects, AXValueType::Enum valueType) +{ + RefPtr<TypeBuilder::Array<AXRelatedNode>> frontendRelatedNodes = TypeBuilder::Array<AXRelatedNode>::create(); + for (unsigned i = 0; i < relatedObjects.size(); i++) { + RefPtr<AXRelatedNode> frontendRelatedNode = relatedNodeForAXObject(relatedObjects[i]->object, &(relatedObjects[i]->text)); + if (frontendRelatedNode) + frontendRelatedNodes->addItem(frontendRelatedNode); + } + RefPtr<AXValue> axValue = AXValue::create().setType(valueType); + axValue->setRelatedNodeArrayValue(frontendRelatedNodes); + return axValue; +} + +PassRefPtr<AXValue> createRelatedNodeListValue(AXObject::AccessibilityChildrenVector& axObjects, AXValueType::Enum valueType) { RefPtr<TypeBuilder::Array<AXRelatedNode>> relatedNodes = TypeBuilder::Array<AXRelatedNode>::create(); for (unsigned i = 0; i < axObjects.size(); i++) { - if (RefPtr<AXRelatedNode> relatedNode = relatedNodeForAXObject(axObjects[i].get())) + RefPtr<AXRelatedNode> relatedNode = relatedNodeForAXObject(axObjects[i].get()); + if (relatedNode) relatedNodes->addItem(relatedNode); } - RefPtr<AXValue> axValue = AXValue::create().setType(AXValueType::IdrefList); + RefPtr<AXValue> axValue = AXValue::create().setType(valueType); axValue->setRelatedNodeArrayValue(relatedNodes); return axValue; } +AXValueSourceType::Enum valueSourceType(AXNameFrom nameFrom) +{ + switch (nameFrom) { + case AXNameFromAttribute: + return AXValueSourceType::Attribute; + case AXNameFromContents: + return AXValueSourceType::Contents; + case AXNameFromPlaceholder: + return AXValueSourceType::Placeholder; + case AXNameFromRelatedElement: + return AXValueSourceType::RelatedElement; + default: + return AXValueSourceType::Implicit; // TODO(aboxhall): what to do here? + } +} + +AXValueNativeSourceType::Enum nativeSourceType(AXTextFromNativeHTML nativeSource) +{ + switch (nativeSource) { + case AXTextFromNativeHTMLFigcaption: + return AXValueNativeSourceType::Figcaption; + case AXTextFromNativeHTMLLabel: + return AXValueNativeSourceType::Label; + case AXTextFromNativeHTMLLabelFor: + return AXValueNativeSourceType::Labelfor; + case AXTextFromNativeHTMLLabelWrapped: + return AXValueNativeSourceType::Labelwrapped; + case AXTextFromNativeHTMLTableCaption: + return AXValueNativeSourceType::Tablecaption; + default: + return AXValueNativeSourceType::Other; + } +} + + +PassRefPtr<AXValueSource> createValueSource(NameSource& nameSource) +{ + String attribute = nameSource.attribute.toString(); + AXValueSourceType::Enum type = valueSourceType(nameSource.type); + RefPtr<AXValueSource> valueSource = AXValueSource::create().setType(type); + RefPtr<AXValue> value; + if (!nameSource.relatedObjects.isEmpty()) { + AXValueType::Enum valueType = nameSource.attributeValue.isNull() ? AXValueType::NodeList : AXValueType::IdrefList; + value = createRelatedNodeListValue(nameSource.relatedObjects, valueType); + if (!nameSource.attributeValue.isNull()) + value->setValue(JSONString::create(nameSource.attributeValue.string())); + valueSource->setValue(value); + } else if (!nameSource.text.isNull()) { + valueSource->setValue(createValue(nameSource.text)); + } else if (!nameSource.attributeValue.isNull()) { + valueSource->setValue(createValue(nameSource.attributeValue)); + } + if (nameSource.attribute != QualifiedName::null()) + valueSource->setAttribute(nameSource.attribute.localName().string()); + if (nameSource.superseded) + valueSource->setSuperseded(true); + if (nameSource.invalid) + valueSource->setInvalid(true); + if (nameSource.nativeSource != AXTextFromNativeHTMLUninitialized) + valueSource->setNativeSource(nativeSourceType(nameSource.nativeSource)); + return valueSource; +} + } // namespace blink
diff --git a/third_party/WebKit/Source/modules/accessibility/InspectorTypeBuilderHelper.h b/third_party/WebKit/Source/modules/accessibility/InspectorTypeBuilderHelper.h index 0168089..ae7808e 100644 --- a/third_party/WebKit/Source/modules/accessibility/InspectorTypeBuilderHelper.h +++ b/third_party/WebKit/Source/modules/accessibility/InspectorTypeBuilderHelper.h
@@ -18,6 +18,7 @@ using TypeBuilder::Accessibility::AXValueType; using TypeBuilder::Accessibility::AXRelationshipAttributes; using TypeBuilder::Accessibility::AXValue; +using TypeBuilder::Accessibility::AXValueSource; using TypeBuilder::Accessibility::AXWidgetAttributes; using TypeBuilder::Accessibility::AXWidgetStates; @@ -33,8 +34,11 @@ PassRefPtr<AXValue> createValue(int value, AXValueType::Enum = AXValueType::Integer); PassRefPtr<AXValue> createValue(float value, AXValueType::Enum = AXValueType::Number); PassRefPtr<AXValue> createBooleanValue(bool value, AXValueType::Enum = AXValueType::Boolean); -PassRefPtr<AXValue> createRelatedNodeValue(const AXObject*); -PassRefPtr<AXValue> createRelatedNodeListValue(AXObject::AccessibilityChildrenVector); +PassRefPtr<AXValue> createRelatedNodeValue(const AXObject*, String* name = nullptr, AXValueType::Enum = AXValueType::Idref); +PassRefPtr<AXValue> createRelatedNodeListValue(AXRelatedObjectVector&, AXValueType::Enum); +PassRefPtr<AXValue> createRelatedNodeListValue(AXObject::AccessibilityChildrenVector& axObjects, AXValueType::Enum = AXValueType::IdrefList); + +PassRefPtr<AXValueSource> createValueSource(NameSource&); } // namespace blink
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBValue.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBValue.cpp index 490ab09..b576368 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBValue.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/IDBValue.cpp
@@ -7,11 +7,17 @@ #include "platform/blob/BlobData.h" #include "public/platform/WebBlobInfo.h" +#include "public/platform/modules/indexeddb/WebIDBValue.h" namespace blink { IDBValue::IDBValue() = default; +IDBValue::IDBValue(const WebIDBValue& value) + : IDBValue(value.data, value.webBlobInfo, value.primaryKey, value.keyPath) +{ +} + IDBValue::IDBValue(PassRefPtr<SharedBuffer> data, const WebVector<WebBlobInfo>& webBlobInfo, IDBKey* primaryKey, const IDBKeyPath& keyPath) : m_data(data) , m_blobData(adoptPtr(new Vector<RefPtr<BlobDataHandle>>())) @@ -25,11 +31,6 @@ } } -IDBValue::IDBValue(PassRefPtr<SharedBuffer> data, const WebVector<WebBlobInfo>& webBlobInfo) - : IDBValue(data, webBlobInfo, nullptr, IDBKeyPath()) -{ -} - IDBValue::IDBValue(const IDBValue* value, IDBKey* primaryKey, const IDBKeyPath& keyPath) : m_data(value->m_data) , m_blobData(adoptPtr(new Vector<RefPtr<BlobDataHandle>>())) @@ -48,14 +49,9 @@ return adoptRef(new IDBValue()); } -PassRefPtr<IDBValue> IDBValue::create(PassRefPtr<SharedBuffer>data, const WebVector<WebBlobInfo>& webBlobInfo) +PassRefPtr<IDBValue> IDBValue::create(const WebIDBValue& value) { - return adoptRef(new IDBValue(data, webBlobInfo)); -} - -PassRefPtr<IDBValue> IDBValue::create(PassRefPtr<SharedBuffer>data, const WebVector<WebBlobInfo>& webBlobInfo, IDBKey* primaryKey, const IDBKeyPath& keyPath) -{ - return adoptRef(new IDBValue(data, webBlobInfo, primaryKey, keyPath)); + return adoptRef(new IDBValue(value)); } PassRefPtr<IDBValue> IDBValue::create(const IDBValue* value, IDBKey* primaryKey, const IDBKeyPath& keyPath)
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBValue.h b/third_party/WebKit/Source/modules/indexeddb/IDBValue.h index c95098a..69fd9c6a 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBValue.h +++ b/third_party/WebKit/Source/modules/indexeddb/IDBValue.h
@@ -17,12 +17,12 @@ class BlobDataHandle; class WebBlobInfo; +struct WebIDBValue; class MODULES_EXPORT IDBValue final : public RefCounted<IDBValue> { public: static PassRefPtr<IDBValue> create(); - static PassRefPtr<IDBValue> create(PassRefPtr<SharedBuffer>, const WebVector<WebBlobInfo>&); - static PassRefPtr<IDBValue> create(PassRefPtr<SharedBuffer>, const WebVector<WebBlobInfo>&, IDBKey*, const IDBKeyPath&); + static PassRefPtr<IDBValue> create(const WebIDBValue&); static PassRefPtr<IDBValue> create(const IDBValue*, IDBKey*, const IDBKeyPath&); bool isNull() const; @@ -34,7 +34,7 @@ private: IDBValue(); - IDBValue(PassRefPtr<SharedBuffer>, const WebVector<WebBlobInfo>&); + IDBValue(const WebIDBValue&); IDBValue(PassRefPtr<SharedBuffer>, const WebVector<WebBlobInfo>&, IDBKey*, const IDBKeyPath&); IDBValue(const IDBValue*, IDBKey*, const IDBKeyPath&);
diff --git a/third_party/WebKit/Source/modules/indexeddb/WebIDBCallbacksImpl.cpp b/third_party/WebKit/Source/modules/indexeddb/WebIDBCallbacksImpl.cpp index 5190eac9..8c0513d 100644 --- a/third_party/WebKit/Source/modules/indexeddb/WebIDBCallbacksImpl.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/WebIDBCallbacksImpl.cpp
@@ -89,7 +89,7 @@ void WebIDBCallbacksImpl::onSuccess(WebIDBCursor* cursor, const WebIDBKey& key, const WebIDBKey& primaryKey, const WebIDBValue& value) { InspectorInstrumentationCookie cookie = InspectorInstrumentation::traceAsyncCallbackStarting(m_request->executionContext(), m_asyncOperationId); - m_request->onSuccess(adoptPtr(cursor), key, primaryKey, IDBValue::create(value.data, value.webBlobInfo)); + m_request->onSuccess(adoptPtr(cursor), key, primaryKey, IDBValue::create(value)); InspectorInstrumentation::traceAsyncCallbackCompleted(cookie); } @@ -110,7 +110,7 @@ void WebIDBCallbacksImpl::onSuccess(const WebIDBValue& value) { InspectorInstrumentationCookie cookie = InspectorInstrumentation::traceAsyncCallbackStarting(m_request->executionContext(), m_asyncOperationId); - m_request->onSuccess(IDBValue::create(value.data, value.webBlobInfo, value.primaryKey, value.keyPath)); + m_request->onSuccess(IDBValue::create(value)); InspectorInstrumentation::traceAsyncCallbackCompleted(cookie); } @@ -118,10 +118,8 @@ { InspectorInstrumentationCookie cookie = InspectorInstrumentation::traceAsyncCallbackStarting(m_request->executionContext(), m_asyncOperationId); Vector<RefPtr<IDBValue>> idbValues(values.size()); - for (size_t i = 0; i < values.size(); ++i) { - const WebIDBValue& value = values[i]; - idbValues[i] = IDBValue::create(value.data, value.webBlobInfo, value.primaryKey, value.keyPath); - } + for (size_t i = 0; i < values.size(); ++i) + idbValues[i] = IDBValue::create(values[i]); m_request->onSuccess(idbValues); InspectorInstrumentation::traceAsyncCallbackCompleted(cookie); } @@ -143,7 +141,7 @@ void WebIDBCallbacksImpl::onSuccess(const WebIDBKey& key, const WebIDBKey& primaryKey, const WebIDBValue& value) { InspectorInstrumentationCookie cookie = InspectorInstrumentation::traceAsyncCallbackStarting(m_request->executionContext(), m_asyncOperationId); - m_request->onSuccess(key, primaryKey, IDBValue::create(value.data, value.webBlobInfo)); + m_request->onSuccess(key, primaryKey, IDBValue::create(value)); InspectorInstrumentation::traceAsyncCallbackCompleted(cookie); }
diff --git a/third_party/WebKit/Source/modules/vr/NavigatorVRDevice.cpp b/third_party/WebKit/Source/modules/vr/NavigatorVRDevice.cpp index 6987356..4824d2b4 100644 --- a/third_party/WebKit/Source/modules/vr/NavigatorVRDevice.cpp +++ b/third_party/WebKit/Source/modules/vr/NavigatorVRDevice.cpp
@@ -83,7 +83,7 @@ NavigatorVRDevice::NavigatorVRDevice(LocalFrame* frame) : DOMWindowProperty(frame) { - m_hardwareUnits = new VRHardwareUnitCollection(controller()); + m_hardwareUnits = new VRHardwareUnitCollection(this); } NavigatorVRDevice::~NavigatorVRDevice()
diff --git a/third_party/WebKit/Source/modules/vr/VRController.h b/third_party/WebKit/Source/modules/vr/VRController.h index 83ca7a1..fed11d5e 100644 --- a/third_party/WebKit/Source/modules/vr/VRController.h +++ b/third_party/WebKit/Source/modules/vr/VRController.h
@@ -14,7 +14,7 @@ namespace blink { class MODULES_EXPORT VRController final - : public GarbageCollectedFinalized<VRController> + : public NoBaseWillBeGarbageCollectedFinalized<VRController> , public WillBeHeapSupplement<LocalFrame> , public LocalFrameLifecycleObserver { WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(VRController);
diff --git a/third_party/WebKit/Source/modules/vr/VRHardwareUnit.cpp b/third_party/WebKit/Source/modules/vr/VRHardwareUnit.cpp index b4d7c788..f463332 100644 --- a/third_party/WebKit/Source/modules/vr/VRHardwareUnit.cpp +++ b/third_party/WebKit/Source/modules/vr/VRHardwareUnit.cpp
@@ -14,10 +14,10 @@ namespace blink { -VRHardwareUnit::VRHardwareUnit(VRController* controller) +VRHardwareUnit::VRHardwareUnit(NavigatorVRDevice* navigatorVRDevice) : m_nextDeviceId(1) , m_frameIndex(0) - , m_controller(controller) + , m_navigatorVRDevice(navigatorVRDevice) { m_positionState = VRPositionState::create(); } @@ -59,13 +59,13 @@ VRController* VRHardwareUnit::controller() { - return m_controller; + return m_navigatorVRDevice->controller(); } VRPositionState* VRHardwareUnit::getSensorState() { WebHMDSensorState state; - m_controller->getSensorState(m_index, state); + controller()->getSensorState(m_index, state); m_positionState->setState(state); m_frameIndex = state.frameIndex; return m_positionState; @@ -73,7 +73,7 @@ DEFINE_TRACE(VRHardwareUnit) { - visitor->trace(m_controller); + visitor->trace(m_navigatorVRDevice); visitor->trace(m_positionState); visitor->trace(m_hmd); visitor->trace(m_positionSensor);
diff --git a/third_party/WebKit/Source/modules/vr/VRHardwareUnit.h b/third_party/WebKit/Source/modules/vr/VRHardwareUnit.h index fc8bfeb..62a4cbee 100644 --- a/third_party/WebKit/Source/modules/vr/VRHardwareUnit.h +++ b/third_party/WebKit/Source/modules/vr/VRHardwareUnit.h
@@ -26,7 +26,7 @@ class VRHardwareUnit : public GarbageCollectedFinalized<VRHardwareUnit> { public: - explicit VRHardwareUnit(VRController*); + explicit VRHardwareUnit(NavigatorVRDevice*); virtual ~VRHardwareUnit(); void updateFromWebVRDevice(const WebVRDevice&); @@ -55,7 +55,7 @@ unsigned m_frameIndex; - Member<VRController> m_controller; + Member<NavigatorVRDevice> m_navigatorVRDevice; Member<VRPositionState> m_positionState; // Device types
diff --git a/third_party/WebKit/Source/modules/vr/VRHardwareUnitCollection.cpp b/third_party/WebKit/Source/modules/vr/VRHardwareUnitCollection.cpp index 9df7d74..383ab65 100644 --- a/third_party/WebKit/Source/modules/vr/VRHardwareUnitCollection.cpp +++ b/third_party/WebKit/Source/modules/vr/VRHardwareUnitCollection.cpp
@@ -22,8 +22,8 @@ namespace blink { -VRHardwareUnitCollection::VRHardwareUnitCollection(VRController* controller) - : m_controller(controller) +VRHardwareUnitCollection::VRHardwareUnitCollection(NavigatorVRDevice* navigatorVRDevice) + : m_navigatorVRDevice(navigatorVRDevice) { } @@ -34,7 +34,7 @@ for (const auto& device : devices) { VRHardwareUnit* hardwareUnit = getHardwareUnitForIndex(device.index); if (!hardwareUnit) { - hardwareUnit = new VRHardwareUnit(m_controller); + hardwareUnit = new VRHardwareUnit(m_navigatorVRDevice); m_hardwareUnits.append(hardwareUnit); } @@ -60,7 +60,7 @@ DEFINE_TRACE(VRHardwareUnitCollection) { - visitor->trace(m_controller); + visitor->trace(m_navigatorVRDevice); visitor->trace(m_hardwareUnits); }
diff --git a/third_party/WebKit/Source/modules/vr/VRHardwareUnitCollection.h b/third_party/WebKit/Source/modules/vr/VRHardwareUnitCollection.h index e273fd2..cbdf63f 100644 --- a/third_party/WebKit/Source/modules/vr/VRHardwareUnitCollection.h +++ b/third_party/WebKit/Source/modules/vr/VRHardwareUnitCollection.h
@@ -16,7 +16,7 @@ class VRHardwareUnitCollection final : public GarbageCollected<VRHardwareUnitCollection> { public: - explicit VRHardwareUnitCollection(VRController*); + explicit VRHardwareUnitCollection(NavigatorVRDevice*); VRDeviceVector updateVRHardwareUnits(const WebVector<WebVRDevice>&); VRHardwareUnit* getHardwareUnitForIndex(unsigned index); @@ -24,7 +24,7 @@ DECLARE_VIRTUAL_TRACE(); private: - Member<VRController> m_controller; + Member<NavigatorVRDevice> m_navigatorVRDevice; HeapVector<Member<VRHardwareUnit>> m_hardwareUnits; };
diff --git a/third_party/WebKit/Source/platform/blink_platform.gypi b/third_party/WebKit/Source/platform/blink_platform.gypi index 4d46be2..fba0e2e2 100644 --- a/third_party/WebKit/Source/platform/blink_platform.gypi +++ b/third_party/WebKit/Source/platform/blink_platform.gypi
@@ -683,10 +683,10 @@ 'graphics/paint/FixedPositionDisplayItem.h', 'graphics/paint/FloatClipDisplayItem.cpp', 'graphics/paint/FloatClipDisplayItem.h', + 'graphics/paint/PaintChunkProperties.h', 'graphics/paint/PaintChunk.h', 'graphics/paint/PaintChunker.cpp', 'graphics/paint/PaintChunker.h', - 'graphics/paint/PaintProperties.h', 'graphics/paint/ScrollDisplayItem.cpp', 'graphics/paint/ScrollDisplayItem.h', 'graphics/paint/SkPictureBuilder.h', @@ -697,6 +697,7 @@ 'graphics/paint/Transform3DDisplayItem.h', 'graphics/paint/TransformDisplayItem.cpp', 'graphics/paint/TransformDisplayItem.h', + 'graphics/paint/TransformPaintPropertyNode.h', 'graphics/paint/CompositingDisplayItem.cpp', 'graphics/paint/CompositingDisplayItem.h', 'graphics/skia/ImagePixelLocker.cpp',
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ClipPathRecorder.cpp b/third_party/WebKit/Source/platform/graphics/paint/ClipPathRecorder.cpp index 5511d28..c2ea498 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/ClipPathRecorder.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/ClipPathRecorder.cpp
@@ -16,8 +16,6 @@ , m_client(client) { ASSERT(m_context.displayItemList()); - if (m_context.displayItemList()->displayItemConstructionIsDisabled()) - return; m_context.displayItemList()->createAndAppend<BeginClipPathDisplayItem>(m_client, clipPath); }
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ClipRecorder.cpp b/third_party/WebKit/Source/platform/graphics/paint/ClipRecorder.cpp index 156f0c2..841154c 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/ClipRecorder.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/ClipRecorder.cpp
@@ -17,8 +17,6 @@ , m_type(type) { ASSERT(m_context.displayItemList()); - if (m_context.displayItemList()->displayItemConstructionIsDisabled()) - return; m_context.displayItemList()->createAndAppend<ClipDisplayItem>(m_client, type, pixelSnappedIntRect(clipRect)); }
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.cpp b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.cpp index 7e8a0df..b4b9c84 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.cpp
@@ -99,9 +99,9 @@ m_newPaintChunks.incrementDisplayItemIndex(); } -void DisplayItemList::updateCurrentPaintProperties(const PaintProperties& newPaintProperties) +void DisplayItemList::updateCurrentPaintChunkProperties(const PaintChunkProperties& newProperties) { - m_newPaintChunks.updateCurrentPaintProperties(newPaintProperties); + m_newPaintChunks.updateCurrentPaintChunkProperties(newProperties); } void DisplayItemList::beginScope()
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.h b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.h index d68207f..482c81a 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.h +++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.h
@@ -78,21 +78,23 @@ // These methods are called during painting. - // Provide a new set of paint properties to apply to recorded display items, - // for Slimming Paint v2. - void updateCurrentPaintProperties(const PaintProperties&); + // Provide a new set of paint chunk properties to apply to recorded display + // items, for Slimming Paint v2. + // TODO(pdr): This should be moved to PaintArtifact. + void updateCurrentPaintChunkProperties(const PaintChunkProperties&); template <typename DisplayItemClass, typename... Args> - DisplayItemClass& createAndAppend(Args&&... args) + void createAndAppend(Args&&... args) { static_assert(WTF::IsSubclass<DisplayItemClass, DisplayItem>::value, "Can only createAndAppend subclasses of DisplayItem."); static_assert(sizeof(DisplayItemClass) <= kMaximumDisplayItemSize, "DisplayItem subclass is larger than kMaximumDisplayItemSize."); + if (displayItemConstructionIsDisabled()) + return; DisplayItemClass& displayItem = m_newDisplayItems.allocateAndConstruct<DisplayItemClass>(WTF::forward<Args>(args)...); processNewItem(displayItem); - return displayItem; } // Creates and appends an ending display item to pair with a preceding
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemTransformTree.h b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemTransformTree.h index 89863dcf..1c7d99b 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemTransformTree.h +++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemTransformTree.h
@@ -18,6 +18,8 @@ // // This class is also the private implementation of WebDisplayItemTransformTree. // For more detail, see WebDisplayItemTransformTree.h. +// +// TODO(pdr): Remove this in favor of TransformPaintPropertyNode. class PLATFORM_EXPORT DisplayItemTransformTree { public: using TransformNode = WebDisplayItemTransformTree::TransformNode;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DrawingRecorder.cpp b/third_party/WebKit/Source/platform/graphics/paint/DrawingRecorder.cpp index 8c41bfbb..cf2859bf 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/DrawingRecorder.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/DrawingRecorder.cpp
@@ -19,9 +19,6 @@ ASSERT(context.displayItemList()); ASSERT(DisplayItem::isDrawingType(type)); - if (context.displayItemList()->displayItemConstructionIsDisabled()) - return false; - if (!context.displayItemList()->clientCacheIsValid(client.displayItemClient())) return false;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintChunk.h b/third_party/WebKit/Source/platform/graphics/paint/PaintChunk.h index b893c28..1edf9f3 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintChunk.h +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintChunk.h
@@ -5,7 +5,7 @@ #ifndef PaintChunk_h #define PaintChunk_h -#include "platform/graphics/paint/PaintProperties.h" +#include "platform/graphics/paint/PaintChunkProperties.h" #include <iosfwd> namespace blink { @@ -18,7 +18,7 @@ // This is a Slimming Paint v2 class. struct PaintChunk { PaintChunk() : beginIndex(0), endIndex(0) { } - PaintChunk(unsigned begin, unsigned end, const PaintProperties& props) + PaintChunk(unsigned begin, unsigned end, const PaintChunkProperties& props) : beginIndex(begin), endIndex(end), properties(props) { } // Index of the first drawing in this chunk. @@ -29,7 +29,7 @@ unsigned endIndex; // The paint properties which apply to this chunk. - PaintProperties properties; + PaintChunkProperties properties; }; inline bool operator==(const PaintChunk& a, const PaintChunk& b)
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintChunkProperties.h b/third_party/WebKit/Source/platform/graphics/paint/PaintChunkProperties.h new file mode 100644 index 0000000..0e8bb4b --- /dev/null +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintChunkProperties.h
@@ -0,0 +1,46 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PaintChunkProperties_h +#define PaintChunkProperties_h + +#include "platform/graphics/paint/TransformPaintPropertyNode.h" + +#include <iosfwd> + +namespace blink { + +// The set of paint properties applying to a |PaintChunk|. These properties are +// not local-only paint style parameters such as color, but instead represent +// the hierarchy of transforms, clips, effects, etc, that apply to a contiguous +// chunk of display items. A single DisplayItemClient can generate multiple +// properties of the same type and this struct represents the total state of all +// properties for a given |PaintChunk|. +// +// This differs from |ObjectPaintProperties| because it only stores one property +// for each type (e.g., either transform or perspective, but not both). +struct PaintChunkProperties { + // TODO(pdr): Add clip, scroll, and effect properties. + RefPtr<TransformPaintPropertyNode> transform; +}; + +// Equality is based only on the pointers and is not 'deep' which would require +// crawling the entire property tree to compute. +inline bool operator==(const PaintChunkProperties& a, const PaintChunkProperties& b) +{ + return a.transform.get() == b.transform.get(); +} + +inline bool operator!=(const PaintChunkProperties& a, const PaintChunkProperties& b) +{ + return !(a == b); +} + +// Redeclared here to avoid ODR issues. +// See platform/testing/PaintPrinters.h. +void PrintTo(const PaintChunkProperties&, std::ostream*); + +} // namespace blink + +#endif // PaintChunkProperties_h
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintChunker.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintChunker.cpp index 2616cca..cf5e9e0 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintChunker.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintChunker.cpp
@@ -17,7 +17,7 @@ { } -void PaintChunker::updateCurrentPaintProperties(const PaintProperties& properties) +void PaintChunker::updateCurrentPaintChunkProperties(const PaintChunkProperties& properties) { ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); @@ -60,7 +60,7 @@ { Vector<PaintChunk> chunks; chunks.swap(m_chunks); - m_currentProperties = PaintProperties(); + m_currentProperties = PaintChunkProperties(); return chunks; }
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintChunker.h b/third_party/WebKit/Source/platform/graphics/paint/PaintChunker.h index 33f5a7a..d99bd34 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintChunker.h +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintChunker.h
@@ -7,22 +7,22 @@ #include "platform/PlatformExport.h" #include "platform/graphics/paint/PaintChunk.h" -#include "platform/graphics/paint/PaintProperties.h" +#include "platform/graphics/paint/PaintChunkProperties.h" #include "wtf/Vector.h" namespace blink { -// Accepts information about changes to |PaintProperties| as drawings are +// Accepts information about changes to |PaintChunkProperties| as drawings are // accumulated, and produces a series of paint chunks: contiguous ranges of the -// display list with identical |PaintProperties|. +// display list with identical |PaintChunkProperties|. class PLATFORM_EXPORT PaintChunker { public: PaintChunker(); ~PaintChunker(); - bool isInInitialState() const { return m_chunks.isEmpty() && m_currentProperties == PaintProperties(); } + bool isInInitialState() const { return m_chunks.isEmpty() && m_currentProperties == PaintChunkProperties(); } - void updateCurrentPaintProperties(const PaintProperties&); + void updateCurrentPaintChunkProperties(const PaintChunkProperties&); void incrementDisplayItemIndex(); void decrementDisplayItemIndex(); @@ -33,7 +33,7 @@ private: Vector<PaintChunk> m_chunks; - PaintProperties m_currentProperties; + PaintChunkProperties m_currentProperties; }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintChunkerTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintChunkerTest.cpp index 38be4a4e..cef32358 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintChunkerTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintChunkerTest.cpp
@@ -14,7 +14,7 @@ namespace blink { namespace { -static PaintProperties samplePaintProperties() { return PaintProperties(); } +static PaintChunkProperties rootPaintChunkProperties() { return PaintChunkProperties(); } class PaintChunkerTest : public testing::Test { protected: @@ -41,33 +41,33 @@ TEST_F(PaintChunkerTest, SingleNonEmptyRange) { PaintChunker chunker; - chunker.updateCurrentPaintProperties(samplePaintProperties()); + chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties()); chunker.incrementDisplayItemIndex(); chunker.incrementDisplayItemIndex(); Vector<PaintChunk> chunks = chunker.releasePaintChunks(); EXPECT_THAT(chunks, ElementsAre( - PaintChunk(0, 2, samplePaintProperties()))); + PaintChunk(0, 2, rootPaintChunkProperties()))); } TEST_F(PaintChunkerTest, SamePropertiesTwiceCombineIntoOneChunk) { PaintChunker chunker; - chunker.updateCurrentPaintProperties(samplePaintProperties()); + chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties()); chunker.incrementDisplayItemIndex(); chunker.incrementDisplayItemIndex(); - chunker.updateCurrentPaintProperties(samplePaintProperties()); + chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties()); chunker.incrementDisplayItemIndex(); Vector<PaintChunk> chunks = chunker.releasePaintChunks(); EXPECT_THAT(chunks, ElementsAre( - PaintChunk(0, 3, samplePaintProperties()))); + PaintChunk(0, 3, rootPaintChunkProperties()))); } TEST_F(PaintChunkerTest, CanRewindDisplayItemIndex) { PaintChunker chunker; - chunker.updateCurrentPaintProperties(samplePaintProperties()); + chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties()); chunker.incrementDisplayItemIndex(); chunker.incrementDisplayItemIndex(); chunker.decrementDisplayItemIndex(); @@ -75,11 +75,85 @@ Vector<PaintChunk> chunks = chunker.releasePaintChunks(); EXPECT_THAT(chunks, ElementsAre( - PaintChunk(0, 2, samplePaintProperties()))); + PaintChunk(0, 2, rootPaintChunkProperties()))); } -// TODO(jbroman): Add more tests one it is possible for there to be two distinct -// PaintProperties. +TEST_F(PaintChunkerTest, BuildMultipleChunksWithSinglePropertyChanging) +{ + PaintChunker chunker; + chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties()); + chunker.incrementDisplayItemIndex(); + chunker.incrementDisplayItemIndex(); + + PaintChunkProperties simpleTransform; + simpleTransform.transform = adoptRef(new TransformPaintPropertyNode(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7))); + + chunker.updateCurrentPaintChunkProperties(simpleTransform); + chunker.incrementDisplayItemIndex(); + + PaintChunkProperties anotherTransform; + anotherTransform.transform = adoptRef(new TransformPaintPropertyNode(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7))); + chunker.updateCurrentPaintChunkProperties(anotherTransform); + chunker.incrementDisplayItemIndex(); + + Vector<PaintChunk> chunks = chunker.releasePaintChunks(); + + EXPECT_THAT(chunks, ElementsAre( + PaintChunk(0, 2, rootPaintChunkProperties()), + PaintChunk(2, 3, simpleTransform), + PaintChunk(3, 4, anotherTransform))); +} + +TEST_F(PaintChunkerTest, BuildLinearChunksFromNestedTransforms) +{ + // Test that "nested" transforms linearize using the following + // sequence of transforms and display items: + // <root xform>, <paint>, <a xform>, <paint>, <paint>, </a xform>, <paint>, </root xform> + PaintChunker chunker; + chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties()); + chunker.incrementDisplayItemIndex(); + + PaintChunkProperties simpleTransform; + simpleTransform.transform = adoptRef(new TransformPaintPropertyNode(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7))); + chunker.updateCurrentPaintChunkProperties(simpleTransform); + chunker.incrementDisplayItemIndex(); + chunker.incrementDisplayItemIndex(); + + chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties()); + chunker.incrementDisplayItemIndex(); + + Vector<PaintChunk> chunks = chunker.releasePaintChunks(); + + EXPECT_THAT(chunks, ElementsAre( + PaintChunk(0, 1, rootPaintChunkProperties()), + PaintChunk(1, 3, simpleTransform), + PaintChunk(3, 4, rootPaintChunkProperties()))); +} + +TEST_F(PaintChunkerTest, ChangingPropertiesWithoutItems) +{ + // Test that properties can change without display items being generated. + PaintChunker chunker; + chunker.updateCurrentPaintChunkProperties(rootPaintChunkProperties()); + chunker.incrementDisplayItemIndex(); + + PaintChunkProperties firstTransform; + firstTransform.transform = adoptRef(new TransformPaintPropertyNode(TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7))); + chunker.updateCurrentPaintChunkProperties(firstTransform); + + PaintChunkProperties secondTransform; + secondTransform.transform = adoptRef(new TransformPaintPropertyNode(TransformationMatrix(9, 8, 7, 6, 5, 4), FloatPoint3D(3, 2, 1))); + chunker.updateCurrentPaintChunkProperties(secondTransform); + + chunker.incrementDisplayItemIndex(); + Vector<PaintChunk> chunks = chunker.releasePaintChunks(); + + EXPECT_THAT(chunks, ElementsAre( + PaintChunk(0, 1, rootPaintChunkProperties()), + PaintChunk(1, 2, secondTransform))); +} + +// TODO(pdr): Add more tests once we have more paint properties. } // namespace } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintProperties.h b/third_party/WebKit/Source/platform/graphics/paint/PaintProperties.h deleted file mode 100644 index 69a6651..0000000 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintProperties.h +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef PaintProperties_h -#define PaintProperties_h - -#include <iosfwd> - -namespace blink { - -// The set of paint properties applying to a |PaintChunk|. -// In particular, this does not mean properties like background-color, but -// rather the hierarchy of transforms, clips, effects, etc. that apply to a -// contiguous chunk of drawings. -struct PaintProperties { - // TODO(jbroman): Add actual properties. -}; - -inline bool operator==(const PaintProperties&, const PaintProperties&) -{ - return true; -} - -inline bool operator!=(const PaintProperties& a, const PaintProperties& b) -{ - return !(a == b); -} - -// Redeclared here to avoid ODR issues. -// See platform/testing/PaintPrinters.h. -void PrintTo(const PaintProperties&, std::ostream*); - -} // namespace blink - -#endif // PaintProperties_h
diff --git a/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.h b/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.h new file mode 100644 index 0000000..e656dc8 --- /dev/null +++ b/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.h
@@ -0,0 +1,46 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef TransformPaintPropertyNode_h +#define TransformPaintPropertyNode_h + +#include "platform/PlatformExport.h" +#include "platform/geometry/FloatPoint3D.h" +#include "platform/transforms/TransformationMatrix.h" +#include "wtf/PassRefPtr.h" +#include "wtf/RefCounted.h" +#include "wtf/RefPtr.h" + +#include <iosfwd> + +namespace blink { + +// A transform created by a css property such as "transform" or "perspective" +// along with a reference to the parent TransformPaintPropertyNode, or nullptr +// for the root. +class PLATFORM_EXPORT TransformPaintPropertyNode : public RefCounted<TransformPaintPropertyNode> { +public: + TransformPaintPropertyNode(const TransformationMatrix& matrix, const FloatPoint3D& origin, PassRefPtr<TransformPaintPropertyNode> parent = nullptr) + : m_matrix(matrix), m_origin(origin), m_parent(parent) { } + + const TransformationMatrix& matrix() const { return m_matrix; } + const FloatPoint3D& origin() const { return m_origin; } + + // Parent transform that this transform is relative to, or nullptr if this + // is the root transform. + const TransformPaintPropertyNode* parent() const { return m_parent.get(); } + +private: + const TransformationMatrix m_matrix; + const FloatPoint3D m_origin; + RefPtr<TransformPaintPropertyNode> m_parent; +}; + +// Redeclared here to avoid ODR issues. +// See platform/testing/PaintPrinters.h. +void PrintTo(const TransformPaintPropertyNode&, std::ostream*); + +} // namespace blink + +#endif // TransformPaintPropertyNode_h
diff --git a/third_party/WebKit/Source/platform/testing/PaintPrinters.cpp b/third_party/WebKit/Source/platform/testing/PaintPrinters.cpp index 16d4667e..8b458a6 100644 --- a/third_party/WebKit/Source/platform/testing/PaintPrinters.cpp +++ b/third_party/WebKit/Source/platform/testing/PaintPrinters.cpp
@@ -6,7 +6,7 @@ #include "platform/testing/PaintPrinters.h" #include "platform/graphics/paint/PaintChunk.h" -#include "platform/graphics/paint/PaintProperties.h" +#include "platform/graphics/paint/PaintChunkProperties.h" #include <ostream> // NOLINT namespace blink { @@ -20,9 +20,46 @@ *os << ")"; } -void PrintTo(const PaintProperties& properties, std::ostream* os) +void PrintTo(const PaintChunkProperties& properties, std::ostream* os) { - *os << "PaintProperties()"; + *os << "PaintChunkProperties("; + if (properties.transform) { + *os << "transform="; + PrintTo(*properties.transform, os); + } + *os << ")"; +} + +// TODO(pdr): Create and move this to TransformPrinters.cpp. +static void PrintTo(const TransformationMatrix& matrix, std::ostream* os) +{ + TransformationMatrix::DecomposedType decomposition; + if (!matrix.decompose(decomposition)) { + *os << "TransformationMatrix(degenerate)"; + return; + } + + if (matrix.isIdentityOrTranslation()) { + *os << "TransformationMatrix(translation=(" << decomposition.translateX << "," << decomposition.translateY << "," << decomposition.translateZ << "))"; + return; + } + + *os << "TransformationMatrix(" + << "translation=(" << decomposition.translateX << "," << decomposition.translateY << "," << decomposition.translateZ << ")" + << ", scale=(" << decomposition.scaleX << "," << decomposition.scaleY << "," << decomposition.scaleZ << ")" + << ", skew=(" << decomposition.skewXY << "," << decomposition.skewXZ << "," << decomposition.skewYZ << ")" + << ", quaternion=(" << decomposition.quaternionX << "," << decomposition.quaternionY << "," << decomposition.quaternionZ << "," << decomposition.quaternionW << ")" + << ", perspective=(" << decomposition.perspectiveX << "," << decomposition.perspectiveY << "," << decomposition.perspectiveZ << "," << decomposition.perspectiveW << ")" + << ")"; +} + +void PrintTo(const TransformPaintPropertyNode& transformPaintProperty, std::ostream* os) +{ + *os << "TransformPaintPropertyNode(matrix="; + PrintTo(transformPaintProperty.matrix(), os); + *os << ", origin="; + PrintTo(transformPaintProperty.origin(), os); + *os << ")"; } } // namespace blink
diff --git a/third_party/WebKit/Source/platform/testing/PaintPrinters.h b/third_party/WebKit/Source/platform/testing/PaintPrinters.h index 31f7ddcc..34c88ef 100644 --- a/third_party/WebKit/Source/platform/testing/PaintPrinters.h +++ b/third_party/WebKit/Source/platform/testing/PaintPrinters.h
@@ -11,6 +11,7 @@ struct PaintChunk; struct PaintProperties; +class TransformPaintPropertyNode; // GTest print support for platform paint classes. // @@ -25,6 +26,7 @@ // your unit test binary. void PrintTo(const PaintChunk&, std::ostream*); void PrintTo(const PaintProperties&, std::ostream*); +void PrintTo(const TransformPaintPropertyNode&, std::ostream*); } // namespace blink
diff --git a/third_party/WebKit/Source/web/WebFrame.cpp b/third_party/WebKit/Source/web/WebFrame.cpp index 98042f6..a1f3cd6 100644 --- a/third_party/WebKit/Source/web/WebFrame.cpp +++ b/third_party/WebKit/Source/web/WebFrame.cpp
@@ -83,12 +83,24 @@ frame->m_openedFrameTracker.reset(m_openedFrameTracker.release()); } + FrameHost* host = oldFrame->host(); + AtomicString name = oldFrame->tree().name(); + FrameOwner* owner = oldFrame->owner(); + oldFrame->disconnectOwnerElement(); + + v8::HandleScope handleScope(v8::Isolate::GetCurrent()); + HashMap<DOMWrapperWorld*, v8::Local<v8::Object>> globals; + oldFrame->windowProxyManager()->clearForNavigation(); + oldFrame->windowProxyManager()->releaseGlobals(globals); + + // Although the Document in this frame is now unloaded, many resources + // associated with the frame itself have not yet been freed yet. + oldFrame->detach(FrameDetachType::Swap); + // Finally, clone the state of the current Frame into one matching // the type of the passed in WebFrame. // FIXME: This is a bit clunky; this results in pointless decrements and // increments of connected subframes. - FrameOwner* owner = oldFrame->owner(); - oldFrame->disconnectOwnerElement(); if (frame->isWebLocalFrame()) { LocalFrame& localFrame = *toWebLocalFrameImpl(frame)->frame(); ASSERT(owner == localFrame.owner()); @@ -104,13 +116,11 @@ localFrame.page()->setMainFrame(&localFrame); } } else { - toWebRemoteFrameImpl(frame)->initializeCoreFrame(oldFrame->host(), owner, oldFrame->tree().name()); + toWebRemoteFrameImpl(frame)->initializeCoreFrame(host, owner, name); } - toCoreFrame(frame)->finishSwapFrom(oldFrame.get()); - // Although the Document in this frame is now unloaded, many resources - // associated with the frame itself have not yet been freed yet. - oldFrame->detach(FrameDetachType::Swap); + toCoreFrame(frame)->windowProxyManager()->setGlobals(globals); + m_parent = nullptr; return true;
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp index 27b2257..51f87fbd 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.cpp +++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -401,7 +401,7 @@ WebViewImpl::WebViewImpl(WebViewClient* client) : m_client(client) - , m_spellCheckClient(0) + , m_spellCheckClient(nullptr) , m_chromeClientImpl(ChromeClientImpl::create(this)) , m_contextMenuClientImpl(this) , m_dragClientImpl(this) @@ -429,10 +429,10 @@ , m_devToolsEmulator(nullptr) , m_isTransparent(false) , m_tabsToLinks(false) - , m_layerTreeView(0) - , m_rootLayer(0) - , m_rootGraphicsLayer(0) - , m_rootTransformLayer(0) + , m_layerTreeView(nullptr) + , m_rootLayer(nullptr) + , m_rootGraphicsLayer(nullptr) + , m_rootTransformLayer(nullptr) , m_graphicsLayerFactory(adoptPtr(new GraphicsLayerFactoryChromium(this))) , m_matchesHeuristicsForGpuRasterization(false) , m_recreatingGraphicsContext(false) @@ -458,7 +458,7 @@ m_page = adoptPtrWillBeNoop(new Page(pageClients)); MediaKeysController::provideMediaKeysTo(*m_page, &m_mediaKeysClientImpl); - provideSpeechRecognitionTo(*m_page, SpeechRecognitionClientProxy::create(client ? client->speechRecognizer() : 0)); + provideSpeechRecognitionTo(*m_page, SpeechRecognitionClientProxy::create(client ? client->speechRecognizer() : nullptr)); provideContextFeaturesTo(*m_page, ContextFeaturesClientImpl::create()); provideDatabaseClientTo(*m_page, DatabaseClientImpl::create()); @@ -501,9 +501,10 @@ return nullptr; } -WebLocalFrameImpl* WebViewImpl::mainFrameImpl() +WebLocalFrameImpl* WebViewImpl::mainFrameImpl() const { - return m_page && m_page->mainFrame() && m_page->mainFrame()->isLocalFrame() ? WebLocalFrameImpl::fromFrame(m_page->deprecatedLocalMainFrame()) : 0; + return m_page && m_page->mainFrame() && m_page->mainFrame()->isLocalFrame() + ? WebLocalFrameImpl::fromFrame(m_page->deprecatedLocalMainFrame()) : nullptr; } bool WebViewImpl::tabKeyCyclesThroughElements() const @@ -1296,7 +1297,7 @@ TRACE_EVENT0("input", "WebViewImpl::bestTapNode"); if (!m_page || !m_page->mainFrame()) - return 0; + return nullptr; Node* bestTouchNode = targetedTapEvent.hitTestResult().innerNode(); if (!bestTouchNode) @@ -1318,7 +1319,7 @@ findCursorDefiningAncestor(bestTouchNode, m_page->deprecatedLocalMainFrame()); // We show a highlight on tap only when the current node shows a hand cursor if (!cursorDefiningAncestor || !showsHandCursor(cursorDefiningAncestor, m_page->deprecatedLocalMainFrame())) { - return 0; + return nullptr; } // We should pick the largest enclosing node with hand cursor set. We do this by first jumping @@ -1395,7 +1396,8 @@ if (shouldZoomOut) { scale = minimumPageScaleFactor(); - isAnimating = startPageScaleAnimation(mainFrameImpl()->frameView()->rootFrameToContents(pointInRootFrame), true, scale, doubleTapZoomAnimationDurationInSeconds); + IntPoint targetPosition = mainFrameImpl()->frameView()->rootFrameToContents(pointInRootFrame); + isAnimating = startPageScaleAnimation(targetPosition, true, scale, doubleTapZoomAnimationDurationInSeconds); } else { isAnimating = startPageScaleAnimation(scroll, false, scale, doubleTapZoomAnimationDurationInSeconds); } @@ -1654,20 +1656,22 @@ void WebViewImpl::enablePopupMouseWheelEventListener() { ASSERT(!m_popupMouseWheelEventListener); - ASSERT(mainFrameImpl()->frame()->document()); + Document* document = mainFrameImpl()->frame()->document(); + ASSERT(document); // We register an empty event listener, EmptyEventListener, so that mouse // wheel events get sent to the WebView. m_popupMouseWheelEventListener = EmptyEventListener::create(); - mainFrameImpl()->frame()->document()->addEventListener(EventTypeNames::mousewheel, m_popupMouseWheelEventListener, false); + document->addEventListener(EventTypeNames::mousewheel, m_popupMouseWheelEventListener, false); } void WebViewImpl::disablePopupMouseWheelEventListener() { ASSERT(m_popupMouseWheelEventListener); - ASSERT(mainFrameImpl()->frame()->document()); + Document* document = mainFrameImpl()->frame()->document(); + ASSERT(document); // Document may have already removed the event listener, for instance, due // to a navigation, but remove it anyway. - mainFrameImpl()->frame()->document()->removeEventListener(EventTypeNames::mousewheel, m_popupMouseWheelEventListener.release(), false); + document->removeEventListener(EventTypeNames::mousewheel, m_popupMouseWheelEventListener.release(), false); } LocalDOMWindow* WebViewImpl::pagePopupWindow() const @@ -1677,14 +1681,12 @@ Frame* WebViewImpl::focusedCoreFrame() const { - return m_page ? m_page->focusController().focusedOrMainFrame() : 0; + return m_page ? m_page->focusController().focusedOrMainFrame() : nullptr; } WebViewImpl* WebViewImpl::fromPage(Page* page) { - if (!page) - return 0; - return static_cast<WebViewImpl*>(page->chromeClient().webView()); + return page ? static_cast<WebViewImpl*>(page->chromeClient().webView()) : nullptr; } // WebWidget ------------------------------------------------------------------ @@ -2228,7 +2230,7 @@ return; LocalFrame* frame = m_page->mainFrame() && m_page->mainFrame()->isLocalFrame() - ? m_page->deprecatedLocalMainFrame() : 0; + ? m_page->deprecatedLocalMainFrame() : nullptr; if (!frame) return; @@ -2595,7 +2597,7 @@ WebPluginContainerImpl* container = WebLocalFrameImpl::pluginContainerFromNode(frame, WebNode(focusedElement())); if (container && container->supportsInputMethod()) return container->plugin(); - return 0; + return nullptr; } bool WebViewImpl::selectionTextDirection(WebTextDirection& start, WebTextDirection& end) const @@ -2699,7 +2701,7 @@ } setRootGraphicsLayer(nullptr); - m_layerTreeView = 0; + m_layerTreeView = nullptr; } void WebViewImpl::didAcquirePointerLock() @@ -2783,7 +2785,7 @@ WebFrame* WebViewImpl::mainFrame() { - return WebFrame::fromFrame(m_page ? m_page->mainFrame() : 0); + return WebFrame::fromFrame(m_page ? m_page->mainFrame() : nullptr); } WebFrame* WebViewImpl::findFrameByName( @@ -2795,7 +2797,7 @@ Frame* frame = toWebLocalFrameImpl(relativeToFrame)->frame(); frame = frame->tree().find(name); if (!frame || !frame->isLocalFrame()) - return 0; + return nullptr; return WebLocalFrameImpl::fromFrame(toLocalFrame(frame)); } @@ -2860,7 +2862,7 @@ bool WebViewImpl::scrollFocusedNodeIntoRect(const WebRect& rectInViewport) { LocalFrame* frame = page()->mainFrame() && page()->mainFrame()->isLocalFrame() - ? page()->deprecatedLocalMainFrame() : 0; + ? page()->deprecatedLocalMainFrame() : nullptr; Element* element = focusedElement(); if (!frame || !frame->view() || !element) return false; @@ -3273,7 +3275,16 @@ setInitialPageScaleOverride(-1); } - pageScaleConstraintsSet().adjustForAndroidWebViewQuirks(adjustedDescription, defaultMinWidth.intValue(), deviceScaleFactor(), settingsImpl()->supportDeprecatedTargetDensityDPI(), page()->settings().wideViewportQuirkEnabled(), page()->settings().useWideViewport(), page()->settings().loadWithOverviewMode(), settingsImpl()->viewportMetaNonUserScalableQuirk()); + Settings& pageSettings = page()->settings(); + pageScaleConstraintsSet().adjustForAndroidWebViewQuirks( + adjustedDescription, + defaultMinWidth.intValue(), + deviceScaleFactor(), + settingsImpl()->supportDeprecatedTargetDensityDPI(), + pageSettings.wideViewportQuirkEnabled(), + pageSettings.useWideViewport(), + pageSettings.loadWithOverviewMode(), + settingsImpl()->viewportMetaNonUserScalableQuirk()); float newInitialScale = pageScaleConstraintsSet().pageDefinedConstraints().initialScale; if (oldInitialScale != newInitialScale && newInitialScale != -1) { pageScaleConstraintsSet().setNeedsReset(true); @@ -3329,7 +3340,7 @@ { layout(); - Document* document = m_page->mainFrame()->isLocalFrame() ? m_page->deprecatedLocalMainFrame()->document() : 0; + Document* document = m_page->mainFrame()->isLocalFrame() ? m_page->deprecatedLocalMainFrame()->document() : nullptr; if (!document || !document->layoutView() || !document->documentElement() || !document->documentElement()->layoutBox()) return WebSize(); @@ -3913,7 +3924,7 @@ // If we get to the <body> try to resume commits since we should have content // to paint now. // TODO(esprehn): Is this really optimal? We might start producing frames - // for very little content, should we wait for some herustic like + // for very little content, should we wait for some heuristic like // isVisuallyNonEmpty() ? resumeTreeViewCommitsIfRenderingReady(); } @@ -3968,11 +3979,12 @@ void WebViewImpl::layoutUpdated(WebLocalFrameImpl* webframe) { - if (!m_client || !webframe->frame()->isLocalRoot()) + LocalFrame* frame = webframe->frame(); + if (!m_client || !frame->isLocalRoot()) return; - if (m_shouldAutoResize && webframe->frame() && webframe->frame()->view()) { - WebSize frameSize = webframe->frame()->view()->frameRect().size(); + if (m_shouldAutoResize) { + WebSize frameSize = frame->view()->frameRect().size(); if (frameSize != m_size) { m_size = frameSize; @@ -4072,11 +4084,11 @@ { Frame* frame = m_page->focusController().focusedFrame(); if (!frame || !frame->isLocalFrame()) - return 0; + return nullptr; Document* document = toLocalFrame(frame)->document(); if (!document) - return 0; + return nullptr; return document->focusedElement(); } @@ -4137,16 +4149,16 @@ visualViewport.attachToLayerTree(layer, graphicsLayerFactory()); if (layer) { m_rootGraphicsLayer = visualViewport.rootGraphicsLayer(); - m_rootLayer = visualViewport.rootGraphicsLayer()->platformLayer(); - m_rootTransformLayer = visualViewport.rootGraphicsLayer(); + m_rootLayer = m_rootGraphicsLayer->platformLayer(); + m_rootTransformLayer = m_rootGraphicsLayer; updateRootLayerTransform(); m_layerTreeView->setRootLayer(*m_rootLayer); // We register viewport layers here since there may not be a layer // tree view prior to this point. - page()->frameHost().visualViewport().registerLayersWithTreeView(m_layerTreeView); + visualViewport.registerLayersWithTreeView(m_layerTreeView); updatePageOverlays(); // TODO(enne): Work around page visibility changes not being - // propogated to the WebView in some circumstances. This needs to + // propagated to the WebView in some circumstances. This needs to // be refreshed here when setting a new root layer to avoid being // stuck in a presumed incorrectly invisible state. bool visible = page()->visibilityState() == PageVisibilityStateVisible; @@ -4162,7 +4174,7 @@ m_layerTreeView->clearRootLayer(); m_shouldDispatchFirstVisuallyNonEmptyLayout = true; m_shouldDispatchFirstLayoutAfterFinishedParsing = true; - page()->frameHost().visualViewport().clearLayersForTreeView(m_layerTreeView); + visualViewport.clearLayersForTreeView(m_layerTreeView); } } @@ -4181,13 +4193,15 @@ PaintLayerCompositor* WebViewImpl::compositor() const { - if (!page() || !page()->mainFrame() || !page()->mainFrame()->isLocalFrame()) - return 0; + WebLocalFrameImpl* frame = mainFrameImpl(); + if (!frame) + return nullptr; - if (!page()->deprecatedLocalMainFrame()->document() || !page()->deprecatedLocalMainFrame()->document()->layoutView()) - return 0; + Document* document = frame->frame()->document(); + if (!document || !document->layoutView()) + return nullptr; - return page()->deprecatedLocalMainFrame()->document()->layoutView()->compositor(); + return document->layoutView()->compositor(); } void WebViewImpl::registerForAnimations(WebLayer* layer) @@ -4233,9 +4247,9 @@ if (WebDevToolsAgentImpl* devTools = mainFrameDevToolsAgentImpl()) devTools->layerTreeViewChanged(m_layerTreeView); - m_page->settings().setAcceleratedCompositingEnabled(m_layerTreeView != 0); + m_page->settings().setAcceleratedCompositingEnabled(m_layerTreeView); - // FIXME: only unittests, click to play, Android priting, and printing (for headers and footers) + // FIXME: only unittests, click to play, Android printing, and printing (for headers and footers) // make this assert necessary. We should make them not hit this code and then delete allowsBrokenNullLayerTreeView. ASSERT(m_layerTreeView || !m_client || m_client->allowsBrokenNullLayerTreeView());
diff --git a/third_party/WebKit/Source/web/WebViewImpl.h b/third_party/WebKit/Source/web/WebViewImpl.h index a1f3e54..fa13843 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.h +++ b/third_party/WebKit/Source/web/WebViewImpl.h
@@ -339,7 +339,7 @@ // Returns the main frame associated with this view. This may be null when // the page is shutting down, but will be valid at all other times. - WebLocalFrameImpl* mainFrameImpl(); + WebLocalFrameImpl* mainFrameImpl() const; // FIXME: Temporary method to accommodate out-of-process frame ancestors; // will be removed when there can be multiple WebWidgets for a single page.
diff --git a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp index d42df534..72cad6f 100644 --- a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
@@ -159,6 +159,22 @@ ASSERT_EQ(10, point4.y); } +TEST_F(WebPluginContainerTest, PluginDocumentPluginIsFocused) +{ + URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("test.pdf"), WebString::fromUTF8("application/pdf")); + + TestPluginWebFrameClient pluginWebFrameClient; // Must outlive webViewHelper. + FrameTestHelpers::WebViewHelper webViewHelper; + WebView* webView = webViewHelper.initializeAndLoad(m_baseURL + "test.pdf", true, &pluginWebFrameClient); + ASSERT(webView); + webView->layout(); + + WebDocument document = webView->mainFrame()->document(); + EXPECT_TRUE(document.isPluginDocument()); + WebPluginContainer* pluginContainer = getWebPluginContainer(webView, "plugin"); + EXPECT_EQ(document.focusedElement(), pluginContainer->element()); +} + TEST_F(WebPluginContainerTest, PrintOnePage) { URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("test.pdf"), WebString::fromUTF8("application/pdf"));
diff --git a/third_party/WebKit/public/platform/WebScrollbarLayer.h b/third_party/WebKit/public/platform/WebScrollbarLayer.h index e9f7fc1..0fabc51 100644 --- a/third_party/WebKit/public/platform/WebScrollbarLayer.h +++ b/third_party/WebKit/public/platform/WebScrollbarLayer.h
@@ -39,7 +39,6 @@ virtual WebLayer* layer() = 0; virtual void setScrollLayer(WebLayer*) = 0; - virtual void setClipLayer(WebLayer*) = 0; }; } // namespace blink
diff --git a/third_party/android_platform/README.chromium b/third_party/android_platform/README.chromium index 0693deb..c795127 100644 --- a/third_party/android_platform/README.chromium +++ b/third_party/android_platform/README.chromium
@@ -35,6 +35,7 @@ Added support for arch=x64 as an alias to arch=x86_64 Added debug logging and --verbose parameter. Used fast ELF symbolizer for symbols.py and tombstones +Used multiprocessing to pre-process logcat before symbolizing it Android relocation packing tool details: Copy sources from AOSP bionic/tools/relocation_packer
diff --git a/third_party/android_platform/development/scripts/stack_core.py b/third_party/android_platform/development/scripts/stack_core.py index 281917f..34309787 100755 --- a/third_party/android_platform/development/scripts/stack_core.py +++ b/third_party/android_platform/development/scripts/stack_core.py
@@ -16,20 +16,85 @@ """stack symbolizes native crash dumps.""" +import itertools import logging +import multiprocessing +import os import re +import subprocess +import time import symbol +UNKNOWN = '<unknown>' +HEAP = '[heap]' +STACK = '[stack]' +_DEFAULT_JOBS=8 +_CHUNK_SIZE = 1000 + +_PROCESS_INFO_LINE = re.compile('(pid: [0-9]+, tid: [0-9]+.*)') +_SIGNAL_LINE = re.compile('(signal [0-9]+ \(.*\).*)') +_REGISTER_LINE = re.compile('(([ ]*[0-9a-z]{2} [0-9a-f]{8}){4})') +_THREAD_LINE = re.compile('(.*)(\-\-\- ){15}\-\-\-') +_DALVIK_JNI_THREAD_LINE = re.compile("(\".*\" prio=[0-9]+ tid=[0-9]+ NATIVE.*)") +_DALVIK_NATIVE_THREAD_LINE = re.compile("(\".*\" sysTid=[0-9]+ nice=[0-9]+.*)") + +_WIDTH = '{8}' +if symbol.ARCH == 'arm64' or symbol.ARCH == 'x86_64' or symbol.ARCH == 'x64': + _WIDTH = '{16}' + +# Matches LOG(FATAL) lines, like the following example: +# [FATAL:source_file.cc(33)] Check failed: !instances_.empty() +_LOG_FATAL_LINE = re.compile('(\[FATAL\:.*\].*)$') + +# Note that both trace and value line matching allow for variable amounts of +# whitespace (e.g. \t). This is because the we want to allow for the stack +# tool to operate on AndroidFeedback provided system logs. AndroidFeedback +# strips out double spaces that are found in tombsone files and logcat output. +# +# Examples of matched trace lines include lines from tombstone files like: +# #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so +# #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so (symbol) +# Or lines from AndroidFeedback crash report system logs like: +# 03-25 00:51:05.520 I/DEBUG ( 65): #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so +# Please note the spacing differences. +_TRACE_LINE = re.compile('(.*)\#(?P<frame>[0-9]+)[ \t]+(..)[ \t]+(0x)?(?P<address>[0-9a-f]{0,16})[ \t]+(?P<lib>[^\r\n \t]*)(?P<symbol_present> \((?P<symbol_name>.*)\))?') # pylint: disable-msg=C6310 + +# Matches lines emitted by src/base/debug/stack_trace_android.cc, like: +# #00 0x7324d92d /data/app-lib/org.chromium.native_test-1/libbase.cr.so+0x0006992d +# This pattern includes the unused named capture groups <symbol_present> and +# <symbol_name> so that it can interoperate with the |_TRACE_LINE| regex. +_DEBUG_TRACE_LINE = re.compile( + '(.*)(?P<frame>\#[0-9]+ 0x[0-9a-f]' + _WIDTH + ') ' + '(?P<lib>[^+]+)\+0x(?P<address>[0-9a-f]' + _WIDTH + ')' + '(?P<symbol_present>)(?P<symbol_name>)') + +# Examples of matched value lines include: +# bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so +# bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so (symbol) +# 03-25 00:51:05.530 I/DEBUG ( 65): bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so +# Again, note the spacing differences. +_VALUE_LINE = re.compile('(.*)([0-9a-f]' + _WIDTH + ')[ \t]+([0-9a-f]' + _WIDTH + ')[ \t]+([^\r\n \t]*)( \((.*)\))?') +# Lines from 'code around' sections of the output will be matched before +# value lines because otheriwse the 'code around' sections will be confused as +# value lines. +# +# Examples include: +# 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8 +# 03-25 00:51:05.530 I/DEBUG ( 65): 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8 +code_line = re.compile('(.*)[ \t]*[a-f0-9]' + _WIDTH + '[ \t]*[a-f0-9]' + _WIDTH + + '[ \t]*[a-f0-9]' + _WIDTH + '[ \t]*[a-f0-9]' + _WIDTH + + '[ \t]*[a-f0-9]' + _WIDTH + '[ \t]*[ \r\n]') # pylint: disable-msg=C6310 + def PrintTraceLines(trace_lines): """Print back trace.""" maxlen = max(map(lambda tl: len(tl[1]), trace_lines)) print - print "Stack Trace:" - print " RELADDR " + "FUNCTION".ljust(maxlen) + " FILE:LINE" + print 'Stack Trace:' + print ' RELADDR ' + 'FUNCTION'.ljust(maxlen) + ' FILE:LINE' for tl in trace_lines: (addr, symbol_with_offset, location) = tl - print " %8s %s %s" % (addr, symbol_with_offset.ljust(maxlen), location) + print ' %8s %s %s' % (addr, symbol_with_offset.ljust(maxlen), location) return @@ -37,17 +102,13 @@ """Print stack data values.""" maxlen = max(map(lambda tl: len(tl[2]), value_lines)) print - print "Stack Data:" - print " ADDR VALUE " + "FUNCTION".ljust(maxlen) + " FILE:LINE" + print 'Stack Data:' + print ' ADDR VALUE ' + 'FUNCTION'.ljust(maxlen) + ' FILE:LINE' for vl in value_lines: (addr, value, symbol_with_offset, location) = vl - print " %8s %8s %s %s" % (addr, value, symbol_with_offset.ljust(maxlen), location) + print ' %8s %8s %s %s' % (addr, value, symbol_with_offset.ljust(maxlen), location) return -UNKNOWN = "<unknown>" -HEAP = "[heap]" -STACK = "[stack]" - def PrintOutput(trace_lines, value_lines, more_info): if trace_lines: @@ -63,66 +124,60 @@ def PrintDivider(): print - print "-----------------------------------------------------\n" + print '-----------------------------------------------------\n' def ConvertTrace(lines, more_info): """Convert strings containing native crash to a stack.""" - process_info_line = re.compile("(pid: [0-9]+, tid: [0-9]+.*)") - signal_line = re.compile("(signal [0-9]+ \(.*\).*)") - register_line = re.compile("(([ ]*[0-9a-z]{2} [0-9a-f]{8}){4})") - thread_line = re.compile("(.*)(\-\-\- ){15}\-\-\-") - dalvik_jni_thread_line = re.compile("(\".*\" prio=[0-9]+ tid=[0-9]+ NATIVE.*)") - dalvik_native_thread_line = re.compile("(\".*\" sysTid=[0-9]+ nice=[0-9]+.*)") + start = time.time() - width = "{8}" - if symbol.ARCH == "arm64" or symbol.ARCH == "x86_64" or symbol.ARCH == "x64": - width = "{16}" + chunks = [lines[i: i+_CHUNK_SIZE] for i in xrange(0, len(lines), _CHUNK_SIZE)] + pool = multiprocessing.Pool(processes=_DEFAULT_JOBS) + useful_log = itertools.chain(*pool.map(PreProcessLog, chunks)) + pool.close() + pool.join() + end = time.time() + logging.debug('Finished processing. Elapsed time: %.4fs', (end - start)) - # Matches LOG(FATAL) lines, like the following example: - # [FATAL:source_file.cc(33)] Check failed: !instances_.empty() - log_fatal_line = re.compile("(\[FATAL\:.*\].*)$") + ResolveCrashSymbol(list(useful_log), more_info) + end = time.time() + logging.debug('Finished resolving symbols. Elapsed time: %.4fs', + (end - start)) - # Note that both trace and value line matching allow for variable amounts of - # whitespace (e.g. \t). This is because the we want to allow for the stack - # tool to operate on AndroidFeedback provided system logs. AndroidFeedback - # strips out double spaces that are found in tombsone files and logcat output. - # - # Examples of matched trace lines include lines from tombstone files like: - # #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so - # #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so (symbol) - # Or lines from AndroidFeedback crash report system logs like: - # 03-25 00:51:05.520 I/DEBUG ( 65): #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so - # Please note the spacing differences. - trace_line = re.compile("(.*)\#(?P<frame>[0-9]+)[ \t]+(..)[ \t]+(0x)?(?P<address>[0-9a-f]{0,16})[ \t]+(?P<lib>[^\r\n \t]*)(?P<symbol_present> \((?P<symbol_name>.*)\))?") # pylint: disable-msg=C6310 - # Matches lines emitted by src/base/debug/stack_trace_android.cc, like: - # #00 0x7324d92d /data/app-lib/org.chromium.native_test-1/libbase.cr.so+0x0006992d - # This pattern includes the unused named capture groups <symbol_present> and - # <symbol_name> so that it can interoperate with the |trace_line| regex. - debug_trace_line = re.compile( - '(.*)(?P<frame>\#[0-9]+ 0x[0-9a-f]' + width + ') ' - '(?P<lib>[^+]+)\+0x(?P<address>[0-9a-f]' + width + ')' - '(?P<symbol_present>)(?P<symbol_name>)') +def PreProcessLog(lines): + """Preprocess the strings, only keep the useful ones. + Args: + lines: a list of byte strings read from logcat - # Examples of matched value lines include: - # bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so - # bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so (symbol) - # 03-25 00:51:05.530 I/DEBUG ( 65): bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so - # Again, note the spacing differences. - value_line = re.compile("(.*)([0-9a-f]" + width + ")[ \t]+([0-9a-f]" + width + ")[ \t]+([^\r\n \t]*)( \((.*)\))?") - # Lines from 'code around' sections of the output will be matched before - # value lines because otheriwse the 'code around' sections will be confused as - # value lines. - # - # Examples include: - # 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8 - # 03-25 00:51:05.530 I/DEBUG ( 65): 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8 - code_line = re.compile("(.*)[ \t]*[a-f0-9]" + width + - "[ \t]*[a-f0-9]" + width + - "[ \t]*[a-f0-9]" + width + - "[ \t]*[a-f0-9]" + width + - "[ \t]*[a-f0-9]" + width + - "[ \t]*[ \r\n]") # pylint: disable-msg=C6310 + Returns: + A list of unicode strings related to native crash + """ + useful_log = [] + for ln in lines: + line = unicode(ln, errors='ignore') + if (_PROCESS_INFO_LINE.search(line) + or _SIGNAL_LINE.search(line) + or _REGISTER_LINE.search(line) + or _THREAD_LINE.search(line) + or _DALVIK_JNI_THREAD_LINE.search(line) + or _DALVIK_NATIVE_THREAD_LINE.search(line) + or _LOG_FATAL_LINE.search(line) + or _TRACE_LINE.match(line) + or _DEBUG_TRACE_LINE.match(line)): + useful_log.append(line) + continue + + if code_line.match(line): + # Code lines should be ignored. If this were excluded the 'code around' + # sections would trigger value_line matches. + continue + if _VALUE_LINE.match(line): + useful_log.append(line) + return useful_log + +def ResolveCrashSymbol(lines, more_info): + """Convert unicode strings which contains native crash to a stack + """ trace_lines = [] value_lines = [] @@ -134,15 +189,14 @@ # from the log and call symbol.SymbolInformation so that the results are # cached in the following lookups. code_addresses = {} - for ln in lines: - line = unicode(ln, errors='ignore') + for line in lines: lib, address = None, None - match = trace_line.match(line) or debug_trace_line.match(line) + match = _TRACE_LINE.match(line) or _DEBUG_TRACE_LINE.match(line) if match: address, lib = match.group('address', 'lib') - match = value_line.match(line) + match = _VALUE_LINE.match(line) if match and not code_line.match(line): (_0, _1, address, lib, _2, _3) = match.groups() @@ -153,17 +207,16 @@ symbol.SymbolInformationForSet( symbol.TranslateLibPath(lib), code_addresses[lib], more_info) - for ln in lines: + for line in lines: # AndroidFeedback adds zero width spaces into its crash reports. These # should be removed or the regular expresssions will fail to match. - line = unicode(ln, errors='ignore') - process_header = process_info_line.search(line) - signal_header = signal_line.search(line) - register_header = register_line.search(line) - thread_header = thread_line.search(line) - dalvik_jni_thread_header = dalvik_jni_thread_line.search(line) - dalvik_native_thread_header = dalvik_native_thread_line.search(line) - log_fatal_header = log_fatal_line.search(line) + process_header = _PROCESS_INFO_LINE.search(line) + signal_header = _SIGNAL_LINE.search(line) + register_header = _REGISTER_LINE.search(line) + thread_header = _THREAD_LINE.search(line) + dalvik_jni_thread_header = _DALVIK_JNI_THREAD_LINE.search(line) + dalvik_native_thread_header = _DALVIK_NATIVE_THREAD_LINE.search(line) + log_fatal_header = _LOG_FATAL_LINE.search(line) if (process_header or signal_header or register_header or thread_header or dalvik_jni_thread_header or dalvik_native_thread_header or log_fatal_header) : @@ -189,7 +242,7 @@ print log_fatal_header.group(1) continue - match = trace_line.match(line) or debug_trace_line.match(line) + match = _TRACE_LINE.match(line) or _DEBUG_TRACE_LINE.match(line) if match: frame, code_addr, area, symbol_present, symbol_name = match.group( 'frame', 'address', 'lib', 'symbol_present', 'symbol_name') @@ -203,7 +256,7 @@ last_frame = frame if area == UNKNOWN or area == HEAP or area == STACK: - trace_lines.append((code_addr, "", area)) + trace_lines.append((code_addr, '', area)) else: logging.debug('Identified lib: %s' % area) # If a calls b which further calls c and c is inlined to b, we want to @@ -221,22 +274,18 @@ source_location = area if nest_count > 0: nest_count = nest_count - 1 - trace_lines.append(("v------>", source_symbol, source_location)) + trace_lines.append(('v------>', source_symbol, source_location)) else: if not object_symbol_with_offset: object_symbol_with_offset = source_symbol trace_lines.append((code_addr, object_symbol_with_offset, source_location)) - if code_line.match(line): - # Code lines should be ignored. If this were exluded the 'code around' - # sections would trigger value_line matches. - continue; - match = value_line.match(line) + match = _VALUE_LINE.match(line) if match: (unused_, addr, value, area, symbol_present, symbol_name) = match.groups() if area == UNKNOWN or area == HEAP or area == STACK or not area: - value_lines.append((addr, value, "", area)) + value_lines.append((addr, value, '', area)) else: info = symbol.SymbolInformation(area, value, more_info) (source_symbol, source_location, object_symbol_with_offset) = info.pop() @@ -255,3 +304,5 @@ source_location)) PrintOutput(trace_lines, value_lines, more_info) + +
diff --git a/third_party/closure_compiler/externs/networking_private.js b/third_party/closure_compiler/externs/networking_private.js index cc9e8b6..aebf7f9 100644 --- a/third_party/closure_compiler/externs/networking_private.js +++ b/third_party/closure_compiler/externs/networking_private.js
@@ -731,6 +731,7 @@ /** * @typedef {{ + * AutoConnect: (boolean|undefined), * Authentication: (string|undefined), * EAP: (!chrome.networkingPrivate.EAPProperties|undefined) * }} @@ -740,6 +741,7 @@ /** * @typedef {{ + * AutoConnect: (!chrome.networkingPrivate.ManagedBoolean|undefined), * Authentication: (!chrome.networkingPrivate.ManagedDOMString|undefined), * EAP: (!chrome.networkingPrivate.ManagedEAPProperties|undefined) * }} @@ -1308,5 +1310,3 @@ * @see https://developer.chrome.com/extensions/networkingPrivate#event-onPortalDetectionCompleted */ chrome.networkingPrivate.onPortalDetectionCompleted; - -
diff --git a/third_party/libvpx_new/README.chromium b/third_party/libvpx_new/README.chromium index 0404d6c..609a484 100644 --- a/third_party/libvpx_new/README.chromium +++ b/third_party/libvpx_new/README.chromium
@@ -5,9 +5,9 @@ License File: source/libvpx/LICENSE Security Critical: yes -Date: Tuesday September 29 2015 +Date: Tuesday October 06 2015 Branch: master -Commit: 7d28d12ef34f6cbb6b1e18f3b23b71392fd3ddf5 +Commit: ce3f4ade670cf02e05998f4ca50e08736802f5e7 Description: Contains the sources used to compile libvpx binaries used by Google Chrome and
diff --git a/third_party/libvpx_new/libvpx_srcs.gni b/third_party/libvpx_new/libvpx_srcs.gni index 63685cb..1b70acf3 100644 --- a/third_party/libvpx_new/libvpx_srcs.gni +++ b/third_party/libvpx_new/libvpx_srcs.gni
@@ -49,6 +49,7 @@ "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.c", + "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.h", "//third_party/libvpx_new/source/libvpx/vp8/common/rtcd.c", @@ -393,7 +394,6 @@ ] libvpx_srcs_x86_sse2 = [ "//third_party/libvpx_new/source/libvpx/vp8/common/x86/idct_blk_sse2.c", - "//third_party/libvpx_new/source/libvpx/vp8/common/x86/recon_wrapper_sse2.c", "//third_party/libvpx_new/source/libvpx/vp8/encoder/x86/denoising_sse2.c", "//third_party/libvpx_new/source/libvpx/vp8/encoder/x86/vp8_enc_stubs_sse2.c", "//third_party/libvpx_new/source/libvpx/vp8/encoder/x86/vp8_quantize_sse2.c", @@ -474,6 +474,7 @@ "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.c", + "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.h", "//third_party/libvpx_new/source/libvpx/vp8/common/rtcd.c", @@ -825,7 +826,6 @@ ] libvpx_srcs_x86_64_sse2 = [ "//third_party/libvpx_new/source/libvpx/vp8/common/x86/idct_blk_sse2.c", - "//third_party/libvpx_new/source/libvpx/vp8/common/x86/recon_wrapper_sse2.c", "//third_party/libvpx_new/source/libvpx/vp8/encoder/x86/denoising_sse2.c", "//third_party/libvpx_new/source/libvpx/vp8/encoder/x86/vp8_enc_stubs_sse2.c", "//third_party/libvpx_new/source/libvpx/vp8/encoder/x86/vp8_quantize_sse2.c", @@ -912,6 +912,7 @@ "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.c", + "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.h", "//third_party/libvpx_new/source/libvpx/vp8/common/rtcd.c", @@ -1200,7 +1201,6 @@ "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/dequantize_v6.asm", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/filter_v6.asm", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/idct_v6.asm", - "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/intra4x4_predict_v6.asm", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/iwalsh_v6.asm", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/loopfilter_v6.asm", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/simpleloopfilter_v6.asm", @@ -1235,7 +1235,6 @@ "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.c", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.c", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/mbloopfilter_neon.c", - "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/reconintra_neon.c", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/shortidct4x4llm_neon.c", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/sixtappredict_neon.c", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/vp8_loopfilter_neon.c", @@ -1282,6 +1281,7 @@ "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.c", + "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.h", "//third_party/libvpx_new/source/libvpx/vp8/common/rtcd.c", @@ -1590,7 +1590,6 @@ "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/dequantize_v6.asm", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/filter_v6.asm", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/idct_v6.asm", - "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/intra4x4_predict_v6.asm", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/iwalsh_v6.asm", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/loopfilter_v6.asm", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/simpleloopfilter_v6.asm", @@ -1674,6 +1673,7 @@ "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.c", + "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.h", "//third_party/libvpx_new/source/libvpx/vp8/common/rtcd.c", @@ -1962,7 +1962,6 @@ "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/dequantize_v6.asm", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/filter_v6.asm", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/idct_v6.asm", - "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/intra4x4_predict_v6.asm", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/iwalsh_v6.asm", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/loopfilter_v6.asm", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/armv6/simpleloopfilter_v6.asm", @@ -2007,7 +2006,6 @@ "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.c", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.c", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/mbloopfilter_neon.c", - "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/reconintra_neon.c", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/shortidct4x4llm_neon.c", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/sixtappredict_neon.c", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/vp8_loopfilter_neon.c", @@ -2050,7 +2048,6 @@ "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.c", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.c", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/mbloopfilter_neon.c", - "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/reconintra_neon.c", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/shortidct4x4llm_neon.c", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/sixtappredict_neon.c", "//third_party/libvpx_new/source/libvpx/vp8/common/arm/neon/vp8_loopfilter_neon.c", @@ -2097,6 +2094,7 @@ "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.c", + "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.h", "//third_party/libvpx_new/source/libvpx/vp8/common/rtcd.c", @@ -2456,6 +2454,7 @@ "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.c", + "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.h", "//third_party/libvpx_new/source/libvpx/vp8/common/rtcd.c", @@ -2779,6 +2778,7 @@ "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.c", + "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.h", "//third_party/libvpx_new/source/libvpx/vp8/common/rtcd.c", @@ -3100,6 +3100,7 @@ "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconinter.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.c", + "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra.h", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.c", "//third_party/libvpx_new/source/libvpx/vp8/common/reconintra4x4.h", "//third_party/libvpx_new/source/libvpx/vp8/common/rtcd.c",
diff --git a/third_party/libvpx_new/libvpx_srcs_arm.gypi b/third_party/libvpx_new/libvpx_srcs_arm.gypi index a5b97bd2..56de0933 100644 --- a/third_party/libvpx_new/libvpx_srcs_arm.gypi +++ b/third_party/libvpx_new/libvpx_srcs_arm.gypi
@@ -17,7 +17,6 @@ '<(libvpx_source)/vp8/common/arm/armv6/filter_v6.asm', '<(libvpx_source)/vp8/common/arm/armv6/idct_blk_v6.c', '<(libvpx_source)/vp8/common/arm/armv6/idct_v6.asm', - '<(libvpx_source)/vp8/common/arm/armv6/intra4x4_predict_v6.asm', '<(libvpx_source)/vp8/common/arm/armv6/iwalsh_v6.asm', '<(libvpx_source)/vp8/common/arm/armv6/loopfilter_v6.asm', '<(libvpx_source)/vp8/common/arm/armv6/simpleloopfilter_v6.asm', @@ -70,6 +69,7 @@ '<(libvpx_source)/vp8/common/reconinter.c', '<(libvpx_source)/vp8/common/reconinter.h', '<(libvpx_source)/vp8/common/reconintra.c', + '<(libvpx_source)/vp8/common/reconintra.h', '<(libvpx_source)/vp8/common/reconintra4x4.c', '<(libvpx_source)/vp8/common/reconintra4x4.h', '<(libvpx_source)/vp8/common/rtcd.c',
diff --git a/third_party/libvpx_new/libvpx_srcs_arm64.gypi b/third_party/libvpx_new/libvpx_srcs_arm64.gypi index 7d88bc5..28199b37 100644 --- a/third_party/libvpx_new/libvpx_srcs_arm64.gypi +++ b/third_party/libvpx_new/libvpx_srcs_arm64.gypi
@@ -22,7 +22,6 @@ '<(libvpx_source)/vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.c', '<(libvpx_source)/vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.c', '<(libvpx_source)/vp8/common/arm/neon/mbloopfilter_neon.c', - '<(libvpx_source)/vp8/common/arm/neon/reconintra_neon.c', '<(libvpx_source)/vp8/common/arm/neon/shortidct4x4llm_neon.c', '<(libvpx_source)/vp8/common/arm/neon/sixtappredict_neon.c', '<(libvpx_source)/vp8/common/arm/neon/vp8_loopfilter_neon.c', @@ -69,6 +68,7 @@ '<(libvpx_source)/vp8/common/reconinter.c', '<(libvpx_source)/vp8/common/reconinter.h', '<(libvpx_source)/vp8/common/reconintra.c', + '<(libvpx_source)/vp8/common/reconintra.h', '<(libvpx_source)/vp8/common/reconintra4x4.c', '<(libvpx_source)/vp8/common/reconintra4x4.h', '<(libvpx_source)/vp8/common/rtcd.c',
diff --git a/third_party/libvpx_new/libvpx_srcs_arm_neon.gypi b/third_party/libvpx_new/libvpx_srcs_arm_neon.gypi index 0e7d48d..0a9803f 100644 --- a/third_party/libvpx_new/libvpx_srcs_arm_neon.gypi +++ b/third_party/libvpx_new/libvpx_srcs_arm_neon.gypi
@@ -17,7 +17,6 @@ '<(libvpx_source)/vp8/common/arm/armv6/filter_v6.asm', '<(libvpx_source)/vp8/common/arm/armv6/idct_blk_v6.c', '<(libvpx_source)/vp8/common/arm/armv6/idct_v6.asm', - '<(libvpx_source)/vp8/common/arm/armv6/intra4x4_predict_v6.asm', '<(libvpx_source)/vp8/common/arm/armv6/iwalsh_v6.asm', '<(libvpx_source)/vp8/common/arm/armv6/loopfilter_v6.asm', '<(libvpx_source)/vp8/common/arm/armv6/simpleloopfilter_v6.asm', @@ -39,7 +38,6 @@ '<(libvpx_source)/vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.c', '<(libvpx_source)/vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.c', '<(libvpx_source)/vp8/common/arm/neon/mbloopfilter_neon.c', - '<(libvpx_source)/vp8/common/arm/neon/reconintra_neon.c', '<(libvpx_source)/vp8/common/arm/neon/shortidct4x4llm_neon.c', '<(libvpx_source)/vp8/common/arm/neon/sixtappredict_neon.c', '<(libvpx_source)/vp8/common/arm/neon/vp8_loopfilter_neon.c', @@ -86,6 +84,7 @@ '<(libvpx_source)/vp8/common/reconinter.c', '<(libvpx_source)/vp8/common/reconinter.h', '<(libvpx_source)/vp8/common/reconintra.c', + '<(libvpx_source)/vp8/common/reconintra.h', '<(libvpx_source)/vp8/common/reconintra4x4.c', '<(libvpx_source)/vp8/common/reconintra4x4.h', '<(libvpx_source)/vp8/common/rtcd.c',
diff --git a/third_party/libvpx_new/libvpx_srcs_arm_neon_cpu_detect.gypi b/third_party/libvpx_new/libvpx_srcs_arm_neon_cpu_detect.gypi index a5b97bd2..56de0933 100644 --- a/third_party/libvpx_new/libvpx_srcs_arm_neon_cpu_detect.gypi +++ b/third_party/libvpx_new/libvpx_srcs_arm_neon_cpu_detect.gypi
@@ -17,7 +17,6 @@ '<(libvpx_source)/vp8/common/arm/armv6/filter_v6.asm', '<(libvpx_source)/vp8/common/arm/armv6/idct_blk_v6.c', '<(libvpx_source)/vp8/common/arm/armv6/idct_v6.asm', - '<(libvpx_source)/vp8/common/arm/armv6/intra4x4_predict_v6.asm', '<(libvpx_source)/vp8/common/arm/armv6/iwalsh_v6.asm', '<(libvpx_source)/vp8/common/arm/armv6/loopfilter_v6.asm', '<(libvpx_source)/vp8/common/arm/armv6/simpleloopfilter_v6.asm', @@ -70,6 +69,7 @@ '<(libvpx_source)/vp8/common/reconinter.c', '<(libvpx_source)/vp8/common/reconinter.h', '<(libvpx_source)/vp8/common/reconintra.c', + '<(libvpx_source)/vp8/common/reconintra.h', '<(libvpx_source)/vp8/common/reconintra4x4.c', '<(libvpx_source)/vp8/common/reconintra4x4.h', '<(libvpx_source)/vp8/common/rtcd.c',
diff --git a/third_party/libvpx_new/libvpx_srcs_arm_neon_cpu_detect_intrinsics.gypi b/third_party/libvpx_new/libvpx_srcs_arm_neon_cpu_detect_intrinsics.gypi index 918dc3d..dcf6043 100644 --- a/third_party/libvpx_new/libvpx_srcs_arm_neon_cpu_detect_intrinsics.gypi +++ b/third_party/libvpx_new/libvpx_srcs_arm_neon_cpu_detect_intrinsics.gypi
@@ -25,7 +25,6 @@ '<(libvpx_source)/vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.c', '<(libvpx_source)/vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.c', '<(libvpx_source)/vp8/common/arm/neon/mbloopfilter_neon.c', - '<(libvpx_source)/vp8/common/arm/neon/reconintra_neon.c', '<(libvpx_source)/vp8/common/arm/neon/shortidct4x4llm_neon.c', '<(libvpx_source)/vp8/common/arm/neon/sixtappredict_neon.c', '<(libvpx_source)/vp8/common/arm/neon/vp8_loopfilter_neon.c',
diff --git a/third_party/libvpx_new/libvpx_srcs_generic.gypi b/third_party/libvpx_new/libvpx_srcs_generic.gypi index fbfe3f7..6ad20965 100644 --- a/third_party/libvpx_new/libvpx_srcs_generic.gypi +++ b/third_party/libvpx_new/libvpx_srcs_generic.gypi
@@ -50,6 +50,7 @@ '<(libvpx_source)/vp8/common/reconinter.c', '<(libvpx_source)/vp8/common/reconinter.h', '<(libvpx_source)/vp8/common/reconintra.c', + '<(libvpx_source)/vp8/common/reconintra.h', '<(libvpx_source)/vp8/common/reconintra4x4.c', '<(libvpx_source)/vp8/common/reconintra4x4.h', '<(libvpx_source)/vp8/common/rtcd.c',
diff --git a/third_party/libvpx_new/libvpx_srcs_mips.gypi b/third_party/libvpx_new/libvpx_srcs_mips.gypi index 6ec3373..ec42587 100644 --- a/third_party/libvpx_new/libvpx_srcs_mips.gypi +++ b/third_party/libvpx_new/libvpx_srcs_mips.gypi
@@ -50,6 +50,7 @@ '<(libvpx_source)/vp8/common/reconinter.c', '<(libvpx_source)/vp8/common/reconinter.h', '<(libvpx_source)/vp8/common/reconintra.c', + '<(libvpx_source)/vp8/common/reconintra.h', '<(libvpx_source)/vp8/common/reconintra4x4.c', '<(libvpx_source)/vp8/common/reconintra4x4.h', '<(libvpx_source)/vp8/common/rtcd.c',
diff --git a/third_party/libvpx_new/libvpx_srcs_nacl.gypi b/third_party/libvpx_new/libvpx_srcs_nacl.gypi index fbfe3f7..6ad20965 100644 --- a/third_party/libvpx_new/libvpx_srcs_nacl.gypi +++ b/third_party/libvpx_new/libvpx_srcs_nacl.gypi
@@ -50,6 +50,7 @@ '<(libvpx_source)/vp8/common/reconinter.c', '<(libvpx_source)/vp8/common/reconinter.h', '<(libvpx_source)/vp8/common/reconintra.c', + '<(libvpx_source)/vp8/common/reconintra.h', '<(libvpx_source)/vp8/common/reconintra4x4.c', '<(libvpx_source)/vp8/common/reconintra4x4.h', '<(libvpx_source)/vp8/common/rtcd.c',
diff --git a/third_party/libvpx_new/libvpx_srcs_x86.gypi b/third_party/libvpx_new/libvpx_srcs_x86.gypi index ffd6280..1616574 100644 --- a/third_party/libvpx_new/libvpx_srcs_x86.gypi +++ b/third_party/libvpx_new/libvpx_srcs_x86.gypi
@@ -50,6 +50,7 @@ '<(libvpx_source)/vp8/common/reconinter.c', '<(libvpx_source)/vp8/common/reconinter.h', '<(libvpx_source)/vp8/common/reconintra.c', + '<(libvpx_source)/vp8/common/reconintra.h', '<(libvpx_source)/vp8/common/reconintra4x4.c', '<(libvpx_source)/vp8/common/reconintra4x4.h', '<(libvpx_source)/vp8/common/rtcd.c',
diff --git a/third_party/libvpx_new/libvpx_srcs_x86_64.gypi b/third_party/libvpx_new/libvpx_srcs_x86_64.gypi index 18b5a02..bce3da4 100644 --- a/third_party/libvpx_new/libvpx_srcs_x86_64.gypi +++ b/third_party/libvpx_new/libvpx_srcs_x86_64.gypi
@@ -50,6 +50,7 @@ '<(libvpx_source)/vp8/common/reconinter.c', '<(libvpx_source)/vp8/common/reconinter.h', '<(libvpx_source)/vp8/common/reconintra.c', + '<(libvpx_source)/vp8/common/reconintra.h', '<(libvpx_source)/vp8/common/reconintra4x4.c', '<(libvpx_source)/vp8/common/reconintra4x4.h', '<(libvpx_source)/vp8/common/rtcd.c',
diff --git a/third_party/libvpx_new/libvpx_srcs_x86_64_intrinsics.gypi b/third_party/libvpx_new/libvpx_srcs_x86_64_intrinsics.gypi index 95fa0e7..881194e 100644 --- a/third_party/libvpx_new/libvpx_srcs_x86_64_intrinsics.gypi +++ b/third_party/libvpx_new/libvpx_srcs_x86_64_intrinsics.gypi
@@ -29,7 +29,6 @@ ], 'sources': [ '<(libvpx_source)/vp8/common/x86/idct_blk_sse2.c', - '<(libvpx_source)/vp8/common/x86/recon_wrapper_sse2.c', '<(libvpx_source)/vp8/encoder/x86/denoising_sse2.c', '<(libvpx_source)/vp8/encoder/x86/vp8_enc_stubs_sse2.c', '<(libvpx_source)/vp8/encoder/x86/vp8_quantize_sse2.c',
diff --git a/third_party/libvpx_new/libvpx_srcs_x86_intrinsics.gypi b/third_party/libvpx_new/libvpx_srcs_x86_intrinsics.gypi index 95fa0e7..881194e 100644 --- a/third_party/libvpx_new/libvpx_srcs_x86_intrinsics.gypi +++ b/third_party/libvpx_new/libvpx_srcs_x86_intrinsics.gypi
@@ -29,7 +29,6 @@ ], 'sources': [ '<(libvpx_source)/vp8/common/x86/idct_blk_sse2.c', - '<(libvpx_source)/vp8/common/x86/recon_wrapper_sse2.c', '<(libvpx_source)/vp8/encoder/x86/denoising_sse2.c', '<(libvpx_source)/vp8/encoder/x86/vp8_enc_stubs_sse2.c', '<(libvpx_source)/vp8/encoder/x86/vp8_quantize_sse2.c',
diff --git a/third_party/libvpx_new/source/config/linux/arm-neon-cpu-detect/vp8_rtcd.h b/third_party/libvpx_new/source/config/linux/arm-neon-cpu-detect/vp8_rtcd.h index a7c415d..c8b17eca 100644 --- a/third_party/libvpx_new/source/config/linux/arm-neon-cpu-detect/vp8_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/arm-neon-cpu-detect/vp8_rtcd.h
@@ -57,14 +57,6 @@ int vp8_block_error_c(short *coeff, short *dqcoeff); #define vp8_block_error vp8_block_error_c -void vp8_build_intra_predictors_mbuv_s_c(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -void vp8_build_intra_predictors_mbuv_s_neon(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -RTCD_EXTERN void (*vp8_build_intra_predictors_mbuv_s)(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); - -void vp8_build_intra_predictors_mby_s_c(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -void vp8_build_intra_predictors_mby_s_neon(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -RTCD_EXTERN void (*vp8_build_intra_predictors_mby_s)(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); - void vp8_clear_system_state_c(); #define vp8_clear_system_state vp8_clear_system_state_c @@ -135,10 +127,6 @@ int vp8_full_search_sad_c(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); #define vp8_full_search_sad vp8_full_search_sad_c -void vp8_intra4x4_predict_c(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -void vp8_intra4x4_predict_armv6(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -#define vp8_intra4x4_predict vp8_intra4x4_predict_armv6 - void vp8_loop_filter_bh_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_armv6(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_neon(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); @@ -268,10 +256,6 @@ if (flags & HAS_NEON) vp8_bilinear_predict8x4 = vp8_bilinear_predict8x4_neon; vp8_bilinear_predict8x8 = vp8_bilinear_predict8x8_armv6; if (flags & HAS_NEON) vp8_bilinear_predict8x8 = vp8_bilinear_predict8x8_neon; - vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_c; - if (flags & HAS_NEON) vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_neon; - vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_c; - if (flags & HAS_NEON) vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_neon; vp8_copy_mem16x16 = vp8_copy_mem16x16_v6; if (flags & HAS_NEON) vp8_copy_mem16x16 = vp8_copy_mem16x16_neon; vp8_copy_mem8x4 = vp8_copy_mem8x4_v6;
diff --git a/third_party/libvpx_new/source/config/linux/arm-neon-cpu-detect/vpx_dsp_rtcd.h b/third_party/libvpx_new/source/config/linux/arm-neon-cpu-detect/vpx_dsp_rtcd.h index 64fce3a..9919f64 100644 --- a/third_party/libvpx_new/source/config/linux/arm-neon-cpu-detect/vpx_dsp_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/arm-neon-cpu-detect/vpx_dsp_rtcd.h
@@ -118,6 +118,9 @@ void vpx_d45_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d45_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45e_predictor_4x4 vpx_d45e_predictor_4x4_c + void vpx_d63_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d63_predictor_16x16 vpx_d63_predictor_16x16_c @@ -130,6 +133,9 @@ void vpx_d63_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d63_predictor_8x8 vpx_d63_predictor_8x8_c +void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63e_predictor_4x4 vpx_d63e_predictor_4x4_c + void vpx_dc_128_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); void vpx_dc_128_predictor_16x16_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_dc_128_predictor_16x16)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); @@ -254,6 +260,9 @@ void vpx_h_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_h_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_he_predictor_4x4 vpx_he_predictor_4x4_c + void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, int dest_stride); void vpx_idct16x16_10_add_neon(const tran_low_t *input, uint8_t *dest, int dest_stride); RTCD_EXTERN void (*vpx_idct16x16_10_add)(const tran_low_t *input, uint8_t *dest, int dest_stride); @@ -743,6 +752,9 @@ uint32_t vpx_variance_halfpixvar16x16_v_media(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); #define vpx_variance_halfpixvar16x16_v vpx_variance_halfpixvar16x16_v_media +void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_ve_predictor_4x4 vpx_ve_predictor_4x4_c + void vpx_dsp_rtcd(void); #include "vpx_config.h"
diff --git a/third_party/libvpx_new/source/config/linux/arm-neon/vp8_rtcd.h b/third_party/libvpx_new/source/config/linux/arm-neon/vp8_rtcd.h index 17d17eb..4fba7a7 100644 --- a/third_party/libvpx_new/source/config/linux/arm-neon/vp8_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/arm-neon/vp8_rtcd.h
@@ -57,14 +57,6 @@ int vp8_block_error_c(short *coeff, short *dqcoeff); #define vp8_block_error vp8_block_error_c -void vp8_build_intra_predictors_mbuv_s_c(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -void vp8_build_intra_predictors_mbuv_s_neon(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -#define vp8_build_intra_predictors_mbuv_s vp8_build_intra_predictors_mbuv_s_neon - -void vp8_build_intra_predictors_mby_s_c(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -void vp8_build_intra_predictors_mby_s_neon(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -#define vp8_build_intra_predictors_mby_s vp8_build_intra_predictors_mby_s_neon - void vp8_clear_system_state_c(); #define vp8_clear_system_state vp8_clear_system_state_c @@ -135,10 +127,6 @@ int vp8_full_search_sad_c(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); #define vp8_full_search_sad vp8_full_search_sad_c -void vp8_intra4x4_predict_c(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -void vp8_intra4x4_predict_armv6(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -#define vp8_intra4x4_predict vp8_intra4x4_predict_armv6 - void vp8_loop_filter_bh_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_armv6(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_neon(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi);
diff --git a/third_party/libvpx_new/source/config/linux/arm-neon/vpx_dsp_rtcd.h b/third_party/libvpx_new/source/config/linux/arm-neon/vpx_dsp_rtcd.h index 4de075d..b618558a 100644 --- a/third_party/libvpx_new/source/config/linux/arm-neon/vpx_dsp_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/arm-neon/vpx_dsp_rtcd.h
@@ -118,6 +118,9 @@ void vpx_d45_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d45_predictor_8x8 vpx_d45_predictor_8x8_neon +void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45e_predictor_4x4 vpx_d45e_predictor_4x4_c + void vpx_d63_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d63_predictor_16x16 vpx_d63_predictor_16x16_c @@ -130,6 +133,9 @@ void vpx_d63_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d63_predictor_8x8 vpx_d63_predictor_8x8_c +void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63e_predictor_4x4 vpx_d63e_predictor_4x4_c + void vpx_dc_128_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); void vpx_dc_128_predictor_16x16_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_dc_128_predictor_16x16 vpx_dc_128_predictor_16x16_neon @@ -254,6 +260,9 @@ void vpx_h_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_h_predictor_8x8 vpx_h_predictor_8x8_neon +void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_he_predictor_4x4 vpx_he_predictor_4x4_c + void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, int dest_stride); void vpx_idct16x16_10_add_neon(const tran_low_t *input, uint8_t *dest, int dest_stride); #define vpx_idct16x16_10_add vpx_idct16x16_10_add_neon @@ -743,6 +752,9 @@ uint32_t vpx_variance_halfpixvar16x16_v_media(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); #define vpx_variance_halfpixvar16x16_v vpx_variance_halfpixvar16x16_v_media +void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_ve_predictor_4x4 vpx_ve_predictor_4x4_c + void vpx_dsp_rtcd(void); #include "vpx_config.h"
diff --git a/third_party/libvpx_new/source/config/linux/arm/vp8_rtcd.h b/third_party/libvpx_new/source/config/linux/arm/vp8_rtcd.h index 6cd65fb..20783d4 100644 --- a/third_party/libvpx_new/source/config/linux/arm/vp8_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/arm/vp8_rtcd.h
@@ -54,12 +54,6 @@ int vp8_block_error_c(short *coeff, short *dqcoeff); #define vp8_block_error vp8_block_error_c -void vp8_build_intra_predictors_mbuv_s_c(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -#define vp8_build_intra_predictors_mbuv_s vp8_build_intra_predictors_mbuv_s_c - -void vp8_build_intra_predictors_mby_s_c(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -#define vp8_build_intra_predictors_mby_s vp8_build_intra_predictors_mby_s_c - void vp8_clear_system_state_c(); #define vp8_clear_system_state vp8_clear_system_state_c @@ -119,10 +113,6 @@ int vp8_full_search_sad_c(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); #define vp8_full_search_sad vp8_full_search_sad_c -void vp8_intra4x4_predict_c(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -void vp8_intra4x4_predict_armv6(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -#define vp8_intra4x4_predict vp8_intra4x4_predict_armv6 - void vp8_loop_filter_bh_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_armv6(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); #define vp8_loop_filter_bh vp8_loop_filter_bh_armv6
diff --git a/third_party/libvpx_new/source/config/linux/arm/vpx_dsp_rtcd.h b/third_party/libvpx_new/source/config/linux/arm/vpx_dsp_rtcd.h index bb570a0..635357f 100644 --- a/third_party/libvpx_new/source/config/linux/arm/vpx_dsp_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/arm/vpx_dsp_rtcd.h
@@ -106,6 +106,9 @@ void vpx_d45_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d45_predictor_8x8 vpx_d45_predictor_8x8_c +void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45e_predictor_4x4 vpx_d45e_predictor_4x4_c + void vpx_d63_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d63_predictor_16x16 vpx_d63_predictor_16x16_c @@ -118,6 +121,9 @@ void vpx_d63_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d63_predictor_8x8 vpx_d63_predictor_8x8_c +void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63e_predictor_4x4 vpx_d63e_predictor_4x4_c + void vpx_dc_128_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_dc_128_predictor_16x16 vpx_dc_128_predictor_16x16_c @@ -217,6 +223,9 @@ void vpx_h_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_h_predictor_8x8 vpx_h_predictor_8x8_c +void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_he_predictor_4x4 vpx_he_predictor_4x4_c + void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, int dest_stride); #define vpx_idct16x16_10_add vpx_idct16x16_10_add_c @@ -652,6 +661,9 @@ uint32_t vpx_variance_halfpixvar16x16_v_media(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); #define vpx_variance_halfpixvar16x16_v vpx_variance_halfpixvar16x16_v_media +void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_ve_predictor_4x4 vpx_ve_predictor_4x4_c + void vpx_dsp_rtcd(void); #include "vpx_config.h"
diff --git a/third_party/libvpx_new/source/config/linux/arm64/vp8_rtcd.h b/third_party/libvpx_new/source/config/linux/arm64/vp8_rtcd.h index 74456fe0..0d421b6 100644 --- a/third_party/libvpx_new/source/config/linux/arm64/vp8_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/arm64/vp8_rtcd.h
@@ -53,14 +53,6 @@ int vp8_block_error_c(short *coeff, short *dqcoeff); #define vp8_block_error vp8_block_error_c -void vp8_build_intra_predictors_mbuv_s_c(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -void vp8_build_intra_predictors_mbuv_s_neon(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -#define vp8_build_intra_predictors_mbuv_s vp8_build_intra_predictors_mbuv_s_neon - -void vp8_build_intra_predictors_mby_s_c(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -void vp8_build_intra_predictors_mby_s_neon(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -#define vp8_build_intra_predictors_mby_s vp8_build_intra_predictors_mby_s_neon - void vp8_clear_system_state_c(); #define vp8_clear_system_state vp8_clear_system_state_c @@ -123,9 +115,6 @@ int vp8_full_search_sad_c(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); #define vp8_full_search_sad vp8_full_search_sad_c -void vp8_intra4x4_predict_c(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -#define vp8_intra4x4_predict vp8_intra4x4_predict_c - void vp8_loop_filter_bh_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_neon(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); #define vp8_loop_filter_bh vp8_loop_filter_bh_neon
diff --git a/third_party/libvpx_new/source/config/linux/arm64/vpx_dsp_rtcd.h b/third_party/libvpx_new/source/config/linux/arm64/vpx_dsp_rtcd.h index 2cac9e6..f93276b0 100644 --- a/third_party/libvpx_new/source/config/linux/arm64/vpx_dsp_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/arm64/vpx_dsp_rtcd.h
@@ -118,6 +118,9 @@ void vpx_d45_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d45_predictor_8x8 vpx_d45_predictor_8x8_neon +void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45e_predictor_4x4 vpx_d45e_predictor_4x4_c + void vpx_d63_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d63_predictor_16x16 vpx_d63_predictor_16x16_c @@ -130,6 +133,9 @@ void vpx_d63_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d63_predictor_8x8 vpx_d63_predictor_8x8_c +void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63e_predictor_4x4 vpx_d63e_predictor_4x4_c + void vpx_dc_128_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); void vpx_dc_128_predictor_16x16_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_dc_128_predictor_16x16 vpx_dc_128_predictor_16x16_neon @@ -254,6 +260,9 @@ void vpx_h_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_h_predictor_8x8 vpx_h_predictor_8x8_neon +void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_he_predictor_4x4 vpx_he_predictor_4x4_c + void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, int dest_stride); void vpx_idct16x16_10_add_neon(const tran_low_t *input, uint8_t *dest, int dest_stride); #define vpx_idct16x16_10_add vpx_idct16x16_10_add_neon @@ -728,6 +737,9 @@ uint32_t vpx_variance_halfpixvar16x16_v_c(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); #define vpx_variance_halfpixvar16x16_v vpx_variance_halfpixvar16x16_v_c +void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_ve_predictor_4x4 vpx_ve_predictor_4x4_c + void vpx_dsp_rtcd(void); #include "vpx_config.h"
diff --git a/third_party/libvpx_new/source/config/linux/generic/vp8_rtcd.h b/third_party/libvpx_new/source/config/linux/generic/vp8_rtcd.h index dc2834b..1697a30 100644 --- a/third_party/libvpx_new/source/config/linux/generic/vp8_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/generic/vp8_rtcd.h
@@ -50,12 +50,6 @@ int vp8_block_error_c(short *coeff, short *dqcoeff); #define vp8_block_error vp8_block_error_c -void vp8_build_intra_predictors_mbuv_s_c(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -#define vp8_build_intra_predictors_mbuv_s vp8_build_intra_predictors_mbuv_s_c - -void vp8_build_intra_predictors_mby_s_c(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -#define vp8_build_intra_predictors_mby_s vp8_build_intra_predictors_mby_s_c - void vp8_clear_system_state_c(); #define vp8_clear_system_state vp8_clear_system_state_c @@ -107,9 +101,6 @@ int vp8_full_search_sad_c(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); #define vp8_full_search_sad vp8_full_search_sad_c -void vp8_intra4x4_predict_c(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -#define vp8_intra4x4_predict vp8_intra4x4_predict_c - void vp8_loop_filter_bh_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); #define vp8_loop_filter_bh vp8_loop_filter_bh_c
diff --git a/third_party/libvpx_new/source/config/linux/generic/vpx_dsp_rtcd.h b/third_party/libvpx_new/source/config/linux/generic/vpx_dsp_rtcd.h index 010cbe7..14170f5 100644 --- a/third_party/libvpx_new/source/config/linux/generic/vpx_dsp_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/generic/vpx_dsp_rtcd.h
@@ -106,6 +106,9 @@ void vpx_d45_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d45_predictor_8x8 vpx_d45_predictor_8x8_c +void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45e_predictor_4x4 vpx_d45e_predictor_4x4_c + void vpx_d63_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d63_predictor_16x16 vpx_d63_predictor_16x16_c @@ -118,6 +121,9 @@ void vpx_d63_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d63_predictor_8x8 vpx_d63_predictor_8x8_c +void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63e_predictor_4x4 vpx_d63e_predictor_4x4_c + void vpx_dc_128_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_dc_128_predictor_16x16 vpx_dc_128_predictor_16x16_c @@ -217,6 +223,9 @@ void vpx_h_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_h_predictor_8x8 vpx_h_predictor_8x8_c +void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_he_predictor_4x4 vpx_he_predictor_4x4_c + void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, int dest_stride); #define vpx_idct16x16_10_add vpx_idct16x16_10_add_c @@ -643,6 +652,9 @@ uint32_t vpx_variance_halfpixvar16x16_v_c(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); #define vpx_variance_halfpixvar16x16_v vpx_variance_halfpixvar16x16_v_c +void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_ve_predictor_4x4 vpx_ve_predictor_4x4_c + void vpx_dsp_rtcd(void); #include "vpx_config.h"
diff --git a/third_party/libvpx_new/source/config/linux/ia32/vp8_rtcd.h b/third_party/libvpx_new/source/config/linux/ia32/vp8_rtcd.h index d08f0804..affac11 100644 --- a/third_party/libvpx_new/source/config/linux/ia32/vp8_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/ia32/vp8_rtcd.h
@@ -60,16 +60,6 @@ int vp8_block_error_xmm(short *coeff, short *dqcoeff); RTCD_EXTERN int (*vp8_block_error)(short *coeff, short *dqcoeff); -void vp8_build_intra_predictors_mbuv_s_c(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -void vp8_build_intra_predictors_mbuv_s_sse2(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -void vp8_build_intra_predictors_mbuv_s_ssse3(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -RTCD_EXTERN void (*vp8_build_intra_predictors_mbuv_s)(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); - -void vp8_build_intra_predictors_mby_s_c(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -void vp8_build_intra_predictors_mby_s_sse2(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -void vp8_build_intra_predictors_mby_s_ssse3(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -RTCD_EXTERN void (*vp8_build_intra_predictors_mby_s)(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); - void vp8_clear_system_state_c(); void vpx_reset_mmx_state(); RTCD_EXTERN void (*vp8_clear_system_state)(); @@ -147,9 +137,6 @@ int vp8_full_search_sadx8(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); RTCD_EXTERN int (*vp8_full_search_sad)(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); -void vp8_intra4x4_predict_c(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -#define vp8_intra4x4_predict vp8_intra4x4_predict_c - void vp8_loop_filter_bh_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_mmx(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_sse2(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); @@ -301,12 +288,6 @@ vp8_block_error = vp8_block_error_c; if (flags & HAS_MMX) vp8_block_error = vp8_block_error_mmx; if (flags & HAS_SSE2) vp8_block_error = vp8_block_error_xmm; - vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_c; - if (flags & HAS_SSE2) vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_sse2; - if (flags & HAS_SSSE3) vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_ssse3; - vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_c; - if (flags & HAS_SSE2) vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_sse2; - if (flags & HAS_SSSE3) vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_ssse3; vp8_clear_system_state = vp8_clear_system_state_c; if (flags & HAS_MMX) vp8_clear_system_state = vpx_reset_mmx_state; vp8_copy32xn = vp8_copy32xn_c;
diff --git a/third_party/libvpx_new/source/config/linux/ia32/vpx_dsp_rtcd.h b/third_party/libvpx_new/source/config/linux/ia32/vpx_dsp_rtcd.h index 8f0da9d..f529afb 100644 --- a/third_party/libvpx_new/source/config/linux/ia32/vpx_dsp_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/ia32/vpx_dsp_rtcd.h
@@ -135,6 +135,9 @@ void vpx_d45_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d45_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45e_predictor_4x4 vpx_d45e_predictor_4x4_c + void vpx_d63_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); void vpx_d63_predictor_16x16_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d63_predictor_16x16)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); @@ -151,6 +154,9 @@ void vpx_d63_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d63_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63e_predictor_4x4 vpx_d63e_predictor_4x4_c + void vpx_dc_128_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); void vpx_dc_128_predictor_16x16_sse2(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_dc_128_predictor_16x16)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); @@ -287,6 +293,9 @@ void vpx_h_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_h_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_he_predictor_4x4 vpx_he_predictor_4x4_c + void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, int dest_stride); void vpx_idct16x16_10_add_sse2(const tran_low_t *input, uint8_t *dest, int dest_stride); RTCD_EXTERN void (*vpx_idct16x16_10_add)(const tran_low_t *input, uint8_t *dest, int dest_stride); @@ -911,6 +920,9 @@ uint32_t vpx_variance_halfpixvar16x16_v_sse2(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); RTCD_EXTERN uint32_t (*vpx_variance_halfpixvar16x16_v)(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); +void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_ve_predictor_4x4 vpx_ve_predictor_4x4_c + void vpx_dsp_rtcd(void); #ifdef RTCD_C
diff --git a/third_party/libvpx_new/source/config/linux/mips64el/vp8_rtcd.h b/third_party/libvpx_new/source/config/linux/mips64el/vp8_rtcd.h index a023cfa..b7ee61ada 100644 --- a/third_party/libvpx_new/source/config/linux/mips64el/vp8_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/mips64el/vp8_rtcd.h
@@ -50,12 +50,6 @@ int vp8_block_error_c(short *coeff, short *dqcoeff); #define vp8_block_error vp8_block_error_c -void vp8_build_intra_predictors_mbuv_s_c(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -#define vp8_build_intra_predictors_mbuv_s vp8_build_intra_predictors_mbuv_s_c - -void vp8_build_intra_predictors_mby_s_c(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -#define vp8_build_intra_predictors_mby_s vp8_build_intra_predictors_mby_s_c - void vp8_clear_system_state_c(); #define vp8_clear_system_state vp8_clear_system_state_c @@ -107,9 +101,6 @@ int vp8_full_search_sad_c(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); #define vp8_full_search_sad vp8_full_search_sad_c -void vp8_intra4x4_predict_c(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -#define vp8_intra4x4_predict vp8_intra4x4_predict_c - void vp8_loop_filter_bh_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); #define vp8_loop_filter_bh vp8_loop_filter_bh_c
diff --git a/third_party/libvpx_new/source/config/linux/mips64el/vpx_dsp_rtcd.h b/third_party/libvpx_new/source/config/linux/mips64el/vpx_dsp_rtcd.h index 010cbe7..14170f5 100644 --- a/third_party/libvpx_new/source/config/linux/mips64el/vpx_dsp_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/mips64el/vpx_dsp_rtcd.h
@@ -106,6 +106,9 @@ void vpx_d45_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d45_predictor_8x8 vpx_d45_predictor_8x8_c +void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45e_predictor_4x4 vpx_d45e_predictor_4x4_c + void vpx_d63_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d63_predictor_16x16 vpx_d63_predictor_16x16_c @@ -118,6 +121,9 @@ void vpx_d63_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d63_predictor_8x8 vpx_d63_predictor_8x8_c +void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63e_predictor_4x4 vpx_d63e_predictor_4x4_c + void vpx_dc_128_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_dc_128_predictor_16x16 vpx_dc_128_predictor_16x16_c @@ -217,6 +223,9 @@ void vpx_h_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_h_predictor_8x8 vpx_h_predictor_8x8_c +void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_he_predictor_4x4 vpx_he_predictor_4x4_c + void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, int dest_stride); #define vpx_idct16x16_10_add vpx_idct16x16_10_add_c @@ -643,6 +652,9 @@ uint32_t vpx_variance_halfpixvar16x16_v_c(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); #define vpx_variance_halfpixvar16x16_v vpx_variance_halfpixvar16x16_v_c +void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_ve_predictor_4x4 vpx_ve_predictor_4x4_c + void vpx_dsp_rtcd(void); #include "vpx_config.h"
diff --git a/third_party/libvpx_new/source/config/linux/mipsel/vp8_rtcd.h b/third_party/libvpx_new/source/config/linux/mipsel/vp8_rtcd.h index a023cfa..b7ee61ada 100644 --- a/third_party/libvpx_new/source/config/linux/mipsel/vp8_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/mipsel/vp8_rtcd.h
@@ -50,12 +50,6 @@ int vp8_block_error_c(short *coeff, short *dqcoeff); #define vp8_block_error vp8_block_error_c -void vp8_build_intra_predictors_mbuv_s_c(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -#define vp8_build_intra_predictors_mbuv_s vp8_build_intra_predictors_mbuv_s_c - -void vp8_build_intra_predictors_mby_s_c(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -#define vp8_build_intra_predictors_mby_s vp8_build_intra_predictors_mby_s_c - void vp8_clear_system_state_c(); #define vp8_clear_system_state vp8_clear_system_state_c @@ -107,9 +101,6 @@ int vp8_full_search_sad_c(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); #define vp8_full_search_sad vp8_full_search_sad_c -void vp8_intra4x4_predict_c(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -#define vp8_intra4x4_predict vp8_intra4x4_predict_c - void vp8_loop_filter_bh_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); #define vp8_loop_filter_bh vp8_loop_filter_bh_c
diff --git a/third_party/libvpx_new/source/config/linux/mipsel/vpx_dsp_rtcd.h b/third_party/libvpx_new/source/config/linux/mipsel/vpx_dsp_rtcd.h index 010cbe7..14170f5 100644 --- a/third_party/libvpx_new/source/config/linux/mipsel/vpx_dsp_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/mipsel/vpx_dsp_rtcd.h
@@ -106,6 +106,9 @@ void vpx_d45_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d45_predictor_8x8 vpx_d45_predictor_8x8_c +void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45e_predictor_4x4 vpx_d45e_predictor_4x4_c + void vpx_d63_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d63_predictor_16x16 vpx_d63_predictor_16x16_c @@ -118,6 +121,9 @@ void vpx_d63_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d63_predictor_8x8 vpx_d63_predictor_8x8_c +void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63e_predictor_4x4 vpx_d63e_predictor_4x4_c + void vpx_dc_128_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_dc_128_predictor_16x16 vpx_dc_128_predictor_16x16_c @@ -217,6 +223,9 @@ void vpx_h_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_h_predictor_8x8 vpx_h_predictor_8x8_c +void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_he_predictor_4x4 vpx_he_predictor_4x4_c + void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, int dest_stride); #define vpx_idct16x16_10_add vpx_idct16x16_10_add_c @@ -643,6 +652,9 @@ uint32_t vpx_variance_halfpixvar16x16_v_c(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); #define vpx_variance_halfpixvar16x16_v vpx_variance_halfpixvar16x16_v_c +void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_ve_predictor_4x4 vpx_ve_predictor_4x4_c + void vpx_dsp_rtcd(void); #include "vpx_config.h"
diff --git a/third_party/libvpx_new/source/config/linux/x64/vp8_rtcd.h b/third_party/libvpx_new/source/config/linux/x64/vp8_rtcd.h index ff9ac9f..7ff11f92 100644 --- a/third_party/libvpx_new/source/config/linux/x64/vp8_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/x64/vp8_rtcd.h
@@ -60,16 +60,6 @@ int vp8_block_error_xmm(short *coeff, short *dqcoeff); #define vp8_block_error vp8_block_error_xmm -void vp8_build_intra_predictors_mbuv_s_c(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -void vp8_build_intra_predictors_mbuv_s_sse2(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -void vp8_build_intra_predictors_mbuv_s_ssse3(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -RTCD_EXTERN void (*vp8_build_intra_predictors_mbuv_s)(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); - -void vp8_build_intra_predictors_mby_s_c(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -void vp8_build_intra_predictors_mby_s_sse2(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -void vp8_build_intra_predictors_mby_s_ssse3(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -RTCD_EXTERN void (*vp8_build_intra_predictors_mby_s)(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); - void vp8_clear_system_state_c(); void vpx_reset_mmx_state(); #define vp8_clear_system_state vpx_reset_mmx_state @@ -147,9 +137,6 @@ int vp8_full_search_sadx8(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); RTCD_EXTERN int (*vp8_full_search_sad)(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); -void vp8_intra4x4_predict_c(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -#define vp8_intra4x4_predict vp8_intra4x4_predict_c - void vp8_loop_filter_bh_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_mmx(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_sse2(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); @@ -290,10 +277,6 @@ if (flags & HAS_SSSE3) vp8_bilinear_predict16x16 = vp8_bilinear_predict16x16_ssse3; vp8_bilinear_predict8x8 = vp8_bilinear_predict8x8_sse2; if (flags & HAS_SSSE3) vp8_bilinear_predict8x8 = vp8_bilinear_predict8x8_ssse3; - vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_sse2; - if (flags & HAS_SSSE3) vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_ssse3; - vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_sse2; - if (flags & HAS_SSSE3) vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_ssse3; vp8_copy32xn = vp8_copy32xn_sse2; if (flags & HAS_SSE3) vp8_copy32xn = vp8_copy32xn_sse3; vp8_diamond_search_sad = vp8_diamond_search_sad_c;
diff --git a/third_party/libvpx_new/source/config/linux/x64/vpx_dsp_rtcd.h b/third_party/libvpx_new/source/config/linux/x64/vpx_dsp_rtcd.h index 7cf74d2..a2da40af 100644 --- a/third_party/libvpx_new/source/config/linux/x64/vpx_dsp_rtcd.h +++ b/third_party/libvpx_new/source/config/linux/x64/vpx_dsp_rtcd.h
@@ -135,6 +135,9 @@ void vpx_d45_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d45_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45e_predictor_4x4 vpx_d45e_predictor_4x4_c + void vpx_d63_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); void vpx_d63_predictor_16x16_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d63_predictor_16x16)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); @@ -151,6 +154,9 @@ void vpx_d63_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d63_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63e_predictor_4x4 vpx_d63e_predictor_4x4_c + void vpx_dc_128_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); void vpx_dc_128_predictor_16x16_sse2(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_dc_128_predictor_16x16 vpx_dc_128_predictor_16x16_sse2 @@ -288,6 +294,9 @@ void vpx_h_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_h_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_he_predictor_4x4 vpx_he_predictor_4x4_c + void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, int dest_stride); void vpx_idct16x16_10_add_sse2(const tran_low_t *input, uint8_t *dest, int dest_stride); #define vpx_idct16x16_10_add vpx_idct16x16_10_add_sse2 @@ -917,6 +926,9 @@ uint32_t vpx_variance_halfpixvar16x16_v_sse2(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); #define vpx_variance_halfpixvar16x16_v vpx_variance_halfpixvar16x16_v_sse2 +void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_ve_predictor_4x4 vpx_ve_predictor_4x4_c + void vpx_dsp_rtcd(void); #ifdef RTCD_C
diff --git a/third_party/libvpx_new/source/config/mac/ia32/vp8_rtcd.h b/third_party/libvpx_new/source/config/mac/ia32/vp8_rtcd.h index d08f0804..affac11 100644 --- a/third_party/libvpx_new/source/config/mac/ia32/vp8_rtcd.h +++ b/third_party/libvpx_new/source/config/mac/ia32/vp8_rtcd.h
@@ -60,16 +60,6 @@ int vp8_block_error_xmm(short *coeff, short *dqcoeff); RTCD_EXTERN int (*vp8_block_error)(short *coeff, short *dqcoeff); -void vp8_build_intra_predictors_mbuv_s_c(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -void vp8_build_intra_predictors_mbuv_s_sse2(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -void vp8_build_intra_predictors_mbuv_s_ssse3(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -RTCD_EXTERN void (*vp8_build_intra_predictors_mbuv_s)(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); - -void vp8_build_intra_predictors_mby_s_c(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -void vp8_build_intra_predictors_mby_s_sse2(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -void vp8_build_intra_predictors_mby_s_ssse3(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -RTCD_EXTERN void (*vp8_build_intra_predictors_mby_s)(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); - void vp8_clear_system_state_c(); void vpx_reset_mmx_state(); RTCD_EXTERN void (*vp8_clear_system_state)(); @@ -147,9 +137,6 @@ int vp8_full_search_sadx8(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); RTCD_EXTERN int (*vp8_full_search_sad)(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); -void vp8_intra4x4_predict_c(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -#define vp8_intra4x4_predict vp8_intra4x4_predict_c - void vp8_loop_filter_bh_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_mmx(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_sse2(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); @@ -301,12 +288,6 @@ vp8_block_error = vp8_block_error_c; if (flags & HAS_MMX) vp8_block_error = vp8_block_error_mmx; if (flags & HAS_SSE2) vp8_block_error = vp8_block_error_xmm; - vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_c; - if (flags & HAS_SSE2) vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_sse2; - if (flags & HAS_SSSE3) vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_ssse3; - vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_c; - if (flags & HAS_SSE2) vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_sse2; - if (flags & HAS_SSSE3) vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_ssse3; vp8_clear_system_state = vp8_clear_system_state_c; if (flags & HAS_MMX) vp8_clear_system_state = vpx_reset_mmx_state; vp8_copy32xn = vp8_copy32xn_c;
diff --git a/third_party/libvpx_new/source/config/mac/ia32/vpx_dsp_rtcd.h b/third_party/libvpx_new/source/config/mac/ia32/vpx_dsp_rtcd.h index 8f0da9d..f529afb 100644 --- a/third_party/libvpx_new/source/config/mac/ia32/vpx_dsp_rtcd.h +++ b/third_party/libvpx_new/source/config/mac/ia32/vpx_dsp_rtcd.h
@@ -135,6 +135,9 @@ void vpx_d45_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d45_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45e_predictor_4x4 vpx_d45e_predictor_4x4_c + void vpx_d63_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); void vpx_d63_predictor_16x16_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d63_predictor_16x16)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); @@ -151,6 +154,9 @@ void vpx_d63_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d63_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63e_predictor_4x4 vpx_d63e_predictor_4x4_c + void vpx_dc_128_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); void vpx_dc_128_predictor_16x16_sse2(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_dc_128_predictor_16x16)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); @@ -287,6 +293,9 @@ void vpx_h_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_h_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_he_predictor_4x4 vpx_he_predictor_4x4_c + void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, int dest_stride); void vpx_idct16x16_10_add_sse2(const tran_low_t *input, uint8_t *dest, int dest_stride); RTCD_EXTERN void (*vpx_idct16x16_10_add)(const tran_low_t *input, uint8_t *dest, int dest_stride); @@ -911,6 +920,9 @@ uint32_t vpx_variance_halfpixvar16x16_v_sse2(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); RTCD_EXTERN uint32_t (*vpx_variance_halfpixvar16x16_v)(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); +void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_ve_predictor_4x4 vpx_ve_predictor_4x4_c + void vpx_dsp_rtcd(void); #ifdef RTCD_C
diff --git a/third_party/libvpx_new/source/config/mac/x64/vp8_rtcd.h b/third_party/libvpx_new/source/config/mac/x64/vp8_rtcd.h index ff9ac9f..7ff11f92 100644 --- a/third_party/libvpx_new/source/config/mac/x64/vp8_rtcd.h +++ b/third_party/libvpx_new/source/config/mac/x64/vp8_rtcd.h
@@ -60,16 +60,6 @@ int vp8_block_error_xmm(short *coeff, short *dqcoeff); #define vp8_block_error vp8_block_error_xmm -void vp8_build_intra_predictors_mbuv_s_c(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -void vp8_build_intra_predictors_mbuv_s_sse2(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -void vp8_build_intra_predictors_mbuv_s_ssse3(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -RTCD_EXTERN void (*vp8_build_intra_predictors_mbuv_s)(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); - -void vp8_build_intra_predictors_mby_s_c(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -void vp8_build_intra_predictors_mby_s_sse2(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -void vp8_build_intra_predictors_mby_s_ssse3(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -RTCD_EXTERN void (*vp8_build_intra_predictors_mby_s)(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); - void vp8_clear_system_state_c(); void vpx_reset_mmx_state(); #define vp8_clear_system_state vpx_reset_mmx_state @@ -147,9 +137,6 @@ int vp8_full_search_sadx8(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); RTCD_EXTERN int (*vp8_full_search_sad)(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); -void vp8_intra4x4_predict_c(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -#define vp8_intra4x4_predict vp8_intra4x4_predict_c - void vp8_loop_filter_bh_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_mmx(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_sse2(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); @@ -290,10 +277,6 @@ if (flags & HAS_SSSE3) vp8_bilinear_predict16x16 = vp8_bilinear_predict16x16_ssse3; vp8_bilinear_predict8x8 = vp8_bilinear_predict8x8_sse2; if (flags & HAS_SSSE3) vp8_bilinear_predict8x8 = vp8_bilinear_predict8x8_ssse3; - vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_sse2; - if (flags & HAS_SSSE3) vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_ssse3; - vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_sse2; - if (flags & HAS_SSSE3) vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_ssse3; vp8_copy32xn = vp8_copy32xn_sse2; if (flags & HAS_SSE3) vp8_copy32xn = vp8_copy32xn_sse3; vp8_diamond_search_sad = vp8_diamond_search_sad_c;
diff --git a/third_party/libvpx_new/source/config/mac/x64/vpx_dsp_rtcd.h b/third_party/libvpx_new/source/config/mac/x64/vpx_dsp_rtcd.h index 7cf74d2..a2da40af 100644 --- a/third_party/libvpx_new/source/config/mac/x64/vpx_dsp_rtcd.h +++ b/third_party/libvpx_new/source/config/mac/x64/vpx_dsp_rtcd.h
@@ -135,6 +135,9 @@ void vpx_d45_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d45_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45e_predictor_4x4 vpx_d45e_predictor_4x4_c + void vpx_d63_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); void vpx_d63_predictor_16x16_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d63_predictor_16x16)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); @@ -151,6 +154,9 @@ void vpx_d63_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d63_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63e_predictor_4x4 vpx_d63e_predictor_4x4_c + void vpx_dc_128_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); void vpx_dc_128_predictor_16x16_sse2(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_dc_128_predictor_16x16 vpx_dc_128_predictor_16x16_sse2 @@ -288,6 +294,9 @@ void vpx_h_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_h_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_he_predictor_4x4 vpx_he_predictor_4x4_c + void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, int dest_stride); void vpx_idct16x16_10_add_sse2(const tran_low_t *input, uint8_t *dest, int dest_stride); #define vpx_idct16x16_10_add vpx_idct16x16_10_add_sse2 @@ -917,6 +926,9 @@ uint32_t vpx_variance_halfpixvar16x16_v_sse2(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); #define vpx_variance_halfpixvar16x16_v vpx_variance_halfpixvar16x16_v_sse2 +void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_ve_predictor_4x4 vpx_ve_predictor_4x4_c + void vpx_dsp_rtcd(void); #ifdef RTCD_C
diff --git a/third_party/libvpx_new/source/config/nacl/vp8_rtcd.h b/third_party/libvpx_new/source/config/nacl/vp8_rtcd.h index dc2834b..1697a30 100644 --- a/third_party/libvpx_new/source/config/nacl/vp8_rtcd.h +++ b/third_party/libvpx_new/source/config/nacl/vp8_rtcd.h
@@ -50,12 +50,6 @@ int vp8_block_error_c(short *coeff, short *dqcoeff); #define vp8_block_error vp8_block_error_c -void vp8_build_intra_predictors_mbuv_s_c(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -#define vp8_build_intra_predictors_mbuv_s vp8_build_intra_predictors_mbuv_s_c - -void vp8_build_intra_predictors_mby_s_c(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -#define vp8_build_intra_predictors_mby_s vp8_build_intra_predictors_mby_s_c - void vp8_clear_system_state_c(); #define vp8_clear_system_state vp8_clear_system_state_c @@ -107,9 +101,6 @@ int vp8_full_search_sad_c(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); #define vp8_full_search_sad vp8_full_search_sad_c -void vp8_intra4x4_predict_c(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -#define vp8_intra4x4_predict vp8_intra4x4_predict_c - void vp8_loop_filter_bh_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); #define vp8_loop_filter_bh vp8_loop_filter_bh_c
diff --git a/third_party/libvpx_new/source/config/nacl/vpx_dsp_rtcd.h b/third_party/libvpx_new/source/config/nacl/vpx_dsp_rtcd.h index 010cbe7..14170f5 100644 --- a/third_party/libvpx_new/source/config/nacl/vpx_dsp_rtcd.h +++ b/third_party/libvpx_new/source/config/nacl/vpx_dsp_rtcd.h
@@ -106,6 +106,9 @@ void vpx_d45_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d45_predictor_8x8 vpx_d45_predictor_8x8_c +void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45e_predictor_4x4 vpx_d45e_predictor_4x4_c + void vpx_d63_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d63_predictor_16x16 vpx_d63_predictor_16x16_c @@ -118,6 +121,9 @@ void vpx_d63_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_d63_predictor_8x8 vpx_d63_predictor_8x8_c +void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63e_predictor_4x4 vpx_d63e_predictor_4x4_c + void vpx_dc_128_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_dc_128_predictor_16x16 vpx_dc_128_predictor_16x16_c @@ -217,6 +223,9 @@ void vpx_h_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_h_predictor_8x8 vpx_h_predictor_8x8_c +void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_he_predictor_4x4 vpx_he_predictor_4x4_c + void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, int dest_stride); #define vpx_idct16x16_10_add vpx_idct16x16_10_add_c @@ -643,6 +652,9 @@ uint32_t vpx_variance_halfpixvar16x16_v_c(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); #define vpx_variance_halfpixvar16x16_v vpx_variance_halfpixvar16x16_v_c +void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_ve_predictor_4x4 vpx_ve_predictor_4x4_c + void vpx_dsp_rtcd(void); #include "vpx_config.h"
diff --git a/third_party/libvpx_new/source/config/vpx_version.h b/third_party/libvpx_new/source/config/vpx_version.h index 2752f2d..cf95c13 100644 --- a/third_party/libvpx_new/source/config/vpx_version.h +++ b/third_party/libvpx_new/source/config/vpx_version.h
@@ -1,7 +1,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 4 #define VERSION_PATCH 0 -#define VERSION_EXTRA "1410-g7d28d12" +#define VERSION_EXTRA "1466-gce3f4ad" #define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH)) -#define VERSION_STRING_NOSP "v1.4.0-1410-g7d28d12" -#define VERSION_STRING " v1.4.0-1410-g7d28d12" +#define VERSION_STRING_NOSP "v1.4.0-1466-gce3f4ad" +#define VERSION_STRING " v1.4.0-1466-gce3f4ad"
diff --git a/third_party/libvpx_new/source/config/win/ia32/vp8_rtcd.h b/third_party/libvpx_new/source/config/win/ia32/vp8_rtcd.h index d08f0804..affac11 100644 --- a/third_party/libvpx_new/source/config/win/ia32/vp8_rtcd.h +++ b/third_party/libvpx_new/source/config/win/ia32/vp8_rtcd.h
@@ -60,16 +60,6 @@ int vp8_block_error_xmm(short *coeff, short *dqcoeff); RTCD_EXTERN int (*vp8_block_error)(short *coeff, short *dqcoeff); -void vp8_build_intra_predictors_mbuv_s_c(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -void vp8_build_intra_predictors_mbuv_s_sse2(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -void vp8_build_intra_predictors_mbuv_s_ssse3(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -RTCD_EXTERN void (*vp8_build_intra_predictors_mbuv_s)(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); - -void vp8_build_intra_predictors_mby_s_c(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -void vp8_build_intra_predictors_mby_s_sse2(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -void vp8_build_intra_predictors_mby_s_ssse3(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -RTCD_EXTERN void (*vp8_build_intra_predictors_mby_s)(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); - void vp8_clear_system_state_c(); void vpx_reset_mmx_state(); RTCD_EXTERN void (*vp8_clear_system_state)(); @@ -147,9 +137,6 @@ int vp8_full_search_sadx8(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); RTCD_EXTERN int (*vp8_full_search_sad)(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); -void vp8_intra4x4_predict_c(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -#define vp8_intra4x4_predict vp8_intra4x4_predict_c - void vp8_loop_filter_bh_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_mmx(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_sse2(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); @@ -301,12 +288,6 @@ vp8_block_error = vp8_block_error_c; if (flags & HAS_MMX) vp8_block_error = vp8_block_error_mmx; if (flags & HAS_SSE2) vp8_block_error = vp8_block_error_xmm; - vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_c; - if (flags & HAS_SSE2) vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_sse2; - if (flags & HAS_SSSE3) vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_ssse3; - vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_c; - if (flags & HAS_SSE2) vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_sse2; - if (flags & HAS_SSSE3) vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_ssse3; vp8_clear_system_state = vp8_clear_system_state_c; if (flags & HAS_MMX) vp8_clear_system_state = vpx_reset_mmx_state; vp8_copy32xn = vp8_copy32xn_c;
diff --git a/third_party/libvpx_new/source/config/win/ia32/vpx_dsp_rtcd.h b/third_party/libvpx_new/source/config/win/ia32/vpx_dsp_rtcd.h index 8f0da9d..f529afb 100644 --- a/third_party/libvpx_new/source/config/win/ia32/vpx_dsp_rtcd.h +++ b/third_party/libvpx_new/source/config/win/ia32/vpx_dsp_rtcd.h
@@ -135,6 +135,9 @@ void vpx_d45_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d45_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45e_predictor_4x4 vpx_d45e_predictor_4x4_c + void vpx_d63_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); void vpx_d63_predictor_16x16_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d63_predictor_16x16)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); @@ -151,6 +154,9 @@ void vpx_d63_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d63_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63e_predictor_4x4 vpx_d63e_predictor_4x4_c + void vpx_dc_128_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); void vpx_dc_128_predictor_16x16_sse2(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_dc_128_predictor_16x16)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); @@ -287,6 +293,9 @@ void vpx_h_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_h_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_he_predictor_4x4 vpx_he_predictor_4x4_c + void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, int dest_stride); void vpx_idct16x16_10_add_sse2(const tran_low_t *input, uint8_t *dest, int dest_stride); RTCD_EXTERN void (*vpx_idct16x16_10_add)(const tran_low_t *input, uint8_t *dest, int dest_stride); @@ -911,6 +920,9 @@ uint32_t vpx_variance_halfpixvar16x16_v_sse2(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); RTCD_EXTERN uint32_t (*vpx_variance_halfpixvar16x16_v)(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); +void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_ve_predictor_4x4 vpx_ve_predictor_4x4_c + void vpx_dsp_rtcd(void); #ifdef RTCD_C
diff --git a/third_party/libvpx_new/source/config/win/x64/vp8_rtcd.h b/third_party/libvpx_new/source/config/win/x64/vp8_rtcd.h index ff9ac9f..7ff11f92 100644 --- a/third_party/libvpx_new/source/config/win/x64/vp8_rtcd.h +++ b/third_party/libvpx_new/source/config/win/x64/vp8_rtcd.h
@@ -60,16 +60,6 @@ int vp8_block_error_xmm(short *coeff, short *dqcoeff); #define vp8_block_error vp8_block_error_xmm -void vp8_build_intra_predictors_mbuv_s_c(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -void vp8_build_intra_predictors_mbuv_s_sse2(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -void vp8_build_intra_predictors_mbuv_s_ssse3(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); -RTCD_EXTERN void (*vp8_build_intra_predictors_mbuv_s)(struct macroblockd *x, unsigned char * uabove_row, unsigned char * vabove_row, unsigned char *uleft, unsigned char *vleft, int left_stride, unsigned char * upred_ptr, unsigned char * vpred_ptr, int pred_stride); - -void vp8_build_intra_predictors_mby_s_c(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -void vp8_build_intra_predictors_mby_s_sse2(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -void vp8_build_intra_predictors_mby_s_ssse3(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); -RTCD_EXTERN void (*vp8_build_intra_predictors_mby_s)(struct macroblockd *x, unsigned char * yabove_row, unsigned char * yleft, int left_stride, unsigned char * ypred_ptr, int y_stride); - void vp8_clear_system_state_c(); void vpx_reset_mmx_state(); #define vp8_clear_system_state vpx_reset_mmx_state @@ -147,9 +137,6 @@ int vp8_full_search_sadx8(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); RTCD_EXTERN int (*vp8_full_search_sad)(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); -void vp8_intra4x4_predict_c(unsigned char *Above, unsigned char *yleft, int left_stride, int b_mode, unsigned char *dst, int dst_stride, unsigned char top_left); -#define vp8_intra4x4_predict vp8_intra4x4_predict_c - void vp8_loop_filter_bh_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_mmx(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); void vp8_loop_filter_bh_sse2(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); @@ -290,10 +277,6 @@ if (flags & HAS_SSSE3) vp8_bilinear_predict16x16 = vp8_bilinear_predict16x16_ssse3; vp8_bilinear_predict8x8 = vp8_bilinear_predict8x8_sse2; if (flags & HAS_SSSE3) vp8_bilinear_predict8x8 = vp8_bilinear_predict8x8_ssse3; - vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_sse2; - if (flags & HAS_SSSE3) vp8_build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s_ssse3; - vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_sse2; - if (flags & HAS_SSSE3) vp8_build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s_ssse3; vp8_copy32xn = vp8_copy32xn_sse2; if (flags & HAS_SSE3) vp8_copy32xn = vp8_copy32xn_sse3; vp8_diamond_search_sad = vp8_diamond_search_sad_c;
diff --git a/third_party/libvpx_new/source/config/win/x64/vpx_dsp_rtcd.h b/third_party/libvpx_new/source/config/win/x64/vpx_dsp_rtcd.h index 7cf74d2..a2da40af 100644 --- a/third_party/libvpx_new/source/config/win/x64/vpx_dsp_rtcd.h +++ b/third_party/libvpx_new/source/config/win/x64/vpx_dsp_rtcd.h
@@ -135,6 +135,9 @@ void vpx_d45_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d45_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45e_predictor_4x4 vpx_d45e_predictor_4x4_c + void vpx_d63_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); void vpx_d63_predictor_16x16_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d63_predictor_16x16)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); @@ -151,6 +154,9 @@ void vpx_d63_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_d63_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63e_predictor_4x4 vpx_d63e_predictor_4x4_c + void vpx_dc_128_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); void vpx_dc_128_predictor_16x16_sse2(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); #define vpx_dc_128_predictor_16x16 vpx_dc_128_predictor_16x16_sse2 @@ -288,6 +294,9 @@ void vpx_h_predictor_8x8_ssse3(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); RTCD_EXTERN void (*vpx_h_predictor_8x8)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_he_predictor_4x4 vpx_he_predictor_4x4_c + void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, int dest_stride); void vpx_idct16x16_10_add_sse2(const tran_low_t *input, uint8_t *dest, int dest_stride); #define vpx_idct16x16_10_add vpx_idct16x16_10_add_sse2 @@ -917,6 +926,9 @@ uint32_t vpx_variance_halfpixvar16x16_v_sse2(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride, uint32_t *sse); #define vpx_variance_halfpixvar16x16_v vpx_variance_halfpixvar16x16_v_sse2 +void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_ve_predictor_4x4 vpx_ve_predictor_4x4_c + void vpx_dsp_rtcd(void); #ifdef RTCD_C
diff --git a/third_party/mojo/src/mojo/public/c/gles2/gles2_call_visitor_chromium_extension_autogen.h b/third_party/mojo/src/mojo/public/c/gles2/gles2_call_visitor_chromium_extension_autogen.h index 9f3788cb..ef8b025 100644 --- a/third_party/mojo/src/mojo/public/c/gles2/gles2_call_visitor_chromium_extension_autogen.h +++ b/third_party/mojo/src/mojo/public/c/gles2/gles2_call_visitor_chromium_extension_autogen.h
@@ -327,6 +327,15 @@ (current, other)) VISIT_GL_CALL(InsertSyncPointCHROMIUM, GLuint, (), ()) VISIT_GL_CALL(WaitSyncPointCHROMIUM, void, (GLuint sync_point), (sync_point)) +VISIT_GL_CALL(InsertFenceSyncCHROMIUM, GLuint64, (), ()) +VISIT_GL_CALL(GenSyncTokenCHROMIUM, + void, + (GLuint64 fence_sync, GLbyte* sync_token), + (fence_sync, sync_token)) +VISIT_GL_CALL(WaitSyncTokenCHROMIUM, + void, + (const GLbyte* sync_token), + (sync_token)) VISIT_GL_CALL(DrawBuffersEXT, void, (GLsizei count, const GLenum* bufs),
diff --git a/third_party/zlib/README.chromium b/third_party/zlib/README.chromium index b90bcff..ddb63d7a 100644 --- a/third_party/zlib/README.chromium +++ b/third_party/zlib/README.chromium
@@ -15,6 +15,7 @@ - Added 'int z_errno' global for WinCE, to which 'errno' is defined in zutil.h. - Added 'mozzconf.h' to mangle the function names. - Added logic in zlib.h to undef our earlier mangles when defaulting to 64 bit offset versions of API. +- Added casts to suppress VC++ warnings The 'google.patch' file represents our changes from the original zlib-1.2.5. A more significant change to support mixed-source data compression. See
diff --git a/third_party/zlib/crc_folding.c b/third_party/zlib/crc_folding.c index 98c559c..48d7774 100644 --- a/third_party/zlib/crc_folding.c +++ b/third_party/zlib/crc_folding.c
@@ -283,7 +283,7 @@ goto partial; } - algn_diff = 0 - (unsigned long)src & 0xF; + algn_diff = 0 - (uintptr_t)src & 0xF; if (algn_diff) { xmm_crc_part = _mm_loadu_si128((__m128i *)src); _mm_storeu_si128((__m128i *)dst, xmm_crc_part);
diff --git a/third_party/zlib/google.patch b/third_party/zlib/google.patch index 3818b11..c943b410 100644 --- a/third_party/zlib/google.patch +++ b/third_party/zlib/google.patch
@@ -1,3 +1,15 @@ +diff -ru zlib-1.2.5/crc_folding.c zlib/crc_folding.c +--- zlib-1.2.5/crc_folding.c ++++ zlib/crc_folding.c +@@ -283,7 +283,7 @@ + goto partial; + } + +- algn_diff = 0 - (unsigned long)src & 0xF; ++ algn_diff = 0 - (uintptr_t)src & 0xF; + if (algn_diff) { + xmm_crc_part = _mm_loadu_si128((__m128i *)src); + _mm_storeu_si128((__m128i *)dst, xmm_crc_part); diff -ru zlib-1.2.5/gzlib.c zlib/gzlib.c --- zlib-1.2.5/gzlib.c +++ zlib/gzlib.c
diff --git a/tools/chrome_proxy/common/chrome_proxy_measurements.py b/tools/chrome_proxy/common/chrome_proxy_measurements.py index 7cdef14d..b7f7515 100644 --- a/tools/chrome_proxy/common/chrome_proxy_measurements.py +++ b/tools/chrome_proxy/common/chrome_proxy_measurements.py
@@ -25,11 +25,15 @@ tab.Navigate('data:text/html;base64,%s' % base64.b64encode( '<html><body><script>' 'function ProbeViaHeader(url, wanted_via) {' - 'var xmlhttp = new XMLHttpRequest();' - 'xmlhttp.open("HEAD",url,false);' - 'xmlhttp.send();' - 'var via=xmlhttp.getResponseHeader("via");' - 'return (via && via.indexOf(wanted_via) != -1);' + 'try {' + 'var xmlhttp = new XMLHttpRequest();' + 'xmlhttp.open("HEAD",url,false);' + 'xmlhttp.send();' + 'var via=xmlhttp.getResponseHeader("via");' + 'return (via && via.indexOf(wanted_via) != -1);' + '} catch (err) {' + 'return false;' + '}' '}' '</script>' 'Waiting for Chrome to start using the DRP...'
diff --git a/tools/gn/README.md b/tools/gn/README.md index 90cf908..f9679eb 100644 --- a/tools/gn/README.md +++ b/tools/gn/README.md
@@ -1,7 +1,7 @@ # What is GN? GN is a meta-build system that generates -[NinjaBuild](https://chromium.googlesource.com/chromium/src/+/master/docs/ninja_build.md) +[NinjaBuild](/chromium/src/+/master/docs/ninja_build.md) files. It's meant to be faster and simpler than GYP. It outputs only Ninja build files. @@ -10,10 +10,7 @@ 1. We believe GN files are more readable and more maintainable than GYP files. 2. GN is fast: - * GN is 20x faster than GYP (as of mid November, building 80% - of what GYP builds, in one configuration rather than two, takes 500ms - on a z620 running Ubuntu Trusty. GYP takes 20 seconds. - We see similar speedups on Mac and Windows). + * GN is 20x faster than GYP. * GN supports automatically re-running itself as needed by Ninja as part of the build. This eliminates the need to remember to re-run GN when you change a build file. @@ -25,30 +22,23 @@ ## What's the status? -_as of 8 Feb 2015:_ +_as of 7 Oct 2015:_ -Chrome and most of the major test suites link on Linux and ChromeOS. -There's probably <1000 objects left to build, in a few test suites and a -bunch of utillities and helper binaries. We will probably have -everything converted in another couple weeks. +GN is now the default system for Linux, though GYP still works. It +is mostly complete on Android, ChromeOS, and Windows (apart from NaCl +support on Windows). -Chrome also links on Android and Windows, and bringing up the remaining -test suites should be mostly straightforward. There's some work left to -enable NaCl on Windows but it should also be straightforward. - -Mac and iOS have not progressed much as attention has been focused on -Linux and Windows; we still need support for bundles and frameworks -before it can get to parity w/ the other platforms. +Mac and iOS are making progress, though we still need better support +for bundles before the major targets like Chrome can link and they get +to parity w/ the other platforms. ## When are you going to be done? -_as of 8 Feb 2015:_ +_as of 7 Oct 2015:_ -We're currently shooting for having the main developer configurations -working and usable by the end of March 2015. There will probably be a -fair amount of verification of flags, bug fixes, etc over the next -couple months, but hopefully we will be flipping configurations from GYP -to GN throughout Q2, targeting having everything done by the end of Q2. +We're currently shooting for having Android, ChromeOS, and Windows +converted over by the end of 2015, with Mac and iOS following in Q1 +of 2016. ## What does "done" mean? @@ -85,21 +75,20 @@ Check to see if your targets build under GN yet. If they don't, volunteer to help convert them! -_17 Nov 2014. We are updating the stuff we use to track progress. Watch -this space and chromium-dev@ for more info!_. +Or, look at [the list of open bugs](https://code.google.com/p/chromium/issues/list?can=2&q=label:Proj-GN-Migration%20-type:Project&sort=pri&colspec=ID%20Pri%20Summary%20Type%20OS%20Owner%20Status%20Modified%20Blocking) related to the migration and see if there's anything that catches your fancy. ## I want more info on GN! Read these links: - * [Quick start](docs/quick_start.md) - * [FAQ](docs/faq.md) - * [GYP conversion cookbook](docs/cookbook.md) - * [Language and operation details](docs/language.md) - * [Reference](docs/reference.md) The built-in `gn help` documentation. - * [Style guide](docs/style_guide.md) - * [Cross compiling and toolchains](docs/cross_compiles.md) - * [Hacking on GN itself](docs/hacking.md) - * [GNStandalone](docs/standalone.md) Standalone GN projects - * [UpdateGNBinaries](docs/update_binaries.md) Pushing new binaries - * [Check](docs/check.md) `gn check` command reference + * [Quick start](/chromium/src/+/master/tools/gn/docs/quick_start.md) + * [FAQ](/chromium/src/+/master/tools/gn/docs/faq.md) + * [GYP conversion cookbook](/chromium/src/+/master/tools/gn/docs/cookbook.md) + * [Language and operation details](/chromium/src/+/master/tools/gn/docs/language.md) + * [Reference](/chromium/src/+/master/tools/gn/docs/reference.md) The built-in `gn help` documentation. + * [Style guide](/chromium/src/+/master/tools/gn/docs/style_guide.md) + * [Cross compiling and toolchains](/chromium/src/+/master/tools/gn/docs/cross_compiles.md) + * [Hacking on GN itself](/chromium/src/+/master/tools/gn/docs/hacking.md) + * [GNStandalone](/chromium/src/+/master/tools/gn/docs/standalone.md) Standalone GN projects + * [UpdateGNBinaries](/chromium/src/+/master/tools/gn/docs/update_binaries.md) Pushing new binaries + * [Check](/chromium/src/+/master/tools/gn/docs/check.md) `gn check` command reference
diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids index 92456c8..1367aef4 100644 --- a/tools/gritsettings/resource_ids +++ b/tools/gritsettings/resource_ids
@@ -115,6 +115,15 @@ "content/app/strings/content_strings.grd": { "messages": [18900], }, + # Settings Chromium strings and Settings Google Chrome strings must start + # at the same id. We only use one file depending on whether we're building + # Chromium or Google Chrome. + "chrome/app/settings_chromium_strings.grd": { + "messages": [19700], + }, + "chrome/app/settings_google_chrome_strings.grd": { + "messages": [19700], + }, "chrome/app/settings_strings.grd": { "messages": [20000], },
diff --git a/tools/gritsettings/translation_expectations.pyl b/tools/gritsettings/translation_expectations.pyl index 0b37063..a64d7c2 100644 --- a/tools/gritsettings/translation_expectations.pyl +++ b/tools/gritsettings/translation_expectations.pyl
@@ -64,6 +64,8 @@ "chrome/app/resources/locale_settings_mac.grd": "Not UI strings; localized separately", "chrome/app/resources/locale_settings_win.grd": "Not UI strings; localized separately", "chrome/app/settings_strings.grd": "Work in progress; to be localized later in development (late 2015)", + "chrome/app/settings_chromium_strings.grd": "Work in progress; to be localized later in development (late 2015)", + "chrome/app/settings_google_chrome_strings.grd": "Work in progress; to be localized later in development (late 2015)", "chromecast/app/resources/chromecast_settings.grd": "Not UI strings; localized separately", "cloud_print/service/win/service_resources.grd": "Separate release process", "cloud_print/virtual_driver/win/install/virtual_driver_setup_resources.grd": "Separate release process",
diff --git a/tools/md_browser/md_browser.py b/tools/md_browser/md_browser.py index 7fb51eb2..9baa84bf8 100644 --- a/tools/md_browser/md_browser.py +++ b/tools/md_browser/md_browser.py
@@ -49,27 +49,34 @@ class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler): def do_GET(self): - full_path = os.path.abspath(os.path.join(self.server.top_level, - self.path[1:])) + path = self.path + + # strip off the repo and branch info, if present, for compatibility + # with gitiles. + if path.startswith('/chromium/src/+/master'): + path = path[len('/chromium/src/+/master'):] + + full_path = os.path.abspath(os.path.join(self.server.top_level, path[1:])) + if not full_path.startswith(SRC_DIR): self._DoUnknown() - elif self.path == '/doc.css': + elif path == '/doc.css': self._WriteTemplate('doc.css') elif not os.path.exists(full_path): self._DoNotFound() - elif self.path.lower().endswith('.md'): - self._DoMD() + elif path.lower().endswith('.md'): + self._DoMD(path) else: self._DoUnknown() - def _DoMD(self): + def _DoMD(self, path): extensions = [ 'markdown.extensions.fenced_code', 'markdown.extensions.tables', 'markdown.extensions.toc', ] - contents = self._Read(self.path[1:]) + contents = self._Read(path[1:]) md_fragment = markdown.markdown(contents, extensions=extensions, output_format='html4').encode('utf-8')
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 6521f84..cf6d33a 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -43262,6 +43262,32 @@ <summary>Usage of the Software Removal Tool (SRT) Prompt.</summary> </histogram> +<histogram name="SoftwareReporter.RunningTime" units="ms"> + <owner>alito@chromium.org</owner> + <summary> + The amount of time it took to run the software reporter tool as reported by + the tool itself via the registry. Logged just after the software reporter + tool has finished. + </summary> +</histogram> + +<histogram name="SoftwareReporter.RunningTimeAccordingToChrome" units="ms"> + <owner>alito@chromium.org</owner> + <summary> + The amount of time it took for the software reporter to run as measured by + chrome. Logged just after the software reporter tool has finished. + </summary> +</histogram> + +<histogram name="SoftwareReporter.RunningTimeRegistryError" + enum="SwReporterRunningTimeRegistryError"> + <owner>alito@chromium.org</owner> + <summary> + Error encountered when reading the software reporter tool's start and end + times from the registry. + </summary> +</histogram> + <histogram name="SoftwareReporter.Step" enum="SwReporterStep"> <owner>mad@chromium.org</owner> <summary> @@ -46487,6 +46513,14 @@ </summary> </histogram> +<histogram name="TabManager.Discarding.DiscardToReloadTime" units="ms"> + <owner>georgesak@chromium.org</owner> + <summary> + Elapsed time between a tab getting discarded to eventually being reloaded by + the user. + </summary> +</histogram> + <histogram name="TabManager.Discarding.ReloadCount" units="Reloads"> <owner>georgesak@chromium.org</owner> <summary> @@ -72780,6 +72814,14 @@ <int value="3" label="Attempted"/> </enum> +<enum name="SwReporterRunningTimeRegistryError" type="int"> + <int value="0" label="No error"/> + <int value="1" label="Registry key invalid"/> + <int value="2" label="Missing start time"/> + <int value="3" label="Missing end time"/> + <int value="4" label="Missing start and end times"/> +</enum> + <enum name="SwReporterStep" type="int"> <int value="0" label="Explicit request"/> <int value="1" label="Startup retry"/> @@ -75200,7 +75242,7 @@ <suffix name="ImageLink" label="The context menu was shown for an image which is also a link"/> <suffix name="Video" label="The context menu was shown for a video"/> - <suffix name="TextSelection" + <suffix name="SelectedText" label="The context menu was shown for a text selection"/> <affected-histogram name="ContextMenu.SelectedOption"/> </histogram_suffixes>
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py index 9a9bb638..e009e30 100644 --- a/tools/perf/benchmarks/blink_perf.py +++ b/tools/perf/benchmarks/blink_perf.py
@@ -4,10 +4,10 @@ import os +from core import path_util from core import perf_benchmark from telemetry import benchmark -from telemetry.core import util from telemetry import page as page_module from telemetry.page import page_test from telemetry.page import shared_page_state @@ -18,7 +18,7 @@ from page_sets import webgl_supported_shared_state -BLINK_PERF_BASE_DIR = os.path.join(util.GetChromiumSrcDir(), +BLINK_PERF_BASE_DIR = os.path.join(path_util.GetChromiumSrcDir(), 'third_party', 'WebKit', 'PerformanceTests') SKIPPED_FILE = os.path.join(BLINK_PERF_BASE_DIR, 'Skipped')
diff --git a/tools/perf/benchmarks/indexeddb_perf.py b/tools/perf/benchmarks/indexeddb_perf.py index 2de700fd..a0fc46c 100644 --- a/tools/perf/benchmarks/indexeddb_perf.py +++ b/tools/perf/benchmarks/indexeddb_perf.py
@@ -22,12 +22,12 @@ import json import os +from core import path_util from core import perf_benchmark from telemetry import benchmark from telemetry import page as page_module from telemetry import story -from telemetry.core import util from telemetry.page import page_test from telemetry.value import scalar @@ -100,8 +100,8 @@ return 'indexeddb_perf' def CreateStorySet(self, options): - indexeddb_dir = os.path.join(util.GetChromiumSrcDir(), 'chrome', 'test', - 'data', 'indexeddb') + indexeddb_dir = os.path.join(path_util.GetChromiumSrcDir(), 'chrome', + 'test', 'data', 'indexeddb') ps = story.StorySet(base_dir=indexeddb_dir) ps.AddStory(page_module.Page('file://perf_test.html', ps, ps.base_dir)) return ps
diff --git a/tools/perf/benchmarks/maps.py b/tools/perf/benchmarks/maps.py index 6924592..900bb90f 100644 --- a/tools/perf/benchmarks/maps.py +++ b/tools/perf/benchmarks/maps.py
@@ -5,13 +5,12 @@ """Runs a Google Maps performance test. Rerforms several common navigation actions on the map (pan, zoom, rotate)""" -import os import re +from core import path_util from core import perf_benchmark from telemetry import benchmark -from telemetry.core import util from telemetry.page import page as page_module from telemetry.page import page_test from telemetry import story @@ -56,11 +55,9 @@ return 'maps' def CreateStorySet(self, options): - page_set_path = os.path.join( - util.GetChromiumSrcDir(), 'tools', 'perf', 'page_sets') - ps = story.StorySet( - archive_data_file='data/maps.json', base_dir=page_set_path, - cloud_storage_bucket=story.PUBLIC_BUCKET) + ps = story.StorySet(archive_data_file='data/maps.json', + base_dir=path_util.GetStorySetsDir(), + cloud_storage_bucket=story.PUBLIC_BUCKET) ps.AddStory(MapsPage(ps, ps.base_dir)) return ps
diff --git a/tools/perf/benchmarks/pywebsocket_server.py b/tools/perf/benchmarks/pywebsocket_server.py index 304d269..494b8db 100644 --- a/tools/perf/benchmarks/pywebsocket_server.py +++ b/tools/perf/benchmarks/pywebsocket_server.py
@@ -5,6 +5,8 @@ import os import sys +from core import path_util + from telemetry.core import local_server from telemetry.core import util @@ -15,7 +17,7 @@ super(PywebsocketServerBackend, self).__init__() self.port = 8001 self.base_dir = os.path.relpath( - os.path.join(util.GetChromiumSrcDir(), + os.path.join(path_util.GetChromiumSrcDir(), 'third_party', 'pywebsocket', 'src'), start=util.GetTelemetryDir())
diff --git a/tools/perf/benchmarks/spaceport.py b/tools/perf/benchmarks/spaceport.py index 9f2ae32..7bcc809 100644 --- a/tools/perf/benchmarks/spaceport.py +++ b/tools/perf/benchmarks/spaceport.py
@@ -7,10 +7,10 @@ import logging import os +from core import path_util from core import perf_benchmark from telemetry import benchmark -from telemetry.core import util from telemetry import page as page_module from telemetry.page import page_test from telemetry import story @@ -114,8 +114,8 @@ return 'spaceport' def CreateStorySet(self, options): - spaceport_dir = os.path.join(util.GetChromiumSrcDir(), 'chrome', 'test', - 'data', 'third_party', 'spaceport') + spaceport_dir = os.path.join(path_util.GetChromiumSrcDir(), 'chrome', + 'test', 'data', 'third_party', 'spaceport') ps = story.StorySet(base_dir=spaceport_dir) ps.AddStory(page_module.Page('file://index.html', ps, ps.base_dir)) return ps
diff --git a/tools/perf/core/path_util.py b/tools/perf/core/path_util.py new file mode 100644 index 0000000..3050c981 --- /dev/null +++ b/tools/perf/core/path_util.py
@@ -0,0 +1,14 @@ +# Copyright (c) 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os + + +def GetChromiumSrcDir(): + return os.path.abspath(os.path.join( + os.path.dirname(__file__), os.pardir, os.pardir, os.pardir)) + +def GetStorySetsDir(): + return os.path.abspath(os.path.join( + os.path.dirname(__file__), os.pardir , 'page_sets'))
diff --git a/tools/telemetry/telemetry/__init__.py b/tools/telemetry/telemetry/__init__.py index d201ec6..c90ed7f0 100644 --- a/tools/telemetry/telemetry/__init__.py +++ b/tools/telemetry/telemetry/__init__.py
@@ -37,6 +37,8 @@ _AddDirToPythonPath(util.GetTelemetryThirdPartyDir(), 'webpagereplay') _AddDirToPythonPath(util.GetTelemetryThirdPartyDir(), 'websocket-client') -_AddDirToPythonPath(util.GetChromiumSrcDir(), 'build', 'android') -_AddDirToPythonPath(util.GetChromiumSrcDir(), - 'third_party', 'catapult', 'tracing') +_AddDirToPythonPath(os.path.dirname(__file__), os.path.pardir, os.path.pardir, + os.path.pardir, 'build', 'android') + +_AddDirToPythonPath(os.path.dirname(__file__), os.path.pardir, os.path.pardir, + os.path.pardir, 'third_party', 'catapult', 'tracing')
diff --git a/tools/telemetry/telemetry/benchmark_runner.py b/tools/telemetry/telemetry/benchmark_runner.py index 66c12a4..aed7d7e 100644 --- a/tools/telemetry/telemetry/benchmark_runner.py +++ b/tools/telemetry/telemetry/benchmark_runner.py
@@ -32,6 +32,11 @@ from telemetry.internal.util import binary_manager from telemetry.internal.util import command_line from telemetry.internal.util import ps_util +from telemetry import project_config + + +# TODO(aiolos): Remove this once clients move over to project_config version. +ProjectConfig = project_config.ProjectConfig def _IsBenchmarkEnabled(benchmark_class, possible_browser): @@ -80,40 +85,6 @@ 'Pass --browser to list benchmarks for another browser.\n') -class ProjectConfig(object): - """Contains information about the benchmark runtime environment. - - Attributes: - top_level_dir: A dir that contains benchmark, page test, and/or story - set dirs and associated artifacts. - benchmark_dirs: A list of dirs containing benchmarks. - benchmark_aliases: A dict of name:alias string pairs to be matched against - exactly during benchmark selection. - client_config: A path to a ProjectDependencies json file. - """ - def __init__(self, top_level_dir, benchmark_dirs=None, - benchmark_aliases=None, client_config=None): - self._top_level_dir = top_level_dir - self._benchmark_dirs = benchmark_dirs or [] - self._benchmark_aliases = benchmark_aliases or dict() - self._client_config = client_config or '' - - @property - def top_level_dir(self): - return self._top_level_dir - - @property - def benchmark_dirs(self): - return self._benchmark_dirs - - @property - def benchmark_aliases(self): - return self._benchmark_aliases - - @property - def client_config(self): - return self._client_config - class Help(command_line.OptparseCommand): """Display help information about a command"""
diff --git a/tools/telemetry/telemetry/project_config.py b/tools/telemetry/telemetry/project_config.py new file mode 100644 index 0000000..549b19da --- /dev/null +++ b/tools/telemetry/telemetry/project_config.py
@@ -0,0 +1,38 @@ +# Copyright 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + + +class ProjectConfig(object): + """Contains information about the benchmark runtime environment. + + Attributes: + top_level_dir: A dir that contains benchmark, page test, and/or story + set dirs and associated artifacts. + benchmark_dirs: A list of dirs containing benchmarks. + benchmark_aliases: A dict of name:alias string pairs to be matched against + exactly during benchmark selection. + client_config: A path to a ProjectDependencies json file. + """ + def __init__(self, top_level_dir, benchmark_dirs=None, + benchmark_aliases=None, client_config=None): + self._top_level_dir = top_level_dir + self._benchmark_dirs = benchmark_dirs or [] + self._benchmark_aliases = benchmark_aliases or dict() + self._client_config = client_config or '' + + @property + def top_level_dir(self): + return self._top_level_dir + + @property + def benchmark_dirs(self): + return self._benchmark_dirs + + @property + def benchmark_aliases(self): + return self._benchmark_aliases + + @property + def client_config(self): + return self._client_config
diff --git a/ui/base/test/ui_controls_mac.mm b/ui/base/test/ui_controls_mac.mm index 002cb03e..15cdb796 100644 --- a/ui/base/test/ui_controls_mac.mm +++ b/ui/base/test/ui_controls_mac.mm
@@ -235,7 +235,7 @@ bool SendMouseMoveNotifyWhenDone(long x, long y, const base::Closure& task) { CHECK(g_ui_controls_enabled); CGFloat screenHeight = - [[[NSScreen screens] objectAtIndex:0] frame].size.height; + [[[NSScreen screens] firstObject] frame].size.height; g_mouse_location = NSMakePoint(x, screenHeight - y); // flip! NSWindow* window = WindowAtCurrentMouseLocation();
diff --git a/ui/compositor/layer_animation_observer.cc b/ui/compositor/layer_animation_observer.cc index 658a835..e5db5ecd 100644 --- a/ui/compositor/layer_animation_observer.cc +++ b/ui/compositor/layer_animation_observer.cc
@@ -18,6 +18,9 @@ StopObserving(); } +void LayerAnimationObserver::OnLayerAnimationStarted( + LayerAnimationSequence* sequence) {} + bool LayerAnimationObserver::RequiresNotificationWhenAnimatorDestroyed() const { return false; }
diff --git a/ui/compositor/layer_animation_observer.h b/ui/compositor/layer_animation_observer.h index 35253d3..26bfdfa 100644 --- a/ui/compositor/layer_animation_observer.h +++ b/ui/compositor/layer_animation_observer.h
@@ -22,6 +22,9 @@ // LayerAnimationObservers are notified when animations complete. class COMPOSITOR_EXPORT LayerAnimationObserver { public: + // Called when the |sequence| starts. + virtual void OnLayerAnimationStarted(LayerAnimationSequence* sequence); + // Called when the |sequence| ends. Not called if |sequence| is aborted. virtual void OnLayerAnimationEnded( LayerAnimationSequence* sequence) = 0;
diff --git a/ui/compositor/layer_animation_sequence.cc b/ui/compositor/layer_animation_sequence.cc index 2c01a22..04a91af2 100644 --- a/ui/compositor/layer_animation_sequence.cc +++ b/ui/compositor/layer_animation_sequence.cc
@@ -48,6 +48,8 @@ if (elements_.empty()) return; + NotifyStarted(); + elements_[0]->set_requested_start_time(start_time_); elements_[0]->Start(delegate, animation_group_id_); } @@ -258,6 +260,11 @@ OnLayerAnimationScheduled(this)); } +void LayerAnimationSequence::NotifyStarted() { + FOR_EACH_OBSERVER(LayerAnimationObserver, observers_, + OnLayerAnimationStarted(this)); +} + void LayerAnimationSequence::NotifyEnded() { FOR_EACH_OBSERVER(LayerAnimationObserver, observers_,
diff --git a/ui/compositor/layer_animation_sequence.h b/ui/compositor/layer_animation_sequence.h index 0dad650..98afe9e 100644 --- a/ui/compositor/layer_animation_sequence.h +++ b/ui/compositor/layer_animation_sequence.h
@@ -140,6 +140,9 @@ // Notifies the observers that this sequence has been scheduled. void NotifyScheduled(); + // Notifies the observers that this sequence has been started. + void NotifyStarted(); + // Notifies the observers that this sequence has ended. void NotifyEnded();
diff --git a/ui/compositor/layer_animator_unittest.cc b/ui/compositor/layer_animator_unittest.cc index b3743ed..3ceeb4d 100644 --- a/ui/compositor/layer_animator_unittest.cc +++ b/ui/compositor/layer_animator_unittest.cc
@@ -54,6 +54,54 @@ return animations; } +// Creates a default animator with timers disabled for test. |delegate| and +// |observer| are attached if non-null. +LayerAnimator* CreateDefaultTestAnimator(LayerAnimationDelegate* delegate, + LayerAnimationObserver* observer) { + LayerAnimator* animator(LayerAnimator::CreateDefaultAnimator()); + animator->set_disable_timer_for_test(true); + if (delegate) + animator->SetDelegate(delegate); + if (observer) + animator->AddObserver(observer); + return animator; +} + +// Creates a default animator with timers disabled for test. |delegate| is +// attached if non-null. +LayerAnimator* CreateDefaultTestAnimator(LayerAnimationDelegate* delegate) { + return CreateDefaultTestAnimator(delegate, nullptr); +} + +// Creates a default animator with timers disabled for test. +LayerAnimator* CreateDefaultTestAnimator() { + return CreateDefaultTestAnimator(nullptr, nullptr); +} + +// Creates an implicit animator with timers disabled for test. |delegate| and +// |observer| are attached if non-null. +LayerAnimator* CreateImplicitTestAnimator(LayerAnimationDelegate* delegate, + LayerAnimationObserver* observer) { + LayerAnimator* animator(LayerAnimator::CreateImplicitAnimator()); + animator->set_disable_timer_for_test(true); + if (delegate) + animator->SetDelegate(delegate); + if (observer) + animator->AddObserver(observer); + return animator; +} + +// Creates an implicit animator with timers disabled for test. |delegate| is +// attached if non-null. +LayerAnimator* CreateImplicitTestAnimator(LayerAnimationDelegate* delegate) { + return CreateImplicitTestAnimator(delegate, nullptr); +} + +// Creates an implicit animator with timers disabled for test. +LayerAnimator* CreateImplicitTestAnimator() { + return CreateImplicitTestAnimator(nullptr, nullptr); +} + class TestImplicitAnimationObserver : public ImplicitAnimationObserver { public: explicit TestImplicitAnimationObserver(bool notify_when_animator_destructed) @@ -188,11 +236,8 @@ // Checks that setting a property on an implicit animator causes an animation to // happen. TEST(LayerAnimatorTest, ImplicitAnimation) { - scoped_refptr<LayerAnimator> animator( - LayerAnimator::CreateImplicitAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateImplicitTestAnimator(&delegate)); base::TimeTicks now = base::TimeTicks::Now(); animator->SetBrightness(0.5); EXPECT_TRUE(animator->is_animating()); @@ -203,10 +248,8 @@ // Checks that if the animator is a default animator, that implicit animations // are not started. TEST(LayerAnimatorTest, NoImplicitAnimation) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); animator->SetBrightness(0.5); EXPECT_FALSE(animator->is_animating()); EXPECT_FLOAT_EQ(delegate.GetBrightnessForAnimation(), 0.5); @@ -215,11 +258,8 @@ // Checks that StopAnimatingProperty stops animation for that property, and also // skips the stopped animation to the end. TEST(LayerAnimatorTest, StopAnimatingProperty) { - scoped_refptr<LayerAnimator> animator( - LayerAnimator::CreateImplicitAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateImplicitTestAnimator(&delegate)); double target_opacity(0.5); gfx::Rect target_bounds(0, 0, 50, 50); animator->SetOpacity(target_opacity); @@ -232,14 +272,12 @@ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), target_bounds); } -// Checks that multiple running animation for separate properties can be stopped -// simultaneously and that all animations are advanced to their target values. +// Checks that multiple running animations for separate properties can be +// stopped simultaneously and that all animations are advanced to their target +// values. TEST(LayerAnimatorTest, StopAnimating) { - scoped_refptr<LayerAnimator> animator( - LayerAnimator::CreateImplicitAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateImplicitTestAnimator(&delegate)); double target_opacity(0.5); gfx::Rect target_bounds(0, 0, 50, 50); animator->SetOpacity(target_opacity); @@ -251,18 +289,16 @@ CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), target_bounds); } -// Checks that multiple running animation for separate properties can be stopped -// simultaneously and that all animations are advanced to their target values. +// Checks that multiple running animations for separate properties can be +// stopped simultaneously and that aborted animations are NOT advanced to their +// target values. TEST(LayerAnimatorTest, AbortAllAnimations) { - scoped_refptr<LayerAnimator> animator( - LayerAnimator::CreateImplicitAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; double initial_opacity(1.0); gfx::Rect initial_bounds(0, 0, 10, 10); delegate.SetOpacityFromAnimation(initial_opacity); delegate.SetBoundsFromAnimation(initial_bounds); - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateImplicitTestAnimator(&delegate)); double target_opacity(0.5); gfx::Rect target_bounds(0, 0, 50, 50); animator->SetOpacity(target_opacity); @@ -277,10 +313,8 @@ // Schedule a non-threaded animation that can run immediately. This is the // trivial case and should result in the animation being started immediately. TEST(LayerAnimatorTest, ScheduleAnimationThatCanRunImmediately) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_brightness(0.0); double middle_brightness(0.5); @@ -314,12 +348,10 @@ // Schedule a threaded animation that can run immediately. TEST(LayerAnimatorTest, ScheduleThreadedAnimationThatCanRunImmediately) { double epsilon = 0.00001; - LayerAnimatorTestController test_controller( - LayerAnimator::CreateDefaultAnimator()); - LayerAnimator* animator = test_controller.animator(); - test_controller.animator()->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - test_controller.animator()->SetDelegate(&delegate); + LayerAnimatorTestController test_controller( + CreateDefaultTestAnimator(&delegate)); + LayerAnimator* animator = test_controller.animator(); double start_opacity(0.0); double target_opacity(1.0); @@ -362,10 +394,8 @@ // Schedule two non-threaded animations on separate properties. Both animations // should start immediately and should progress in lock step. TEST(LayerAnimatorTest, ScheduleTwoAnimationsThatCanRunImmediately) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_brightness(0.0); double middle_brightness(0.5); @@ -413,12 +443,10 @@ // animations should progress in lock step. TEST(LayerAnimatorTest, ScheduleThreadedAndNonThreadedAnimations) { double epsilon = 0.00001; - LayerAnimatorTestController test_controller( - LayerAnimator::CreateDefaultAnimator()); - LayerAnimator* animator = test_controller.animator(); - test_controller.animator()->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - test_controller.animator()->SetDelegate(&delegate); + LayerAnimatorTestController test_controller( + CreateDefaultTestAnimator(&delegate)); + LayerAnimator* animator = test_controller.animator(); double start_opacity(0.0); double target_opacity(1.0); @@ -477,10 +505,8 @@ // Schedule two animations on the same property. In this case, the two // animations should run one after another. TEST(LayerAnimatorTest, ScheduleTwoAnimationsOnSameProperty) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_brightness(0.0); double middle_brightness(0.5); @@ -530,10 +556,8 @@ // is, ensure that all animations targetting a particular property are run in // order. TEST(LayerAnimatorTest, ScheduleBlockedAnimation) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_grayscale(0.0); double middle_grayscale(0.5); @@ -609,10 +633,8 @@ // ScheduleTogether is being used, the bounds animation should not start until // the second grayscale animation starts. TEST(LayerAnimatorTest, ScheduleTogether) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_grayscale(0.0); double target_grayscale(1.0); @@ -662,10 +684,8 @@ // Start non-threaded animation (that can run immediately). This is the trivial // case (see the trival case for ScheduleAnimation). TEST(LayerAnimatorTest, StartAnimationThatCanRunImmediately) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_brightness(0.0); double middle_brightness(0.5); @@ -699,12 +719,10 @@ // Start threaded animation (that can run immediately). TEST(LayerAnimatorTest, StartThreadedAnimationThatCanRunImmediately) { double epsilon = 0.00001; - LayerAnimatorTestController test_controller( - LayerAnimator::CreateDefaultAnimator()); - LayerAnimator* animator = test_controller.animator(); - test_controller.animator()->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - test_controller.animator()->SetDelegate(&delegate); + LayerAnimatorTestController test_controller( + CreateDefaultTestAnimator(&delegate)); + LayerAnimator* animator = test_controller.animator(); double start_opacity(0.0); double target_opacity(1.0); @@ -745,10 +763,8 @@ // Preempt by immediately setting new target. TEST(LayerAnimatorTest, PreemptBySettingNewTarget) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_opacity(0.0); double target_opacity(1.0); @@ -773,10 +789,8 @@ // Preempt by animating to new target, with a non-threaded animation. TEST(LayerAnimatorTest, PreemptByImmediatelyAnimatingToNewTarget) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_brightness(0.0); double middle_brightness(0.5); @@ -828,12 +842,10 @@ // Preempt by animating to new target, with a threaded animation. TEST(LayerAnimatorTest, PreemptThreadedByImmediatelyAnimatingToNewTarget) { double epsilon = 0.00001; - LayerAnimatorTestController test_controller( - LayerAnimator::CreateDefaultAnimator()); - LayerAnimator* animator = test_controller.animator(); - test_controller.animator()->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - test_controller.animator()->SetDelegate(&delegate); + LayerAnimatorTestController test_controller( + CreateDefaultTestAnimator(&delegate)); + LayerAnimator* animator = test_controller.animator(); double start_opacity(0.0); double middle_opacity(0.5); @@ -899,10 +911,8 @@ // Preempt by enqueuing the new animation. TEST(LayerAnimatorTest, PreemptEnqueueNewAnimation) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_brightness(0.0); double middle_brightness(0.5); @@ -953,10 +963,8 @@ // case, all pending and running animations should be finished, and the new // animation started. TEST(LayerAnimatorTest, PreemptyByReplacingQueuedAnimations) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_brightness(0.0); double middle_brightness(0.5); @@ -1009,10 +1017,8 @@ } TEST(LayerAnimatorTest, StartTogetherSetsLastStepTime) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_grayscale(0.0); double target_grayscale(1.0); @@ -1048,10 +1054,8 @@ //------------------------------------------------------- // Preempt by immediately setting new target. TEST(LayerAnimatorTest, MultiPreemptBySettingNewTarget) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_opacity(0.0); double target_opacity(1.0); @@ -1086,10 +1090,8 @@ // Preempt by animating to new target. TEST(LayerAnimatorTest, MultiPreemptByImmediatelyAnimatingToNewTarget) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_grayscale(0.0); double middle_grayscale(0.5); @@ -1155,12 +1157,10 @@ // Preempt a threaded animation by animating to new target. TEST(LayerAnimatorTest, MultiPreemptThreadedByImmediatelyAnimatingToNewTarget) { double epsilon = 0.00001; - LayerAnimatorTestController test_controller( - LayerAnimator::CreateDefaultAnimator()); - LayerAnimator* animator = test_controller.animator(); - test_controller.animator()->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - test_controller.animator()->SetDelegate(&delegate); + LayerAnimatorTestController test_controller( + CreateDefaultTestAnimator(&delegate)); + LayerAnimator* animator = test_controller.animator(); double start_opacity(0.0); double middle_opacity(0.5); @@ -1243,10 +1243,8 @@ // Preempt by enqueuing the new animation. TEST(LayerAnimatorTest, MultiPreemptEnqueueNewAnimation) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_grayscale(0.0); double middle_grayscale(0.5); @@ -1309,10 +1307,8 @@ // case, all pending and running animations should be finished, and the new // animation started. TEST(LayerAnimatorTest, MultiPreemptByReplacingQueuedAnimations) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_grayscale(0.0); double middle_grayscale(0.5); @@ -1380,10 +1376,8 @@ //------------------------------------------------------- // Test that non-threaded cyclic sequences continue to animate. TEST(LayerAnimatorTest, CyclicSequences) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_brightness(0.0); double target_brightness(1.0); @@ -1440,12 +1434,10 @@ // Test that threaded cyclic sequences continue to animate. TEST(LayerAnimatorTest, ThreadedCyclicSequences) { - LayerAnimatorTestController test_controller( - LayerAnimator::CreateDefaultAnimator()); - LayerAnimator* animator = test_controller.animator(); - test_controller.animator()->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - test_controller.animator()->SetDelegate(&delegate); + LayerAnimatorTestController test_controller( + CreateDefaultTestAnimator(&delegate)); + LayerAnimator* animator = test_controller.animator(); double start_opacity(0.0); double target_opacity(1.0); @@ -1534,12 +1526,10 @@ } TEST(LayerAnimatorTest, AddObserverExplicit) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationObserver observer; TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); - animator->AddObserver(&observer); + scoped_refptr<LayerAnimator> animator( + CreateDefaultTestAnimator(&delegate, &observer)); observer.set_requires_notification_when_animator_destroyed(true); EXPECT_TRUE(!observer.last_ended_sequence()); @@ -1575,11 +1565,9 @@ // Tests that an observer added to a scoped settings object is still notified // when the object goes out of scope. TEST(LayerAnimatorTest, ImplicitAnimationObservers) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); - TestImplicitAnimationObserver observer(false); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); + TestImplicitAnimationObserver observer(false); EXPECT_FALSE(observer.animations_completed()); animator->SetBrightness(1.0f); @@ -1602,11 +1590,9 @@ // Tests that an observer added to a scoped settings object is still notified // when the object goes out of scope due to the animation being interrupted. TEST(LayerAnimatorTest, InterruptedImplicitAnimationObservers) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); - TestImplicitAnimationObserver observer(false); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); + TestImplicitAnimationObserver observer(false); EXPECT_FALSE(observer.animations_completed()); animator->SetBrightness(1.0f); @@ -1653,12 +1639,10 @@ // Tests that an observer added to a scoped settings object is not notified // when the animator is destroyed unless explicitly requested. TEST(LayerAnimatorTest, ImplicitObserversAtAnimatorDestruction) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); + TestLayerAnimationDelegate delegate; + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); TestImplicitAnimationObserver observer_notify(true); TestImplicitAnimationObserver observer_do_not_notify(false); - TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); EXPECT_FALSE(observer_notify.animations_completed()); EXPECT_FALSE(observer_do_not_notify.animations_completed()); @@ -1682,11 +1666,9 @@ } TEST(LayerAnimatorTest, AbortedAnimationStatusInImplicitObservers) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); - TestImplicitAnimationObserver observer(false); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); + TestImplicitAnimationObserver observer(false); EXPECT_FALSE(observer.animations_completed()); animator->SetBrightness(1.0f); @@ -1722,12 +1704,10 @@ } TEST(LayerAnimatorTest, RemoveObserverShouldRemoveFromSequences) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); + TestLayerAnimationDelegate delegate; + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); TestLayerAnimationObserver observer; TestLayerAnimationObserver removed_observer; - TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); base::TimeDelta delta = base::TimeDelta::FromSeconds(1); @@ -1757,13 +1737,10 @@ TEST(LayerAnimatorTest, ObserverReleasedBeforeAnimationSequenceEnds) { TestLayerAnimationDelegate delegate; - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); - scoped_ptr<TestLayerAnimationObserver> observer( new TestLayerAnimationObserver); - animator->SetDelegate(&delegate); - animator->AddObserver(observer.get()); + scoped_refptr<LayerAnimator> animator( + CreateDefaultTestAnimator(&delegate, observer.get())); delegate.SetOpacityFromAnimation(0.0f); @@ -1784,12 +1761,10 @@ } TEST(LayerAnimatorTest, ObserverAttachedAfterAnimationStarted) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); + TestLayerAnimationDelegate delegate; + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); TestImplicitAnimationObserver observer(false); - TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); delegate.SetBrightnessFromAnimation(0.0f); @@ -1818,12 +1793,10 @@ } TEST(LayerAnimatorTest, ObserverDetachedBeforeAnimationFinished) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); + TestLayerAnimationDelegate delegate; + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); TestImplicitAnimationObserver observer(false); - TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); delegate.SetBrightnessFromAnimation(0.0f); base::TimeDelta delta = base::TimeDelta::FromSeconds(1); @@ -2017,10 +1990,8 @@ // Check that setting a property during an animation with a default animator // cancels the original animation. TEST(LayerAnimatorTest, SettingPropertyDuringAnAnimation) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); double start_opacity(0.0); double target_opacity(1.0); @@ -2044,11 +2015,9 @@ // Tests that the preemption mode IMMEDIATELY_SET_NEW_TARGET, doesn't cause the // second sequence to be leaked. TEST(LayerAnimatorTest, ImmediatelySettingNewTargetDoesNotLeak) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_preemption_strategy(LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); + animator->set_preemption_strategy(LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); gfx::Rect start_bounds(0, 0, 50, 50); gfx::Rect middle_bounds(10, 10, 100, 100); @@ -2085,10 +2054,8 @@ // Verifies GetTargetOpacity() works when multiple sequences are scheduled. TEST(LayerAnimatorTest, GetTargetOpacity) { TestLayerAnimationDelegate delegate; - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); animator->set_preemption_strategy(LayerAnimator::ENQUEUE_NEW_ANIMATION); - animator->set_disable_timer_for_test(true); - animator->SetDelegate(&delegate); delegate.SetOpacityFromAnimation(0.0); @@ -2105,11 +2072,9 @@ // Verifies GetTargetBrightness() works when multiple sequences are scheduled. TEST(LayerAnimatorTest, GetTargetBrightness) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_preemption_strategy(LayerAnimator::ENQUEUE_NEW_ANIMATION); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); + animator->set_preemption_strategy(LayerAnimator::ENQUEUE_NEW_ANIMATION); delegate.SetBrightnessFromAnimation(0.0); @@ -2126,11 +2091,9 @@ // Verifies GetTargetGrayscale() works when multiple sequences are scheduled. TEST(LayerAnimatorTest, GetTargetGrayscale) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_preemption_strategy(LayerAnimator::ENQUEUE_NEW_ANIMATION); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); + animator->set_preemption_strategy(LayerAnimator::ENQUEUE_NEW_ANIMATION); delegate.SetGrayscaleFromAnimation(0.0); @@ -2147,10 +2110,8 @@ // Verifies color property is modified appropriately. TEST(LayerAnimatorTest, Color) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); SkColor start_color = SkColorSetARGB( 64, 20, 40, 60); SkColor middle_color = SkColorSetARGB(128, 35, 70, 120); @@ -2185,7 +2146,7 @@ // Verifies SchedulePauseForProperties(). TEST(LayerAnimatorTest, SchedulePauseForProperties) { - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator()); animator->set_preemption_strategy(LayerAnimator::ENQUEUE_NEW_ANIMATION); animator->SchedulePauseForProperties( base::TimeDelta::FromMilliseconds(100), @@ -2198,9 +2159,7 @@ class AnimatorOwner { public: - AnimatorOwner() - : animator_(LayerAnimator::CreateDefaultAnimator()) { - } + AnimatorOwner() : animator_(CreateDefaultTestAnimator()) {} LayerAnimator* animator() { return animator_.get(); } @@ -2281,7 +2240,6 @@ observer->set_delete_on_animation_ended(true); observer->set_delete_on_animation_aborted(true); LayerAnimator* animator = observer->animator(); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; animator->SetDelegate(&delegate); @@ -2314,7 +2272,6 @@ observer->set_delete_on_animation_ended(true); observer->set_delete_on_animation_aborted(true); LayerAnimator* animator = observer->animator(); - animator->set_disable_timer_for_test(true); TestLayerAnimationDelegate delegate; animator->SetDelegate(&delegate); @@ -2346,7 +2303,6 @@ DeletingObserver* observer = new DeletingObserver(&observer_was_deleted); observer->set_delete_on_animation_scheduled(true); LayerAnimator* animator = observer->animator(); - animator->set_disable_timer_for_test(true); animator->SetDelegate(&delegate); delegate.SetOpacityFromAnimation(0.0f); @@ -2379,7 +2335,6 @@ LayerAnimator* animator = observer->animator(); animator->set_preemption_strategy( LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); - animator->set_disable_timer_for_test(true); animator->SetDelegate(&delegate); delegate.SetOpacityFromAnimation(0.0f); @@ -2412,10 +2367,7 @@ TEST(LayerAnimatorTest, TestSetterRespectEnqueueStrategy) { TestLayerAnimationDelegate delegate; - scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator()); - animator->set_disable_timer_for_test(true); - - animator->SetDelegate(&delegate); + scoped_refptr<LayerAnimator> animator(CreateDefaultTestAnimator(&delegate)); float start_opacity = 0.0f; float target_opacity = 1.0f; @@ -2618,9 +2570,7 @@ }; TEST(LayerAnimatorTest, ObserverDeletesLayerInStopAnimating) { - scoped_refptr<LayerAnimator> animator( - LayerAnimator::CreateImplicitAnimator()); - animator->set_disable_timer_for_test(true); + scoped_refptr<LayerAnimator> animator(CreateImplicitTestAnimator()); LayerOwnerAnimationObserver observer(animator.get()); LayerAnimationDelegate* delegate = observer.animator_layer(); @@ -2649,4 +2599,206 @@ EXPECT_TRUE(animator->is_animating()); } +// Verifies the LayerAnimatorObserver notification order for an animation +// sequence that completes successfully. +TEST(LayerAnimatorObserverNotificationOrderTest, + SuccessfulCompletionOfSequence) { + TestLayerAnimationObserver observer; + TestLayerAnimationDelegate delegate; + scoped_refptr<LayerAnimator> animator( + CreateDefaultTestAnimator(&delegate, &observer)); + observer.set_requires_notification_when_animator_destroyed(true); + + const base::TimeDelta animation_duration = base::TimeDelta::FromSeconds(100); + + LayerAnimationSequence* sequence = new LayerAnimationSequence( + LayerAnimationElement::CreateBrightnessElement(1.0f, animation_duration)); + + EXPECT_TRUE(observer.NoEventsObserved()); + + animator->StartAnimation(sequence); + + EXPECT_EQ(observer.last_attached_sequence(), sequence); + EXPECT_EQ(observer.last_scheduled_sequence(), sequence); + EXPECT_EQ(observer.last_started_sequence(), sequence); + EXPECT_EQ(observer.last_aborted_sequence(), nullptr); + EXPECT_EQ(observer.last_ended_sequence(), nullptr); + EXPECT_EQ(observer.last_detached_sequence(), nullptr); + + EXPECT_TRUE(observer.AttachedEpochIsBeforeScheduledEpoch()); + EXPECT_TRUE(observer.ScheduledEpochIsBeforeStartedEpoch()); + + observer.ResetLayerAnimationObserverations(); + + const base::TimeTicks start_time = animator->last_step_time(); + + animator->Step(start_time + animation_duration); + + EXPECT_EQ(observer.last_attached_sequence(), nullptr); + EXPECT_EQ(observer.last_scheduled_sequence(), nullptr); + EXPECT_EQ(observer.last_started_sequence(), nullptr); + EXPECT_EQ(observer.last_aborted_sequence(), nullptr); + EXPECT_EQ(observer.last_ended_sequence(), sequence); + EXPECT_EQ(observer.last_detached_sequence(), sequence); + + EXPECT_TRUE(observer.EndedEpochIsBeforeDetachedEpoch()); +} + +// Verifies the LayerAnimatorObserver notification order for an animation +// sequence that is aborted after being scheduled. +TEST(LayerAnimatorObserverNotificationOrderTest, AbortingAScheduledSequence) { + TestLayerAnimationObserver observer; + TestLayerAnimationDelegate delegate; + scoped_refptr<LayerAnimator> animator( + CreateDefaultTestAnimator(&delegate, &observer)); + observer.set_requires_notification_when_animator_destroyed(true); + + const base::TimeDelta animation_duration = base::TimeDelta::FromSeconds(100); + + LayerAnimationSequence* sequence = new LayerAnimationSequence( + LayerAnimationElement::CreateBrightnessElement(1.0f, animation_duration)); + + EXPECT_TRUE(observer.NoEventsObserved()); + + animator->StartAnimation(sequence); + + EXPECT_EQ(observer.last_attached_sequence(), sequence); + EXPECT_EQ(observer.last_scheduled_sequence(), sequence); + EXPECT_EQ(observer.last_started_sequence(), sequence); + EXPECT_EQ(observer.last_aborted_sequence(), nullptr); + EXPECT_EQ(observer.last_ended_sequence(), nullptr); + EXPECT_EQ(observer.last_detached_sequence(), nullptr); + + EXPECT_TRUE(observer.AttachedEpochIsBeforeScheduledEpoch()); + EXPECT_TRUE(observer.ScheduledEpochIsBeforeStartedEpoch()); + + observer.ResetLayerAnimationObserverations(); + + animator->AbortAllAnimations(); + + EXPECT_EQ(observer.last_attached_sequence(), nullptr); + EXPECT_EQ(observer.last_scheduled_sequence(), nullptr); + EXPECT_EQ(observer.last_started_sequence(), nullptr); + EXPECT_EQ(observer.last_aborted_sequence(), sequence); + EXPECT_EQ(observer.last_ended_sequence(), nullptr); + EXPECT_EQ(observer.last_detached_sequence(), sequence); + + EXPECT_TRUE(observer.AbortedEpochIsBeforeDetachedEpoch()); +} + +// Verifies the LayerAnimatorObserver notification order for an animation +// sequence that is queued up after another sequence that +// completes successfully. +TEST(LayerAnimatorObserverNotificationOrderTest, + RunningASequenceThatIsQueuedForLaterStartTime) { + TestLayerAnimationObserver observer; + TestLayerAnimationDelegate delegate; + scoped_refptr<LayerAnimator> animator( + CreateDefaultTestAnimator(&delegate, &observer)); + observer.set_requires_notification_when_animator_destroyed(true); + + const base::TimeDelta animation_duration = base::TimeDelta::FromSeconds(100); + + LayerAnimationSequence* first_sequence = new LayerAnimationSequence( + LayerAnimationElement::CreateBrightnessElement(1.0f, animation_duration)); + + LayerAnimationSequence* queued_sequence = new LayerAnimationSequence( + LayerAnimationElement::CreateBrightnessElement(1.0f, animation_duration)); + + EXPECT_TRUE(observer.NoEventsObserved()); + + animator->StartAnimation(first_sequence); + + EXPECT_EQ(observer.last_attached_sequence(), first_sequence); + EXPECT_EQ(observer.last_scheduled_sequence(), first_sequence); + EXPECT_EQ(observer.last_started_sequence(), first_sequence); + EXPECT_EQ(observer.last_aborted_sequence(), nullptr); + EXPECT_EQ(observer.last_ended_sequence(), nullptr); + EXPECT_EQ(observer.last_detached_sequence(), nullptr); + + EXPECT_TRUE(observer.AttachedEpochIsBeforeScheduledEpoch()); + EXPECT_TRUE(observer.ScheduledEpochIsBeforeStartedEpoch()); + + observer.ResetLayerAnimationObserverations(); + + animator->set_preemption_strategy(LayerAnimator::ENQUEUE_NEW_ANIMATION); + animator->StartAnimation(queued_sequence); + + EXPECT_EQ(observer.last_attached_sequence(), queued_sequence); + EXPECT_EQ(observer.last_scheduled_sequence(), queued_sequence); + EXPECT_EQ(observer.last_started_sequence(), nullptr); + EXPECT_EQ(observer.last_aborted_sequence(), nullptr); + EXPECT_EQ(observer.last_ended_sequence(), nullptr); + EXPECT_EQ(observer.last_detached_sequence(), nullptr); + + EXPECT_TRUE(observer.AttachedEpochIsBeforeScheduledEpoch()); + + observer.ResetLayerAnimationObserverations(); + + base::TimeTicks start_time = animator->last_step_time(); + + animator->Step(start_time + animation_duration); + + EXPECT_EQ(observer.last_attached_sequence(), nullptr); + EXPECT_EQ(observer.last_scheduled_sequence(), nullptr); + EXPECT_EQ(observer.last_started_sequence(), queued_sequence); + EXPECT_EQ(observer.last_aborted_sequence(), nullptr); + EXPECT_EQ(observer.last_ended_sequence(), first_sequence); + EXPECT_EQ(observer.last_detached_sequence(), first_sequence); + + EXPECT_TRUE(observer.EndedEpochIsBeforeDetachedEpoch()); + EXPECT_TRUE(observer.EndedEpochIsBeforeStartedEpoch()); +} + +// Verifies the LayerAnimatorObserver notification order for an animation +// sequence that pre-empts another sequence. +TEST(LayerAnimatorObserverNotificationOrderTest, + RunningASequenceThatPreEmptsAnotherSequence) { + TestLayerAnimationObserver observer; + TestLayerAnimationDelegate delegate; + scoped_refptr<LayerAnimator> animator( + CreateDefaultTestAnimator(&delegate, &observer)); + observer.set_requires_notification_when_animator_destroyed(true); + + const base::TimeDelta animation_duration = base::TimeDelta::FromSeconds(100); + + LayerAnimationSequence* first_sequence = new LayerAnimationSequence( + LayerAnimationElement::CreateBrightnessElement(1.0f, animation_duration)); + + LayerAnimationSequence* queued_sequence = new LayerAnimationSequence( + LayerAnimationElement::CreateBrightnessElement(1.0f, animation_duration)); + + EXPECT_TRUE(observer.NoEventsObserved()); + + animator->StartAnimation(first_sequence); + + EXPECT_EQ(observer.last_attached_sequence(), first_sequence); + EXPECT_EQ(observer.last_scheduled_sequence(), first_sequence); + EXPECT_EQ(observer.last_started_sequence(), first_sequence); + EXPECT_EQ(observer.last_aborted_sequence(), nullptr); + EXPECT_EQ(observer.last_ended_sequence(), nullptr); + EXPECT_EQ(observer.last_detached_sequence(), nullptr); + + EXPECT_TRUE(observer.AttachedEpochIsBeforeScheduledEpoch()); + EXPECT_TRUE(observer.ScheduledEpochIsBeforeStartedEpoch()); + + observer.ResetLayerAnimationObserverations(); + + animator->set_preemption_strategy( + LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); + animator->StartAnimation(queued_sequence); + + EXPECT_EQ(observer.last_attached_sequence(), queued_sequence); + EXPECT_EQ(observer.last_scheduled_sequence(), queued_sequence); + EXPECT_EQ(observer.last_started_sequence(), queued_sequence); + EXPECT_EQ(observer.last_aborted_sequence(), first_sequence); + EXPECT_EQ(observer.last_ended_sequence(), nullptr); + EXPECT_EQ(observer.last_detached_sequence(), first_sequence); + + EXPECT_TRUE(observer.AbortedEpochIsBeforeDetachedEpoch()); + EXPECT_TRUE(observer.AbortedEpochIsBeforeStartedEpoch()); + EXPECT_TRUE(observer.AttachedEpochIsBeforeScheduledEpoch()); + EXPECT_TRUE(observer.ScheduledEpochIsBeforeStartedEpoch()); +} + } // namespace ui
diff --git a/ui/compositor/test/test_layer_animation_observer.cc b/ui/compositor/test/test_layer_animation_observer.cc index abc74ae..838b7f2 100644 --- a/ui/compositor/test/test_layer_animation_observer.cc +++ b/ui/compositor/test/test_layer_animation_observer.cc
@@ -9,28 +9,74 @@ namespace ui { TestLayerAnimationObserver::TestLayerAnimationObserver() - : last_ended_sequence_(NULL), - last_scheduled_sequence_(NULL), - last_aborted_sequence_(NULL), - requires_notification_when_animator_destroyed_(false) { -} + : next_epoch_(0), + last_attached_sequence_(nullptr), + last_attached_sequence_epoch_(-1), + last_scheduled_sequence_(nullptr), + last_scheduled_sequence_epoch_(-1), + last_started_sequence_(nullptr), + last_started_sequence_epoch_(-1), + last_aborted_sequence_(nullptr), + last_aborted_sequence_epoch_(-1), + last_ended_sequence_(nullptr), + last_ended_sequence_epoch_(-1), + last_detached_sequence_(nullptr), + last_detached_sequence_epoch_(-1), + requires_notification_when_animator_destroyed_(false) {} TestLayerAnimationObserver::~TestLayerAnimationObserver() { } -void TestLayerAnimationObserver::OnLayerAnimationEnded( - LayerAnimationSequence* sequence) { - last_ended_sequence_ = sequence; +void TestLayerAnimationObserver::ResetLayerAnimationObserverations() { + next_epoch_ = 0; + last_attached_sequence_ = nullptr; + last_attached_sequence_epoch_ = -1; + last_scheduled_sequence_ = nullptr; + last_scheduled_sequence_epoch_ = -1; + last_started_sequence_ = nullptr; + last_started_sequence_epoch_ = -1; + last_aborted_sequence_ = nullptr; + last_aborted_sequence_epoch_ = -1; + last_ended_sequence_ = nullptr; + last_ended_sequence_epoch_ = -1; + last_detached_sequence_ = nullptr; + last_detached_sequence_epoch_ = -1; } -void TestLayerAnimationObserver::OnLayerAnimationAborted( +void TestLayerAnimationObserver::OnAttachedToSequence( LayerAnimationSequence* sequence) { - last_aborted_sequence_ = sequence; + last_attached_sequence_ = sequence; + last_attached_sequence_epoch_ = next_epoch_++; } void TestLayerAnimationObserver::OnLayerAnimationScheduled( LayerAnimationSequence* sequence) { last_scheduled_sequence_ = sequence; + last_scheduled_sequence_epoch_ = next_epoch_++; +} + +void TestLayerAnimationObserver::OnLayerAnimationStarted( + LayerAnimationSequence* sequence) { + last_started_sequence_ = sequence; + last_started_sequence_epoch_ = next_epoch_++; +} + +void TestLayerAnimationObserver::OnLayerAnimationAborted( + LayerAnimationSequence* sequence) { + last_aborted_sequence_ = sequence; + last_aborted_sequence_epoch_ = next_epoch_++; +} + +void TestLayerAnimationObserver::OnLayerAnimationEnded( + LayerAnimationSequence* sequence) { + last_ended_sequence_ = sequence; + last_ended_sequence_epoch_ = next_epoch_++; +} + +void TestLayerAnimationObserver::OnDetachedFromSequence( + LayerAnimationSequence* sequence) { + last_detached_sequence_ = sequence; + last_detached_sequence_epoch_ = next_epoch_++; } bool @@ -38,4 +84,134 @@ return requires_notification_when_animator_destroyed_; } +testing::AssertionResult TestLayerAnimationObserver::NoEventsObserved() { + if (!last_attached_sequence_ && !last_scheduled_sequence_ && + !last_started_sequence_ && !last_aborted_sequence_ && + !last_ended_sequence_ && !last_detached_sequence_) { + return testing::AssertionSuccess(); + } else { + testing::AssertionResult assertion_failure = testing::AssertionFailure(); + assertion_failure << "The following events have been observed:"; + if (last_attached_sequence_) { + assertion_failure << "\n\tlast_attached_sequence_=" + << last_attached_sequence_; + } + if (last_scheduled_sequence_) { + assertion_failure << "\n\tlast_scheduled_sequence_=" + << last_scheduled_sequence_; + } + if (last_started_sequence_) { + assertion_failure << "\n\tlast_started_sequence_=" + << last_started_sequence_; + } + if (last_aborted_sequence_) { + assertion_failure << "\n\tlast_aborted_sequence_=" + << last_aborted_sequence_; + } + if (last_ended_sequence_) { + assertion_failure << "\n\tlast_ended_sequence_" << last_ended_sequence_; + } + if (last_detached_sequence_) { + assertion_failure << "\n\tlast_detached_sequence_=" + << last_detached_sequence_; + } + return assertion_failure; + } +} + +testing::AssertionResult +TestLayerAnimationObserver::AttachedEpochIsBeforeScheduledEpoch() { + if (last_attached_sequence_epoch_ < last_scheduled_sequence_epoch_) { + return testing::AssertionSuccess(); + } else { + return testing::AssertionFailure() + << "The attached epoch=" << last_attached_sequence_epoch_ + << " is NOT before the scheduled epoch=" + << last_scheduled_sequence_epoch_; + } +} + +testing::AssertionResult +TestLayerAnimationObserver::ScheduledEpochIsBeforeStartedEpoch() { + if (last_scheduled_sequence_epoch_ < last_started_sequence_epoch_) { + return testing::AssertionSuccess(); + } else { + return testing::AssertionFailure() + << "The scheduled epoch=" << last_scheduled_sequence_epoch_ + << " is NOT before the started epoch=" + << last_started_sequence_epoch_; + } +} + +testing::AssertionResult +TestLayerAnimationObserver::StartedEpochIsBeforeEndedEpoch() { + if (last_started_sequence_epoch_ < last_ended_sequence_epoch_) { + return testing::AssertionSuccess(); + } else { + return testing::AssertionFailure() + << "The started epoch=" << last_started_sequence_epoch_ + << " is NOT before the ended epoch=" << last_ended_sequence_epoch_; + } +} + +testing::AssertionResult +TestLayerAnimationObserver::StartedEpochIsBeforeAbortedEpoch() { + if (last_started_sequence_epoch_ < last_aborted_sequence_epoch_) { + return testing::AssertionSuccess(); + } else { + return testing::AssertionFailure() + << "The started epoch=" << last_started_sequence_epoch_ + << " is NOT before the aborted epoch=" + << last_aborted_sequence_epoch_; + } +} + +testing::AssertionResult +TestLayerAnimationObserver::AbortedEpochIsBeforeStartedEpoch() { + if (last_aborted_sequence_epoch_ < last_started_sequence_epoch_) { + return testing::AssertionSuccess(); + } else { + return testing::AssertionFailure() + << "The aborted epoch=" << last_aborted_sequence_epoch_ + << " is NOT before the started epoch=" + << last_started_sequence_epoch_; + } +} + +testing::AssertionResult +TestLayerAnimationObserver::AbortedEpochIsBeforeDetachedEpoch() { + if (last_aborted_sequence_epoch_ < last_detached_sequence_epoch_) { + return testing::AssertionSuccess(); + } else { + return testing::AssertionFailure() + << "The aborted epoch=" << last_aborted_sequence_epoch_ + << " is NOT before the detached epoch=" + << last_detached_sequence_epoch_; + } +} + +testing::AssertionResult +TestLayerAnimationObserver::EndedEpochIsBeforeStartedEpoch() { + if (last_ended_sequence_epoch_ < last_started_sequence_epoch_) { + return testing::AssertionSuccess(); + } else { + return testing::AssertionFailure() + << "The ended epoch=" << last_ended_sequence_epoch_ + << " is NOT before the started epoch=" + << last_started_sequence_epoch_; + } +} + +testing::AssertionResult +TestLayerAnimationObserver::EndedEpochIsBeforeDetachedEpoch() { + if (last_ended_sequence_epoch_ < last_detached_sequence_epoch_) { + return testing::AssertionSuccess(); + } else { + return testing::AssertionFailure() + << "The ended epoch=" << last_ended_sequence_epoch_ + << " is NOT before the detached epoch=" + << last_detached_sequence_epoch_; + } +} + } // namespace ui
diff --git a/ui/compositor/test/test_layer_animation_observer.h b/ui/compositor/test/test_layer_animation_observer.h index 0f0a18e..6860b173 100644 --- a/ui/compositor/test/test_layer_animation_observer.h +++ b/ui/compositor/test/test_layer_animation_observer.h
@@ -6,6 +6,7 @@ #define UI_COMPOSITOR_TEST_TEST_LAYER_ANIMATION_OBSERVER_H_ #include "base/compiler_specific.h" +#include "testing/gtest/include/gtest/gtest.h" #include "ui/compositor/layer_animation_observer.h" namespace ui { @@ -19,34 +20,110 @@ TestLayerAnimationObserver(); ~TestLayerAnimationObserver() override; - void OnLayerAnimationEnded(LayerAnimationSequence* sequence) override; + // Resets all the data tracking LayerAnimationObserver observations. + void ResetLayerAnimationObserverations(); - void OnLayerAnimationAborted(LayerAnimationSequence* sequence) override; - + // LayerAnimationObserver: void OnLayerAnimationScheduled(LayerAnimationSequence* sequence) override; - + void OnLayerAnimationStarted(LayerAnimationSequence* sequence) override; + void OnLayerAnimationAborted(LayerAnimationSequence* sequence) override; + void OnLayerAnimationEnded(LayerAnimationSequence* sequence) override; bool RequiresNotificationWhenAnimatorDestroyed() const override; - const LayerAnimationSequence* last_ended_sequence() const { - return last_ended_sequence_; + const LayerAnimationSequence* last_attached_sequence() const { + return last_attached_sequence_; + } + + int last_attached_sequence_epoch() const { + return last_attached_sequence_epoch_; } const LayerAnimationSequence* last_scheduled_sequence() const { return last_scheduled_sequence_; } + int last_scheduled_sequence_epoch() const { + return last_scheduled_sequence_epoch_; + } + + const LayerAnimationSequence* last_started_sequence() const { + return last_started_sequence_; + } + + int last_started_sequence_epoch() const { + return last_started_sequence_epoch_; + } + const LayerAnimationSequence* last_aborted_sequence() const { return last_aborted_sequence_; } + int last_aborted_sequence_epoch() const { + return last_aborted_sequence_epoch_; + } + + const LayerAnimationSequence* last_ended_sequence() const { + return last_ended_sequence_; + } + + int last_ended_sequence_epoch() const { return last_ended_sequence_epoch_; } + + const LayerAnimationSequence* last_detached_sequence() const { + return last_detached_sequence_; + } + + int last_detached_sequence_epoch() const { + return last_detached_sequence_epoch_; + } + void set_requires_notification_when_animator_destroyed(bool value) { requires_notification_when_animator_destroyed_ = value; } + testing::AssertionResult NoEventsObserved(); + + testing::AssertionResult AttachedEpochIsBeforeScheduledEpoch(); + + testing::AssertionResult ScheduledEpochIsBeforeStartedEpoch(); + + testing::AssertionResult StartedEpochIsBeforeEndedEpoch(); + + testing::AssertionResult StartedEpochIsBeforeAbortedEpoch(); + + testing::AssertionResult AbortedEpochIsBeforeStartedEpoch(); + + testing::AssertionResult AbortedEpochIsBeforeDetachedEpoch(); + + testing::AssertionResult EndedEpochIsBeforeStartedEpoch(); + + testing::AssertionResult EndedEpochIsBeforeDetachedEpoch(); + + protected: + // LayerAnimationObserver: + void OnAttachedToSequence(LayerAnimationSequence* sequence) override; + void OnDetachedFromSequence(LayerAnimationSequence* sequence) override; + private: - const LayerAnimationSequence* last_ended_sequence_; + int next_epoch_; + + const LayerAnimationSequence* last_attached_sequence_; + int last_attached_sequence_epoch_; + const LayerAnimationSequence* last_scheduled_sequence_; + int last_scheduled_sequence_epoch_; + + const LayerAnimationSequence* last_started_sequence_; + int last_started_sequence_epoch_; + const LayerAnimationSequence* last_aborted_sequence_; + int last_aborted_sequence_epoch_; + + const LayerAnimationSequence* last_ended_sequence_; + int last_ended_sequence_epoch_; + + const LayerAnimationSequence* last_detached_sequence_; + int last_detached_sequence_epoch_; + bool requires_notification_when_animator_destroyed_; // Copy and assign are allowed.
diff --git a/ui/events/cocoa/events_mac_unittest.mm b/ui/events/cocoa/events_mac_unittest.mm index c4169bf..ff943b9f 100644 --- a/ui/events/cocoa/events_mac_unittest.mm +++ b/ui/events/cocoa/events_mac_unittest.mm
@@ -109,7 +109,7 @@ NSPointFromCGPoint(Flip(window_location).ToCGPoint()); NSPoint screen_point = [test_window() convertBaseToScreen:window_point]; CGFloat primary_screen_height = - NSHeight([[[NSScreen screens] objectAtIndex:0] frame]); + NSHeight([[[NSScreen screens] firstObject] frame]); screen_point.y = primary_screen_height - screen_point.y; CGEventSetLocation(scroll, NSPointToCGPoint(screen_point)); return [NSEvent eventWithCGEvent:scroll];
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index 341d876..f2f465f 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -665,6 +665,10 @@ } if (is_android) { + apk_deps = [ + "//ui/android:ui_java" + ] + sources -= [ # Do not run display_change_notifier_unittest.cc on Android because it # does not compile display_observer.cc
diff --git a/ui/gfx/OWNERS b/ui/gfx/OWNERS index ac6e6b3..3c51f44 100644 --- a/ui/gfx/OWNERS +++ b/ui/gfx/OWNERS
@@ -20,6 +20,7 @@ # GPU memory buffer interface. per-file gpu_memory_buffer*=reveman@chromium.org +per-file buffer*=reveman@chromium.org # Vector icons. per-file *vector_icon*=estade@chromium.org
diff --git a/ui/gfx/buffer_format_util.cc b/ui/gfx/buffer_format_util.cc index 36222c9..33bf627 100644 --- a/ui/gfx/buffer_format_util.cc +++ b/ui/gfx/buffer_format_util.cc
@@ -8,6 +8,27 @@ #include "base/numerics/safe_math.h" namespace gfx { +namespace { + +const BufferFormat kBufferFormats[] = { + BufferFormat::ATC, BufferFormat::ATCIA, + BufferFormat::DXT1, BufferFormat::DXT5, + BufferFormat::ETC1, BufferFormat::R_8, + BufferFormat::RGBA_4444, BufferFormat::RGBA_8888, + BufferFormat::BGRX_8888, BufferFormat::BGRA_8888, + BufferFormat::UYVY_422, BufferFormat::YUV_420_BIPLANAR, + BufferFormat::YUV_420}; + +static_assert(arraysize(kBufferFormats) == + (static_cast<int>(BufferFormat::LAST) + 1), + "BufferFormat::LAST must be last value of kBufferFormats"); + +} // namespace + +std::vector<BufferFormat> GetBufferFormats() { + return std::vector<BufferFormat>(kBufferFormats, + kBufferFormats + arraysize(kBufferFormats)); +} size_t NumberOfPlanesForBufferFormat(BufferFormat format) { switch (format) {
diff --git a/ui/gfx/buffer_format_util.h b/ui/gfx/buffer_format_util.h index 39df27b..f656f4ad 100644 --- a/ui/gfx/buffer_format_util.h +++ b/ui/gfx/buffer_format_util.h
@@ -5,6 +5,8 @@ #ifndef UI_GFX_BUFFER_FORMAT_UTIL_H_ #define UI_GFX_BUFFER_FORMAT_UTIL_H_ +#include <vector> + #include "base/basictypes.h" #include "ui/gfx/buffer_types.h" #include "ui/gfx/geometry/size.h" @@ -12,6 +14,9 @@ namespace gfx { +// Returns a vector containing all buffer formats. +GFX_EXPORT std::vector<BufferFormat> GetBufferFormats(); + // Returns the number of planes for |format|. GFX_EXPORT size_t NumberOfPlanesForBufferFormat(BufferFormat format); @@ -22,17 +27,21 @@ // Returns the number of bytes used to store a row of the given zero-indexed // |plane| of |format|. -GFX_EXPORT size_t RowSizeForBufferFormat( - size_t width, gfx::BufferFormat format, int plane); -GFX_EXPORT bool RowSizeForBufferFormatChecked( - size_t width, gfx::BufferFormat format, int plane, size_t* size_in_bytes) +GFX_EXPORT size_t RowSizeForBufferFormat(size_t width, + BufferFormat format, + int plane); +GFX_EXPORT bool RowSizeForBufferFormatChecked(size_t width, + BufferFormat format, + int plane, + size_t* size_in_bytes) WARN_UNUSED_RESULT; // Returns the number of bytes used to store all the planes of a given |format|. -GFX_EXPORT size_t BufferSizeForBufferFormat( - const Size& size, gfx::BufferFormat format); -GFX_EXPORT bool BufferSizeForBufferFormatChecked( - const Size& size, gfx::BufferFormat format, size_t* size_in_bytes) +GFX_EXPORT size_t BufferSizeForBufferFormat(const Size& size, + BufferFormat format); +GFX_EXPORT bool BufferSizeForBufferFormatChecked(const Size& size, + BufferFormat format, + size_t* size_in_bytes) WARN_UNUSED_RESULT; } // namespace gfx
diff --git a/ui/gfx/color_profile_mac_unittest.mm b/ui/gfx/color_profile_mac_unittest.mm index 26dd290..3910a9d2 100644 --- a/ui/gfx/color_profile_mac_unittest.mm +++ b/ui/gfx/color_profile_mac_unittest.mm
@@ -51,7 +51,7 @@ } NSRect PrimaryScreenFrame() { - return [[[NSScreen screens] objectAtIndex:0] frame]; + return [[[NSScreen screens] firstObject] frame]; } };
diff --git a/ui/gfx/mac/coordinate_conversion.mm b/ui/gfx/mac/coordinate_conversion.mm index 54b16e9..b31ce9e 100644 --- a/ui/gfx/mac/coordinate_conversion.mm +++ b/ui/gfx/mac/coordinate_conversion.mm
@@ -16,7 +16,7 @@ // The height of the primary display, which OSX defines as the monitor with the // menubar. This is always at index 0. CGFloat PrimaryDisplayHeight() { - return NSMaxY([[[NSScreen screens] objectAtIndex:0] frame]); + return NSMaxY([[[NSScreen screens] firstObject] frame]); } } // namespace
diff --git a/ui/gfx/mac/coordinate_conversion_unittest.mm b/ui/gfx/mac/coordinate_conversion_unittest.mm index ac882fa6..ccddbe8 100644 --- a/ui/gfx/mac/coordinate_conversion_unittest.mm +++ b/ui/gfx/mac/coordinate_conversion_unittest.mm
@@ -48,7 +48,7 @@ void MacCoordinateConversionTest::SetUp() { // Before swizzling, do a sanity check that the primary screen's origin is // (0, 0). This should always be true. - NSRect primary_screen_frame = [[[NSScreen screens] objectAtIndex:0] frame]; + NSRect primary_screen_frame = [[[NSScreen screens] firstObject] frame]; EXPECT_EQ(0, primary_screen_frame.origin.x); EXPECT_EQ(0, primary_screen_frame.origin.y); @@ -57,7 +57,7 @@ [MacCoordinateConversionTestScreenDonor class], @selector(frame))); - primary_screen_frame = [[[NSScreen screens] objectAtIndex:0] frame]; + primary_screen_frame = [[[NSScreen screens] firstObject] frame]; EXPECT_EQ(kTestWidth, primary_screen_frame.size.width); EXPECT_EQ(kTestHeight, primary_screen_frame.size.height); }
diff --git a/ui/gfx/screen_mac.mm b/ui/gfx/screen_mac.mm index abd8549..e23feede 100644 --- a/ui/gfx/screen_mac.mm +++ b/ui/gfx/screen_mac.mm
@@ -24,7 +24,7 @@ gfx::Rect ConvertCoordinateSystem(NSRect ns_rect) { // Primary monitor is defined as the monitor with the menubar, // which is always at index 0. - NSScreen* primary_screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* primary_screen = [[NSScreen screens] firstObject]; float primary_screen_height = [primary_screen frame].size.height; gfx::Rect rect(NSRectToCGRect(ns_rect)); rect.set_y(primary_screen_height - rect.y() - rect.height()); @@ -58,7 +58,7 @@ gfx::Display display(display_id, gfx::Rect(NSRectToCGRect(frame))); NSRect visible_frame = [screen visibleFrame]; - NSScreen* primary = [[NSScreen screens] objectAtIndex:0]; + NSScreen* primary = [[NSScreen screens] firstObject]; // Convert work area's coordinate systems. if ([screen isEqual:primary]) { @@ -103,7 +103,7 @@ gfx::Point GetCursorScreenPoint() override { NSPoint mouseLocation = [NSEvent mouseLocation]; // Flip coordinates to gfx (0,0 in top-left corner) using primary screen. - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* screen = [[NSScreen screens] firstObject]; mouseLocation.y = NSMaxY([screen frame]) - mouseLocation.y; return gfx::Point(mouseLocation.x, mouseLocation.y); } @@ -161,7 +161,7 @@ gfx::Display GetPrimaryDisplay() const override { // Primary display is defined as the display with the menubar, // which is always at index 0. - NSScreen* primary = [[NSScreen screens] objectAtIndex:0]; + NSScreen* primary = [[NSScreen screens] firstObject]; gfx::Display display = GetDisplayForScreen(primary); return display; }
diff --git a/ui/gl/gl_enums_implementation_autogen.h b/ui/gl/gl_enums_implementation_autogen.h index 38efaed..54dea5a 100644 --- a/ui/gl/gl_enums_implementation_autogen.h +++ b/ui/gl/gl_enums_implementation_autogen.h
@@ -2857,6 +2857,9 @@ 0x00100000, "GL_STENCIL_BUFFER_BIT4_QCOM", }, { + 24, "GL_SYNC_TOKEN_SIZE_CHROMIUM", + }, + { 0x8E4E, "GL_LAST_VERTEX_CONVENTION_EXT", }, {
diff --git a/ui/message_center/cocoa/popup_collection.mm b/ui/message_center/cocoa/popup_collection.mm index 5961e614..05a6bdde 100644 --- a/ui/message_center/cocoa/popup_collection.mm +++ b/ui/message_center/cocoa/popup_collection.mm
@@ -150,7 +150,7 @@ - (NSRect)screenFrame { if (!NSIsEmptyRect(testingScreenFrame_)) return testingScreenFrame_; - return [[[NSScreen screens] objectAtIndex:0] visibleFrame]; + return [[[NSScreen screens] firstObject] visibleFrame]; } - (BOOL)addNotification:(const message_center::Notification*)notification {
diff --git a/ui/message_center/message_center_style.cc b/ui/message_center/message_center_style.cc index 3413149e..33f8757 100644 --- a/ui/message_center/message_center_style.cc +++ b/ui/message_center/message_center_style.cc
@@ -54,6 +54,10 @@ // Timing. const int kAutocloseDefaultDelaySeconds = 8; const int kAutocloseHighPriorityDelaySeconds = 25; +// Web notifications use a larger timeout for now, which improves re-engagement. +// TODO(johnme): Use Finch to experiment with different values for this, then +// consider replacing kAutocloseDefaultDelaySeconds with this. +const int kAutocloseWebNotificationDelaySeconds = 20; // Colors. const SkColor kBackgroundLightColor = SkColorSetRGB(0xf1, 0xf1, 0xf1);
diff --git a/ui/message_center/message_center_style.h b/ui/message_center/message_center_style.h index 51ab6652..6c1ac96 100644 --- a/ui/message_center/message_center_style.h +++ b/ui/message_center/message_center_style.h
@@ -101,6 +101,7 @@ // Timing. extern const int kAutocloseDefaultDelaySeconds; extern const int kAutocloseHighPriorityDelaySeconds; +extern const int kAutocloseWebNotificationDelaySeconds; // Buttons. const int kButtonHeight = 38; // In DIPs.
diff --git a/ui/message_center/notification.cc b/ui/message_center/notification.cc index af35e57..a39f7c7 100644 --- a/ui/message_center/notification.cc +++ b/ui/message_center/notification.cc
@@ -26,6 +26,7 @@ RichNotificationData::RichNotificationData() : priority(DEFAULT_PRIORITY), + is_web_notification(false), never_timeout(false), timestamp(base::Time::Now()), context_message(base::string16()), @@ -36,6 +37,7 @@ RichNotificationData::RichNotificationData(const RichNotificationData& other) : priority(other.priority), + is_web_notification(other.is_web_notification), never_timeout(other.never_timeout), timestamp(other.timestamp), context_message(other.context_message), @@ -139,6 +141,7 @@ is_read_ = base->is_read_; if (!delegate_.get()) delegate_ = base->delegate(); + optional_fields_.is_web_notification = base->is_web_notification(); optional_fields_.never_timeout = base->never_timeout(); }
diff --git a/ui/message_center/notification.h b/ui/message_center/notification.h index 3b63e54..41dfa21 100644 --- a/ui/message_center/notification.h +++ b/ui/message_center/notification.h
@@ -41,6 +41,7 @@ ~RichNotificationData(); int priority; + bool is_web_notification; bool never_timeout; base::Time timestamp; base::string16 context_message; @@ -75,7 +76,7 @@ virtual ~Notification(); // Copies the internal on-memory state from |base|, i.e. shown_as_popup, - // is_read, and never_timeout. + // is_read, is_web_notification and never_timeout. void CopyState(Notification* base); NotificationType type() const { return type_; } @@ -193,14 +194,20 @@ // The notification with lesser serial_number is considered 'older'. unsigned serial_number() { return serial_number_; } - // Marks this explicitly to prevent the timeout dismiss of notification. - // This is used by webkit notifications to keep the existing behavior. + // Gets and sets whether this was shown using the Web Notifications API. + bool is_web_notification() const { + return optional_fields_.is_web_notification; + } + void set_is_web_notification(bool is_web_notification) { + optional_fields_.is_web_notification = is_web_notification; + } + + // Gets and sets whether the notifiction should remain onscreen permanently. + bool never_timeout() const { return optional_fields_.never_timeout; } void set_never_timeout(bool never_timeout) { optional_fields_.never_timeout = never_timeout; } - bool never_timeout() const { return optional_fields_.never_timeout; } - bool clickable() const { return optional_fields_.clickable; } void set_clickable(bool clickable) { optional_fields_.clickable = clickable;
diff --git a/ui/message_center/popup_timer.cc b/ui/message_center/popup_timer.cc index aa45d06..f2f9c5e0 100644 --- a/ui/message_center/popup_timer.cc +++ b/ui/message_center/popup_timer.cc
@@ -11,21 +11,20 @@ #include "ui/message_center/notification.h" #include "ui/message_center/notification_list.h" +namespace message_center { + namespace { -base::TimeDelta GetTimeoutForPriority(int priority) { - if (priority > message_center::DEFAULT_PRIORITY) { - return base::TimeDelta::FromSeconds( - message_center::kAutocloseHighPriorityDelaySeconds); - } - return base::TimeDelta::FromSeconds( - message_center::kAutocloseDefaultDelaySeconds); +base::TimeDelta GetTimeoutForNotification(Notification* notification) { + if (notification->priority() > message_center::DEFAULT_PRIORITY) + return base::TimeDelta::FromSeconds(kAutocloseHighPriorityDelaySeconds); + if (notification->is_web_notification()) + return base::TimeDelta::FromSeconds(kAutocloseWebNotificationDelaySeconds); + return base::TimeDelta::FromSeconds(kAutocloseDefaultDelaySeconds); } } // namespace -namespace message_center { - //////////////////////////////////////////////////////////////////////////////// // PopupTimer @@ -165,7 +164,7 @@ // Start the timer if not yet. if (popup_timers_.find(id) == popup_timers_.end()) - StartTimer(id, GetTimeoutForPriority((*iter)->priority())); + StartTimer(id, GetTimeoutForNotification(*iter)); } void PopupTimersController::OnNotificationRemoved(const std::string& id,
diff --git a/ui/ozone/common/stub_client_native_pixmap_factory.cc b/ui/ozone/common/stub_client_native_pixmap_factory.cc index d076a0c..112a7ff 100644 --- a/ui/ozone/common/stub_client_native_pixmap_factory.cc +++ b/ui/ozone/common/stub_client_native_pixmap_factory.cc
@@ -15,8 +15,9 @@ // ClientNativePixmapFactory: void Initialize(base::ScopedFD device_fd) override {} - std::vector<Configuration> GetSupportedConfigurations() const override { - return std::vector<Configuration>(); + bool IsConfigurationSupported(gfx::BufferFormat format, + gfx::BufferUsage usage) const override { + return false; } scoped_ptr<ClientNativePixmap> ImportFromHandle( const gfx::NativePixmapHandle& handle,
diff --git a/ui/ozone/platform/drm/common/client_native_pixmap_factory_gbm.cc b/ui/ozone/platform/drm/common/client_native_pixmap_factory_gbm.cc index af7042d44..f5dfd78 100644 --- a/ui/ozone/platform/drm/common/client_native_pixmap_factory_gbm.cc +++ b/ui/ozone/platform/drm/common/client_native_pixmap_factory_gbm.cc
@@ -44,21 +44,23 @@ vgem_fd_ = device_fd.Pass(); #endif } - std::vector<Configuration> GetSupportedConfigurations() const override { - const Configuration kConfigurations[] = { - {gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::SCANOUT}, - {gfx::BufferFormat::BGRX_8888, gfx::BufferUsage::SCANOUT}}; - std::vector<Configuration> configurations( - kConfigurations, kConfigurations + arraysize(kConfigurations)); + bool IsConfigurationSupported(gfx::BufferFormat format, + gfx::BufferUsage usage) const override { + switch (usage) { + case gfx::BufferUsage::SCANOUT: + return format == gfx::BufferFormat::BGRA_8888 || + format == gfx::BufferFormat::BGRX_8888; + case gfx::BufferUsage::MAP: + case gfx::BufferUsage::PERSISTENT_MAP: { #if defined(USE_VGEM_MAP) - if (vgem_fd_.is_valid()) { - configurations.push_back( - {gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::MAP}); - configurations.push_back( - {gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::PERSISTENT_MAP}); - } + return vgem_fd_.is_valid() && format == gfx::BufferFormat::BGRA_8888; +#else + return false; #endif - return configurations; + } + } + NOTREACHED(); + return false; } scoped_ptr<ClientNativePixmap> ImportFromHandle( const gfx::NativePixmapHandle& handle,
diff --git a/ui/ozone/platform/drm/common/drm_util.cc b/ui/ozone/platform/drm/common/drm_util.cc index 845cb41..5e100873 100644 --- a/ui/ozone/platform/drm/common/drm_util.cc +++ b/ui/ozone/platform/drm/common/drm_util.cc
@@ -4,6 +4,7 @@ #include "ui/ozone/platform/drm/common/drm_util.h" +#include <drm_fourcc.h> #include <stdint.h> #include <stdlib.h> #include <sys/mman.h> @@ -264,4 +265,16 @@ return params; } +int GetFourCCFormatFromBufferFormat(gfx::BufferFormat format) { + switch (format) { + case gfx::BufferFormat::BGRA_8888: + return DRM_FORMAT_ARGB8888; + case gfx::BufferFormat::BGRX_8888: + return DRM_FORMAT_XRGB8888; + default: + NOTREACHED(); + return 0; + } +} + } // namespace ui
diff --git a/ui/ozone/platform/drm/common/drm_util.h b/ui/ozone/platform/drm/common/drm_util.h index e761aba2..a79700e9 100644 --- a/ui/ozone/platform/drm/common/drm_util.h +++ b/ui/ozone/platform/drm/common/drm_util.h
@@ -56,6 +56,8 @@ size_t display_index, const gfx::Point& origin); +int GetFourCCFormatFromBufferFormat(gfx::BufferFormat format); + } // namespace ui #endif // UI_OZONE_PLATFORM_DRM_COMMON_DRM_UTIL_H_
diff --git a/ui/ozone/platform/drm/gpu/drm_window.cc b/ui/ozone/platform/drm/gpu/drm_window.cc index 22e99cb..969224c4 100644 --- a/ui/ozone/platform/drm/gpu/drm_window.cc +++ b/ui/ozone/platform/drm/gpu/drm_window.cc
@@ -12,6 +12,7 @@ #include "third_party/skia/include/core/SkDevice.h" #include "third_party/skia/include/core/SkSurface.h" #include "ui/ozone/common/gpu/ozone_gpu_message_params.h" +#include "ui/ozone/platform/drm/common/drm_util.h" #include "ui/ozone/platform/drm/gpu/crtc_controller.h" #include "ui/ozone/platform/drm/gpu/drm_buffer.h" #include "ui/ozone/platform/drm/gpu/drm_device.h" @@ -34,20 +35,6 @@ void EmptyFlipCallback(gfx::SwapResult) { } -// TODO(kalyank): We now have this switch statement in GBMBuffer and here. -// It would be nice to have it in one place. -uint32_t GetFourCCFormatFromBufferFormat(gfx::BufferFormat format) { - switch (format) { - case gfx::BufferFormat::BGRA_8888: - return DRM_FORMAT_ARGB8888; - case gfx::BufferFormat::BGRX_8888: - return DRM_FORMAT_XRGB8888; - default: - NOTREACHED(); - return 0; - } -} - void UpdateCursorImage(DrmBuffer* cursor, const SkBitmap& image) { SkRect damage; image.getBounds(&damage);
diff --git a/ui/ozone/platform/drm/gpu/gbm_buffer.cc b/ui/ozone/platform/drm/gpu/gbm_buffer.cc index 045caad..117a52f7 100644 --- a/ui/ozone/platform/drm/gpu/gbm_buffer.cc +++ b/ui/ozone/platform/drm/gpu/gbm_buffer.cc
@@ -14,6 +14,7 @@ #include "base/trace_event/trace_event.h" #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/native_pixmap_handle_ozone.h" +#include "ui/ozone/platform/drm/common/drm_util.h" #include "ui/ozone/platform/drm/gpu/drm_window.h" #include "ui/ozone/platform/drm/gpu/gbm_device.h" #include "ui/ozone/platform/drm/gpu/gbm_surface_factory.h" @@ -21,22 +22,6 @@ namespace ui { -namespace { - -int GetGbmFormatFromBufferFormat(gfx::BufferFormat fmt) { - switch (fmt) { - case gfx::BufferFormat::BGRA_8888: - return GBM_FORMAT_ARGB8888; - case gfx::BufferFormat::BGRX_8888: - return GBM_FORMAT_XRGB8888; - default: - NOTREACHED(); - return 0; - } -} - -} // namespace - GbmBuffer::GbmBuffer(const scoped_refptr<GbmDevice>& gbm, gbm_bo* bo, gfx::BufferUsage usage) @@ -62,7 +47,7 @@ if (use_scanout) flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING; gbm_bo* bo = gbm_bo_create(gbm->device(), size.width(), size.height(), - GetGbmFormatFromBufferFormat(format), flags); + GetFourCCFormatFromBufferFormat(format), flags); if (!bo) return nullptr;
diff --git a/ui/ozone/public/client_native_pixmap_factory.h b/ui/ozone/public/client_native_pixmap_factory.h index 943547c..f0593b5c 100644 --- a/ui/ozone/public/client_native_pixmap_factory.h +++ b/ui/ozone/public/client_native_pixmap_factory.h
@@ -34,13 +34,9 @@ // Initialize with the given client native pixmap |device_fd|. virtual void Initialize(base::ScopedFD device_fd) = 0; - struct Configuration { - gfx::BufferFormat format; - gfx::BufferUsage usage; - }; - - // Gets supported format/usage configurations. - virtual std::vector<Configuration> GetSupportedConfigurations() const = 0; + // Returns true if format/usage configuration is supported. + virtual bool IsConfigurationSupported(gfx::BufferFormat format, + gfx::BufferUsage usage) const = 0; // TODO(dshwang): implement it. crbug.com/475633 // Import the native pixmap from |handle| to be used in non-GPU processes.
diff --git a/ui/snapshot/snapshot_mac.mm b/ui/snapshot/snapshot_mac.mm index aa4048e..d1eb698 100644 --- a/ui/snapshot/snapshot_mac.mm +++ b/ui/snapshot/snapshot_mac.mm
@@ -20,7 +20,7 @@ std::vector<unsigned char>* png_representation, const gfx::Rect& snapshot_bounds) { NSWindow* window = [view window]; - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* screen = [[NSScreen screens] firstObject]; gfx::Rect screen_bounds = gfx::Rect(NSRectToCGRect([screen frame]));
diff --git a/ui/views/event_monitor_mac.mm b/ui/views/event_monitor_mac.mm index cb3e54e9..45578c9 100644 --- a/ui/views/event_monitor_mac.mm +++ b/ui/views/event_monitor_mac.mm
@@ -30,7 +30,7 @@ gfx::Point EventMonitor::GetLastMouseLocation() { NSPoint mouseLocation = [NSEvent mouseLocation]; // Flip coordinates to gfx (0,0 in top-left corner) using primary screen. - NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + NSScreen* screen = [[NSScreen screens] firstObject]; mouseLocation.y = NSMaxY([screen frame]) - mouseLocation.y; return gfx::Point(mouseLocation.x, mouseLocation.y); }
diff --git a/ui/views/widget/native_widget_mac_unittest.mm b/ui/views/widget/native_widget_mac_unittest.mm index 0ff4fbf2..2670ed6b 100644 --- a/ui/views/widget/native_widget_mac_unittest.mm +++ b/ui/views/widget/native_widget_mac_unittest.mm
@@ -1081,7 +1081,7 @@ params.bounds = gfx::Rect(100, 100, 300, 200); widget.Init(params); widget.Show(); - NSRect expected = [[[NSScreen screens] objectAtIndex:0] visibleFrame]; + NSRect expected = [[[NSScreen screens] firstObject] visibleFrame]; NSRect actual = gfx::ScreenRectToNSRect(widget.GetWorkAreaBoundsInScreen()); EXPECT_FALSE(NSIsEmptyRect(actual)); EXPECT_NSEQ(expected, actual);
diff --git a/ui/webui/resources/cr_elements/v1_0/network/cr_network_list.html b/ui/webui/resources/cr_elements/v1_0/network/cr_network_list.html index 73562a4..00c701d 100644 --- a/ui/webui/resources/cr_elements/v1_0/network/cr_network_list.html +++ b/ui/webui/resources/cr_elements/v1_0/network/cr_network_list.html
@@ -11,7 +11,7 @@ <div id="container" class="layout vertical flex"> <template is="dom-repeat" items="[[networks]]"> <cr-network-list-item network-state="[[item]]" - list-item-type="[[listType]]" on-click="onSelected_"> + list-item-type="[[listType]]" on-tap="onTap_"> </cr-network-list-item> </template> </div>
diff --git a/ui/webui/resources/cr_elements/v1_0/network/cr_network_list.js b/ui/webui/resources/cr_elements/v1_0/network/cr_network_list.js index 070614a9..04962be3 100644 --- a/ui/webui/resources/cr_elements/v1_0/network/cr_network_list.js +++ b/ui/webui/resources/cr_elements/v1_0/network/cr_network_list.js
@@ -64,12 +64,12 @@ }, /** - * Event triggered when a list item is selected. + * Event triggered when a list item is tapped. * @param {!{model: {item: !CrOnc.NetworkStateProperties}}} event * @private */ - onSelected_: function(event) { + onTap_: function(event) { this.fire('selected', event.model.item); - } + }, }); })();
diff --git a/ui/webui/resources/cr_elements/v1_0/network/cr_network_list_item.css b/ui/webui/resources/cr_elements/v1_0/network/cr_network_list_item.css index 3f1154d..0f1b10f9 100644 --- a/ui/webui/resources/cr_elements/v1_0/network/cr_network_list_item.css +++ b/ui/webui/resources/cr_elements/v1_0/network/cr_network_list_item.css
@@ -58,8 +58,17 @@ font-size: 14px; } -#divButtons paper-icon-button { +.buttons { + align-items: center; + display: flex; + flex-direction: row; +} + +.buttons paper-icon-button { text-align: center; +} + +.known paper-icon-button { width: 60px; }
diff --git a/ui/webui/resources/cr_elements/v1_0/network/cr_network_list_item.html b/ui/webui/resources/cr_elements/v1_0/network/cr_network_list_item.html index 869316c..ef98ac0 100644 --- a/ui/webui/resources/cr_elements/v1_0/network/cr_network_list_item.html +++ b/ui/webui/resources/cr_elements/v1_0/network/cr_network_list_item.html
@@ -19,17 +19,22 @@ <span id="networkStateText" hidden$="[[isListItem_(listItemType)]]"> </span> </div> - <div id="divButtons" class="layout horizontal center" + <div class="buttons" + hidden$="[[!isListItemType_(listItemType, 'visible')]]"> + <paper-icon-button icon="settings" on-tap="fireShowDetails_"> + </paper-icon-button> + </div> + <div class="known buttons" hidden$="[[!isListItemType_(listItemType, 'known')]]"> <paper-icon-button icon="[[sharedIcon_(networkState)]]" disabled> </paper-icon-button> <paper-icon-button icon="[[preferredIcon_(networkState)]]" disabled$="[[isPolicyManaged_(networkState)]]" - on-click="fireTogglePreferred_"> + on-tap="fireTogglePreferred_"> </paper-icon-button> <paper-icon-button icon="clear" disabled$="[[isPolicyManaged_(networkState)]]" - on-click="fireRemove_"> + on-tap="fireRemove_"> </paper-icon-button> </div> </div>
diff --git a/ui/webui/resources/cr_elements/v1_0/network/cr_network_list_item.js b/ui/webui/resources/cr_elements/v1_0/network/cr_network_list_item.js index 6b6aefd05..84d2c137 100644 --- a/ui/webui/resources/cr_elements/v1_0/network/cr_network_list_item.js +++ b/ui/webui/resources/cr_elements/v1_0/network/cr_network_list_item.js
@@ -158,6 +158,16 @@ }, /** + * Fires a 'show-details' event with |this.networkState| as the details. + * @param {Event} event + * @private + */ + fireShowDetails_: function(event) { + this.fire('show-detail', this.networkState); + event.stopPropagation(); + }, + + /** * Fires the 'toggle-preferred' event with |this.networkState| as the details. * @param {Event} event * @private
diff --git a/ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js b/ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js index 8ff05c4..1d78635 100644 --- a/ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js +++ b/ui/webui/resources/cr_elements/v1_0/network/cr_onc_types.js
@@ -257,31 +257,42 @@ var type = properties.Type; if (type == CrOnc.Type.CELLULAR && properties.Cellular) return properties.Cellular.SignalStrength || 0; - else if (type == CrOnc.Type.WI_FI && properties.WiFi) + if (type == CrOnc.Type.WI_FI && properties.WiFi) return properties.WiFi.SignalStrength || 0; - else if (type == CrOnc.Type.WI_MAX && properties.WiMAX) + if (type == CrOnc.Type.WI_MAX && properties.WiMAX) return properties.WiMAX.SignalStrength || 0; return 0; } /** + * Gets the Managed AutoConnect dictionary from |properties| based on + * properties.Type. + * @param {!CrOnc.NetworkProperties|undefined} + * properties The ONC network properties or state properties. + * @return {!chrome.networkingPrivate.ManagedBoolean|undefined} The AutoConnect + * managed dictionary or undefined. + */ +CrOnc.getManagedAutoConnect = function(properties) { + var type = properties.Type; + if (type == CrOnc.Type.CELLULAR && properties.Cellular) + return properties.Cellular.AutoConnect; + if (type == CrOnc.Type.VPN && properties.VPN) + return properties.VPN.AutoConnect; + if (type == CrOnc.Type.WI_FI && properties.WiFi) + return properties.WiFi.AutoConnect; + if (type == CrOnc.Type.WI_MAX && properties.WiMAX) + return properties.WiMAX.AutoConnect; + return undefined; +} + +/** * Gets the AutoConnect value from |properties| based on properties.Type. * @param {!CrOnc.NetworkProperties|undefined} * properties The ONC network properties or state properties. * @return {boolean} The AutoConnect value if it exists or false. */ CrOnc.getAutoConnect = function(properties) { - var type = properties.Type; - /** @type {!chrome.networkingPrivate.ManagedBoolean|undefined} */ - var autoconnect; - if (type == CrOnc.Type.CELLULAR && properties.Cellular) - autoconnect = properties.Cellular.AutoConnect; - else if (type == CrOnc.Type.VPN && properties.VPN) - autoconnect = properties.VPN.AutoConnect; - else if (type == CrOnc.Type.WI_FI && properties.WiFi) - autoconnect = properties.WiFi.AutoConnect; - else if (type == CrOnc.Type.WI_MAX && properties.WiMAX) - autoconnect = properties.WiMAX.AutoConnect; + var autoconnect = CrOnc.getManagedAutoConnect(properties); return !!CrOnc.getActiveValue(autoconnect); }