diff --git a/DEPS b/DEPS index 3363f0e..9dd07c7 100644 --- a/DEPS +++ b/DEPS
@@ -40,7 +40,7 @@ # 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': '63afe64a5f33a61235706dbec0f0cc695c88469b', + 'skia_revision': '99d4721171f9b8f23cd907ef3da938c4c5579ae9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '00d4064e5414fc0845e354b50c7f1a8323449268', + 'pdfium_revision': 'c8017b2581b7ade6b05ba086eb7221465414173f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -88,7 +88,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling NaCl # and whatever else without interference from each other. - 'nacl_revision': 'afa90269512fe22519d7a8445e0d54a177d63f42', + 'nacl_revision': '70540f6583440d4174e6d75743bb544cfbaaf204', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype-android # and whatever else without interference from each other. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '2c3f1f3d69c01170e93ab32a441b51b1712016c1', + 'catapult_revision': '4ee31ea3b497ffe08391e88a5434e0a340e48342', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/android_webview/java/src/org/chromium/android_webview/AwActionModeCallback.java b/android_webview/java/src/org/chromium/android_webview/AwActionModeCallback.java index 82b4595a..2c54cdd 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwActionModeCallback.java +++ b/android_webview/java/src/org/chromium/android_webview/AwActionModeCallback.java
@@ -93,7 +93,7 @@ RecordUserAction.record("MobileActionMode.ProcessTextIntent"); assert Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; - String query = mHelper.sanitizeQuery(mHelper.getSelectedText(), + String query = ActionModeCallbackHelper.sanitizeQuery(mHelper.getSelectedText(), ActionModeCallbackHelper.MAX_SEARCH_QUERY_LENGTH); if (TextUtils.isEmpty(query)) return;
diff --git a/ash/common/system/tray/tray_details_view.cc b/ash/common/system/tray/tray_details_view.cc index 9fbe9c6..4a5fecd 100644 --- a/ash/common/system/tray/tray_details_view.cc +++ b/ash/common/system/tray/tray_details_view.cc
@@ -23,7 +23,7 @@ #include "ui/compositor/paint_context.h" #include "ui/compositor/paint_recorder.h" #include "ui/gfx/canvas.h" -#include "ui/gfx/skia_util.h" +#include "ui/gfx/skia_paint_util.h" #include "ui/views/background.h" #include "ui/views/border.h" #include "ui/views/controls/label.h"
diff --git a/ash/magnifier/partial_magnification_controller.cc b/ash/magnifier/partial_magnification_controller.cc index a9184eb8..61feab3 100644 --- a/ash/magnifier/partial_magnification_controller.cc +++ b/ash/magnifier/partial_magnification_controller.cc
@@ -14,6 +14,7 @@ #include "ui/events/event.h" #include "ui/events/event_constants.h" #include "ui/gfx/shadow_value.h" +#include "ui/gfx/skia_paint_util.h" #include "ui/views/widget/widget.h" #include "ui/wm/core/coordinate_conversion.h"
diff --git a/base/android/application_status_listener_unittest.cc b/base/android/application_status_listener_unittest.cc index a6f098b..803dedb 100644 --- a/base/android/application_status_listener_unittest.cc +++ b/base/android/application_status_listener_unittest.cc
@@ -69,9 +69,6 @@ APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES); event_.Wait(); EXPECT_EQ(APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES, state_); - - // Delete |listener_| on the thread on which it was created. - thread_.task_runner()->DeleteSoon(FROM_HERE, listener_.release()); } private:
diff --git a/base/observer_list_threadsafe.h b/base/observer_list_threadsafe.h index f8481de..afb1010 100644 --- a/base/observer_list_threadsafe.h +++ b/base/observer_list_threadsafe.h
@@ -5,48 +5,52 @@ #ifndef BASE_OBSERVER_LIST_THREADSAFE_H_ #define BASE_OBSERVER_LIST_THREADSAFE_H_ -#include <unordered_map> +#include <algorithm> +#include <map> +#include <memory> +#include <tuple> #include "base/bind.h" #include "base/location.h" #include "base/logging.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "base/observer_list.h" -#include "base/sequenced_task_runner.h" -#include "base/stl_util.h" -#include "base/synchronization/lock.h" -#include "base/threading/sequenced_task_runner_handle.h" -#include "base/threading/thread_local.h" -#include "build/build_config.h" - -// TODO(fdoray): Removing these includes causes IWYU failures in other headers, -// remove them in a follow- up CL. -#include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" +#include "base/threading/platform_thread.h" +#include "base/threading/thread_task_runner_handle.h" /////////////////////////////////////////////////////////////////////////////// // // OVERVIEW: // -// A thread-safe container for a list of observers. This is similar to the -// observer_list (see observer_list.h), but it is more robust for multi- -// threaded situations. +// A thread-safe container for a list of observers. +// This is similar to the observer_list (see observer_list.h), but it +// is more robust for multi-threaded situations. // // The following use cases are supported: -// * Observers can register for notifications from any sequence. They are -// always notified on the sequence from which they were registered. -// * Any sequence may trigger a notification via Notify(). -// * Observers can remove themselves from the observer list inside of a -// callback. -// * If one sequence is notifying observers concurrently with an observer -// removing itself from the observer list, the notifications will be -// silently dropped. +// * Observers can register for notifications from any thread. +// Callbacks to the observer will occur on the same thread where +// the observer initially called AddObserver() from. +// * Any thread may trigger a notification via Notify(). +// * Observers can remove themselves from the observer list inside +// of a callback. +// * If one thread is notifying observers concurrently with an observer +// removing itself from the observer list, the notifications will +// be silently dropped. // -// The drawback of the threadsafe observer list is that notifications are not -// as real-time as the non-threadsafe version of this class. Notifications -// will always be done via PostTask() to another sequence, whereas with the -// non-thread-safe observer_list, notifications happen synchronously. +// The drawback of the threadsafe observer list is that notifications +// are not as real-time as the non-threadsafe version of this class. +// Notifications will always be done via PostTask() to another thread, +// whereas with the non-thread-safe observer_list, notifications happen +// synchronously and immediately. +// +// IMPLEMENTATION NOTES +// The ObserverListThreadSafe maintains an ObserverList for each thread +// which uses the ThreadSafeObserver. When Notifying the observers, +// we simply call PostTask to each registered thread, and then each thread +// will notify its regular ObserverList. // /////////////////////////////////////////////////////////////////////////////// @@ -73,72 +77,68 @@ using NotificationType = typename ObserverList<ObserverType>::NotificationType; - ObserverListThreadSafe() = default; + ObserverListThreadSafe() + : type_(ObserverListBase<ObserverType>::NOTIFY_ALL) {} explicit ObserverListThreadSafe(NotificationType type) : type_(type) {} - // Adds |observer| to the list. |observer| must not already be in the list. - void AddObserver(ObserverType* observer) { - // TODO(fdoray): Change this to a DCHECK once all call sites have a - // SequencedTaskRunnerHandle. - if (!SequencedTaskRunnerHandle::IsSet()) + // Add an observer to the list. An observer should not be added to + // the same list more than once. + void AddObserver(ObserverType* obs) { + // If there is no ThreadTaskRunnerHandle, it is impossible to notify on it, + // so do not add the observer. + if (!ThreadTaskRunnerHandle::IsSet()) return; - AutoLock auto_lock(lock_); - - // Add |observer| to the list of observers. - DCHECK(!ContainsKey(observers_, observer)); - const scoped_refptr<SequencedTaskRunner> task_runner = - SequencedTaskRunnerHandle::Get(); - observers_[observer] = task_runner; - - // If this is called while a notification is being dispatched on this thread - // and |type_| is NOTIFY_ALL, |observer| must be notified (if a notification - // is being dispatched on another thread in parallel, the notification may - // or may not make it to |observer| depending on the outcome of the race to - // |lock_|). - if (type_ == NotificationType::NOTIFY_ALL) { - const NotificationData* current_notification = - tls_current_notification_.Get(); - if (current_notification) { - task_runner->PostTask( - current_notification->from_here, - Bind(&ObserverListThreadSafe<ObserverType>::NotifyWrapper, this, - observer, *current_notification)); + ObserverList<ObserverType>* list = nullptr; + PlatformThreadId thread_id = PlatformThread::CurrentId(); + { + AutoLock lock(list_lock_); + if (observer_lists_.find(thread_id) == observer_lists_.end()) { + observer_lists_[thread_id] = + base::MakeUnique<ObserverListContext>(type_); } + list = &(observer_lists_[thread_id]->list); } + list->AddObserver(obs); } // Remove an observer from the list if it is in the list. // If there are pending notifications in-transit to the observer, they will // be aborted. // If the observer to be removed is in the list, RemoveObserver MUST - // be called from the same sequence which called AddObserver. - void RemoveObserver(ObserverType* observer) { - AutoLock auto_lock(lock_); - auto it = observers_.find(observer); - if (it == observers_.end()) - return; + // be called from the same thread which called AddObserver. + void RemoveObserver(ObserverType* obs) { + PlatformThreadId thread_id = PlatformThread::CurrentId(); + { + AutoLock lock(list_lock_); + auto it = observer_lists_.find(thread_id); + if (it == observer_lists_.end()) { + // This will happen if we try to remove an observer on a thread + // we never added an observer for. + return; + } + ObserverList<ObserverType>& list = it->second->list; - // TODO(fdoray): Enable this on Android once all tests pass. -#if !defined(OS_ANDROID) - DCHECK(it->second->RunsTasksOnCurrentThread()); -#endif + list.RemoveObserver(obs); - observers_.erase(it); + // If that was the last observer in the list, remove the ObserverList + // entirely. + if (list.size() == 0) + observer_lists_.erase(it); + } } // Verifies that the list is currently empty (i.e. there are no observers). void AssertEmpty() const { -#if DCHECK_IS_ON() - AutoLock auto_lock(lock_); - DCHECK(observers_.empty()); -#endif + AutoLock lock(list_lock_); + DCHECK(observer_lists_.empty()); } - // Asynchronously invokes a callback on all observers, on their registration - // sequence. You cannot assume that at the completion of the Notify call that - // all Observers have been Notified. The notification may still be pending - // delivery. + // Notify methods. + // Make a thread-safe callback to each Observer in the list. + // Note, these calls are effectively asynchronous. You cannot assume + // that at the completion of the Notify call that all Observers have + // been Notified. The notification may still be pending delivery. template <typename Method, typename... Params> void Notify(const tracked_objects::Location& from_here, Method m, Params&&... params) { @@ -146,71 +146,79 @@ Bind(&internal::Dispatcher<ObserverType, Method>::Run, m, std::forward<Params>(params)...); - AutoLock lock(lock_); - for (const auto& observer : observers_) { - observer.second->PostTask( + AutoLock lock(list_lock_); + for (const auto& entry : observer_lists_) { + ObserverListContext* context = entry.second.get(); + context->task_runner->PostTask( from_here, - Bind(&ObserverListThreadSafe<ObserverType>::NotifyWrapper, this, - observer.first, NotificationData(from_here, method))); + Bind(&ObserverListThreadSafe<ObserverType>::NotifyWrapper, + this, context, method)); } } private: friend class RefCountedThreadSafe<ObserverListThreadSafe<ObserverType>>; - struct NotificationData { - NotificationData(const tracked_objects::Location& from_here_in, - const Callback<void(ObserverType*)>& method_in) - : from_here(from_here_in), method(method_in) {} + struct ObserverListContext { + explicit ObserverListContext(NotificationType type) + : task_runner(ThreadTaskRunnerHandle::Get()), list(type) {} - tracked_objects::Location from_here; - Callback<void(ObserverType*)> method; + scoped_refptr<SingleThreadTaskRunner> task_runner; + ObserverList<ObserverType> list; + + private: + DISALLOW_COPY_AND_ASSIGN(ObserverListContext); }; - ~ObserverListThreadSafe() = default; - - void NotifyWrapper(ObserverType* observer, - const NotificationData& notification) { - { - AutoLock auto_lock(lock_); - - // Check whether the observer still needs a notification. - auto it = observers_.find(observer); - if (it == observers_.end()) - return; - DCHECK(it->second->RunsTasksOnCurrentThread()); - } - - // Keep track of the notification being dispatched on the current thread. - // This will be used if the callback below calls AddObserver(). - // - // Note: |tls_current_notification_| may not be nullptr if this runs in a - // nested loop started by a notification callback. In that case, it is - // important to save the previous value to restore it later. - const NotificationData* const previous_notification = - tls_current_notification_.Get(); - tls_current_notification_.Set(¬ification); - - // Invoke the callback. - notification.method.Run(observer); - - // Reset the notification being dispatched on the current thread to its - // previous value. - tls_current_notification_.Set(previous_notification); + ~ObserverListThreadSafe() { } - const NotificationType type_ = NotificationType::NOTIFY_ALL; + // Wrapper which is called to fire the notifications for each thread's + // ObserverList. This function MUST be called on the thread which owns + // the unsafe ObserverList. + void NotifyWrapper(ObserverListContext* context, + const Callback<void(ObserverType*)>& method) { + // Check that this list still needs notifications. + { + AutoLock lock(list_lock_); + auto it = observer_lists_.find(PlatformThread::CurrentId()); - // Synchronizes access to |observers_|. - mutable Lock lock_; + // The ObserverList could have been removed already. In fact, it could + // have been removed and then re-added! If the master list's loop + // does not match this one, then we do not need to finish this + // notification. + if (it == observer_lists_.end() || it->second.get() != context) + return; + } - // Keys are observers. Values are the SequencedTaskRunners on which they must - // be notified. - std::unordered_map<ObserverType*, scoped_refptr<SequencedTaskRunner>> - observers_; + for (auto& observer : context->list) { + method.Run(&observer); + } - // Notification being dispatched on the current thread. - ThreadLocalPointer<const NotificationData> tls_current_notification_; + // If there are no more observers on the list, we can now delete it. + if (context->list.size() == 0) { + { + AutoLock lock(list_lock_); + // Remove |list| if it's not already removed. + // This can happen if multiple observers got removed in a notification. + // See http://crbug.com/55725. + auto it = observer_lists_.find(PlatformThread::CurrentId()); + if (it != observer_lists_.end() && it->second.get() == context) + observer_lists_.erase(it); + } + } + } + + mutable Lock list_lock_; // Protects the observer_lists_. + + // Key by PlatformThreadId because in tests, clients can attempt to remove + // observers without a SingleThreadTaskRunner. If this were keyed by + // SingleThreadTaskRunner, that operation would be silently ignored, leaving + // garbage in the ObserverList. + std::map<PlatformThreadId, std::unique_ptr<ObserverListContext>> + observer_lists_; + + const NotificationType type_; DISALLOW_COPY_AND_ASSIGN(ObserverListThreadSafe); };
diff --git a/base/observer_list_unittest.cc b/base/observer_list_unittest.cc index 653d881..c5e556b 100644 --- a/base/observer_list_unittest.cc +++ b/base/observer_list_unittest.cc
@@ -5,18 +5,13 @@ #include "base/observer_list.h" #include "base/observer_list_threadsafe.h" -#include <utility> #include <vector> -#include "base/bind.h" #include "base/compiler_specific.h" #include "base/location.h" #include "base/memory/weak_ptr.h" #include "base/run_loop.h" -#include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" -#include "base/task_scheduler/post_task.h" -#include "base/test/scoped_task_scheduler.h" #include "base/threading/platform_thread.h" #include "testing/gtest/include/gtest/gtest.h" @@ -70,6 +65,20 @@ bool remove_self_; }; +class ThreadSafeDisrupter : public Foo { + public: + ThreadSafeDisrupter(ObserverListThreadSafe<Foo>* list, Foo* doomed) + : list_(list), + doomed_(doomed) { + } + ~ThreadSafeDisrupter() override {} + void Observe(int x) override { list_->RemoveObserver(doomed_); } + + private: + ObserverListThreadSafe<Foo>* list_; + Foo* doomed_; +}; + template <typename ObserverListType> class AddInObserve : public Foo { public: @@ -267,6 +276,7 @@ Adder b(-1); Adder c(1); Adder d(-1); + ThreadSafeDisrupter evil(observer_list.get(), &c); observer_list->AddObserver(&a); observer_list->AddObserver(&b); @@ -274,11 +284,11 @@ observer_list->Notify(FROM_HERE, &Foo::Observe, 10); RunLoop().RunUntilIdle(); + observer_list->AddObserver(&evil); observer_list->AddObserver(&c); observer_list->AddObserver(&d); observer_list->Notify(FROM_HERE, &Foo::Observe, 10); - observer_list->RemoveObserver(&c); RunLoop().RunUntilIdle(); EXPECT_EQ(20, a.total); @@ -319,18 +329,18 @@ EXPECT_EQ(0, b.total); } -TEST(ObserverListThreadSafeTest, WithoutSequence) { +TEST(ObserverListThreadSafeTest, WithoutMessageLoop) { scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( new ObserverListThreadSafe<Foo>); Adder a(1), b(1), c(1); - // No sequence, so these should not be added. + // No MessageLoop, so these should not be added. observer_list->AddObserver(&a); observer_list->AddObserver(&b); { - // Add c when there's a sequence. + // Add c when there's a loop. MessageLoop loop; observer_list->AddObserver(&c); @@ -341,10 +351,10 @@ EXPECT_EQ(0, b.total); EXPECT_EQ(10, c.total); - // Now add a when there's a sequence. + // Now add a when there's a loop. observer_list->AddObserver(&a); - // Remove c when there's a sequence. + // Remove c when there's a loop. observer_list->RemoveObserver(&c); // Notify again. @@ -356,7 +366,7 @@ EXPECT_EQ(10, c.total); } - // Removing should always succeed with or without a sequence. + // Removing should always succeed with or without a loop. observer_list->RemoveObserver(&a); // Notifying should not fail but should also be a no-op. @@ -481,79 +491,6 @@ observer_list->Notify(FROM_HERE, &Foo::Observe, 1); } -namespace { - -class SequenceVerificationObserver : public Foo { - public: - explicit SequenceVerificationObserver( - scoped_refptr<SequencedTaskRunner> task_runner) - : task_runner_(std::move(task_runner)) {} - ~SequenceVerificationObserver() override = default; - - void Observe(int x) override { - called_on_valid_sequence_ = task_runner_->RunsTasksOnCurrentThread(); - } - - bool called_on_valid_sequence() const { return called_on_valid_sequence_; } - - private: - const scoped_refptr<SequencedTaskRunner> task_runner_; - bool called_on_valid_sequence_ = false; - - DISALLOW_COPY_AND_ASSIGN(SequenceVerificationObserver); -}; - -} // namespace - -// Verify that observers are notified on the correct sequence. -TEST(ObserverListThreadSafeTest, NotificationOnValidSequence) { - test::ScopedTaskScheduler scoped_task_scheduler; - - auto task_runner_1 = CreateSequencedTaskRunnerWithTraits(TaskTraits()); - auto task_runner_2 = CreateSequencedTaskRunnerWithTraits(TaskTraits()); - - auto observer_list = make_scoped_refptr(new ObserverListThreadSafe<Foo>()); - - SequenceVerificationObserver observer_1(task_runner_1); - SequenceVerificationObserver observer_2(task_runner_2); - - task_runner_1->PostTask( - FROM_HERE, Bind(&ObserverListThreadSafe<Foo>::AddObserver, observer_list, - Unretained(&observer_1))); - task_runner_2->PostTask( - FROM_HERE, Bind(&ObserverListThreadSafe<Foo>::AddObserver, observer_list, - Unretained(&observer_2))); - - RunLoop().RunUntilIdle(); - - observer_list->Notify(FROM_HERE, &Foo::Observe, 1); - - RunLoop().RunUntilIdle(); - - EXPECT_TRUE(observer_1.called_on_valid_sequence()); - EXPECT_TRUE(observer_2.called_on_valid_sequence()); -} - -// Verify that when an observer is added to a NOTIFY_ALL ObserverListThreadSafe -// from a notification, it is itself notified. -TEST(ObserverListThreadSafeTest, AddObserverFromNotificationNotifyAll) { - MessageLoop message_loop; - auto observer_list = make_scoped_refptr(new ObserverListThreadSafe<Foo>()); - - Adder observer_added_from_notification(1); - - AddInObserve<ObserverListThreadSafe<Foo>> initial_observer( - observer_list.get()); - initial_observer.SetToAdd(&observer_added_from_notification); - observer_list->AddObserver(&initial_observer); - - observer_list->Notify(FROM_HERE, &Foo::Observe, 1); - - RunLoop().RunUntilIdle(); - - EXPECT_EQ(1, observer_added_from_notification.GetValue()); -} - TEST(ObserverListTest, Existing) { ObserverList<Foo> observer_list(ObserverList<Foo>::NOTIFY_EXISTING_ONLY); Adder a(1);
diff --git a/cc/raster/bitmap_raster_buffer_provider.cc b/cc/raster/bitmap_raster_buffer_provider.cc index 5ff8e4f..3d6d0a4 100644 --- a/cc/raster/bitmap_raster_buffer_provider.cc +++ b/cc/raster/bitmap_raster_buffer_provider.cc
@@ -116,6 +116,20 @@ return true; } +bool BitmapRasterBufferProvider::IsResourceReadyToDraw( + ResourceId resource_id) const { + // Bitmap resources are immediately ready to draw. + return true; +} + +uint64_t BitmapRasterBufferProvider::SetReadyToDrawCallback( + const ResourceProvider::ResourceIdArray& resource_ids, + const base::Closure& callback, + uint64_t pending_callback_id) const { + // Bitmap resources are immediately ready to draw. + return 0; +} + void BitmapRasterBufferProvider::Shutdown() {} } // namespace cc
diff --git a/cc/raster/bitmap_raster_buffer_provider.h b/cc/raster/bitmap_raster_buffer_provider.h index ded16f5..d4e44e7 100644 --- a/cc/raster/bitmap_raster_buffer_provider.h +++ b/cc/raster/bitmap_raster_buffer_provider.h
@@ -37,6 +37,11 @@ ResourceFormat GetResourceFormat(bool must_support_alpha) const override; bool IsResourceSwizzleRequired(bool must_support_alpha) const override; bool CanPartialRasterIntoProvidedResource() const override; + bool IsResourceReadyToDraw(ResourceId id) const override; + uint64_t SetReadyToDrawCallback( + const ResourceProvider::ResourceIdArray& resource_ids, + const base::Closure& callback, + uint64_t pending_callback_id) const override; void Shutdown() override; protected:
diff --git a/cc/raster/gpu_raster_buffer_provider.cc b/cc/raster/gpu_raster_buffer_provider.cc index 97fb581..d874928 100644 --- a/cc/raster/gpu_raster_buffer_provider.cc +++ b/cc/raster/gpu_raster_buffer_provider.cc
@@ -17,6 +17,7 @@ #include "cc/playback/raster_source.h" #include "cc/raster/scoped_gpu_raster.h" #include "cc/resources/resource.h" +#include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "third_party/skia/include/core/SkMultiPictureDraw.h" #include "third_party/skia/include/core/SkPictureRecorder.h" @@ -186,6 +187,47 @@ return msaa_sample_count_ == 0; } +bool GpuRasterBufferProvider::IsResourceReadyToDraw( + ResourceId resource_id) const { + if (!async_worker_context_enabled_) + return true; + + ResourceProvider::ResourceIdArray resources; + resources.push_back(resource_id); + gpu::SyncToken sync_token = + resource_provider_->GetSyncTokenForResources(resources); + if (!sync_token.HasData()) + return true; + + // IsSyncTokenSignalled is threadsafe, no need for worker context lock. + return worker_context_provider_->ContextSupport()->IsSyncTokenSignalled( + sync_token); +} + +uint64_t GpuRasterBufferProvider::SetReadyToDrawCallback( + const ResourceProvider::ResourceIdArray& resource_ids, + const base::Closure& callback, + uint64_t pending_callback_id) const { + if (!async_worker_context_enabled_) + return 0; + + gpu::SyncToken sync_token = + resource_provider_->GetSyncTokenForResources(resource_ids); + uint64_t callback_id = sync_token.release_count(); + DCHECK_NE(callback_id, 0u); + + // If the callback is different from the one the caller is already waiting on, + // pass the callback through to SignalSinkToken. Otherwise the request is + // redundant. + if (callback_id != pending_callback_id) { + // SignalSyncToken is threadsafe, no need for worker context lock. + worker_context_provider_->ContextSupport()->SignalSyncToken(sync_token, + callback); + } + + return callback_id; +} + void GpuRasterBufferProvider::Shutdown() { pending_raster_buffers_.clear(); }
diff --git a/cc/raster/gpu_raster_buffer_provider.h b/cc/raster/gpu_raster_buffer_provider.h index 0df055b2..195eef84 100644 --- a/cc/raster/gpu_raster_buffer_provider.h +++ b/cc/raster/gpu_raster_buffer_provider.h
@@ -35,6 +35,11 @@ ResourceFormat GetResourceFormat(bool must_support_alpha) const override; bool IsResourceSwizzleRequired(bool must_support_alpha) const override; bool CanPartialRasterIntoProvidedResource() const override; + bool IsResourceReadyToDraw(ResourceId id) const override; + uint64_t SetReadyToDrawCallback( + const ResourceProvider::ResourceIdArray& resource_ids, + const base::Closure& callback, + uint64_t pending_callback_id) const override; void Shutdown() override; void PlaybackOnWorkerThread(
diff --git a/cc/raster/one_copy_raster_buffer_provider.cc b/cc/raster/one_copy_raster_buffer_provider.cc index 9f11314..0f34334 100644 --- a/cc/raster/one_copy_raster_buffer_provider.cc +++ b/cc/raster/one_copy_raster_buffer_provider.cc
@@ -21,6 +21,7 @@ #include "cc/resources/resource_util.h" #include "cc/resources/scoped_resource.h" #include "gpu/GLES2/gl2extchromium.h" +#include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" #include "ui/gfx/buffer_format_util.h" @@ -162,6 +163,47 @@ return false; } +bool OneCopyRasterBufferProvider::IsResourceReadyToDraw( + ResourceId resource_id) const { + if (!async_worker_context_enabled_) + return true; + + ResourceProvider::ResourceIdArray resources; + resources.push_back(resource_id); + gpu::SyncToken sync_token = + resource_provider_->GetSyncTokenForResources(resources); + if (!sync_token.HasData()) + return true; + + // IsSyncTokenSignalled is threadsafe, no need for worker context lock. + return worker_context_provider_->ContextSupport()->IsSyncTokenSignalled( + sync_token); +} + +uint64_t OneCopyRasterBufferProvider::SetReadyToDrawCallback( + const ResourceProvider::ResourceIdArray& resource_ids, + const base::Closure& callback, + uint64_t pending_callback_id) const { + if (!async_worker_context_enabled_) + return 0; + + gpu::SyncToken sync_token = + resource_provider_->GetSyncTokenForResources(resource_ids); + uint64_t callback_id = sync_token.release_count(); + DCHECK_NE(callback_id, 0u); + + // If the callback is different from the one the caller is already waiting on, + // pass the callback through to SignalSinkToken. Otherwise the request is + // redundant. + if (callback_id != pending_callback_id) { + // SignalSyncToken is threadsafe, no need for worker context lock. + worker_context_provider_->ContextSupport()->SignalSyncToken(sync_token, + callback); + } + + return callback_id; +} + void OneCopyRasterBufferProvider::Shutdown() { staging_pool_.Shutdown(); pending_raster_buffers_.clear();
diff --git a/cc/raster/one_copy_raster_buffer_provider.h b/cc/raster/one_copy_raster_buffer_provider.h index e1fa666..22e0dd5 100644 --- a/cc/raster/one_copy_raster_buffer_provider.h +++ b/cc/raster/one_copy_raster_buffer_provider.h
@@ -41,6 +41,11 @@ ResourceFormat GetResourceFormat(bool must_support_alpha) const override; bool IsResourceSwizzleRequired(bool must_support_alpha) const override; bool CanPartialRasterIntoProvidedResource() const override; + bool IsResourceReadyToDraw(ResourceId id) const override; + uint64_t SetReadyToDrawCallback( + const ResourceProvider::ResourceIdArray& resource_ids, + const base::Closure& callback, + uint64_t pending_callback_id) const override; void Shutdown() override; // Playback raster source and copy result into |resource|.
diff --git a/cc/raster/raster_buffer_provider.h b/cc/raster/raster_buffer_provider.h index 30dcc29..4804584 100644 --- a/cc/raster/raster_buffer_provider.h +++ b/cc/raster/raster_buffer_provider.h
@@ -12,6 +12,7 @@ #include "cc/raster/task_graph_runner.h" #include "cc/raster/tile_task.h" #include "cc/resources/resource_format.h" +#include "cc/resources/resource_provider.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" @@ -63,6 +64,20 @@ // the Resource provided in AcquireBufferForRaster. virtual bool CanPartialRasterIntoProvidedResource() const = 0; + // Returns true if the indicated resource is ready to draw. + virtual bool IsResourceReadyToDraw(ResourceId id) const = 0; + + // Calls the provided |callback| when the provided |resources| are ready to + // draw. Returns a callback ID which can be used to track this callback. + // Will return 0 if no callback is needed (resources are already ready to + // draw). The caller may optionally pass the ID of a pending callback to + // avoid creating a new callback unnecessarily. If the caller does not + // have a pending callback, 0 should be passed for |pending_callback_id|. + virtual uint64_t SetReadyToDrawCallback( + const ResourceProvider::ResourceIdArray& resource_ids, + const base::Callback<void()>& callback, + uint64_t pending_callback_id) const = 0; + // Shutdown for doing cleanup. virtual void Shutdown() = 0;
diff --git a/cc/raster/raster_buffer_provider_unittest.cc b/cc/raster/raster_buffer_provider_unittest.cc index 3b8668d..2f51ef7f 100644 --- a/cc/raster/raster_buffer_provider_unittest.cc +++ b/cc/raster/raster_buffer_provider_unittest.cc
@@ -16,6 +16,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" +#include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "cc/base/unique_notifier.h" @@ -47,7 +48,9 @@ enum RasterBufferProviderType { RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY, RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY, + RASTER_BUFFER_PROVIDER_TYPE_ASYNC_ONE_COPY, RASTER_BUFFER_PROVIDER_TYPE_GPU, + RASTER_BUFFER_PROVIDER_TYPE_ASYNC_GPU, RASTER_BUFFER_PROVIDER_TYPE_BITMAP }; @@ -62,13 +65,11 @@ class TestRasterTaskImpl : public TileTask { public: TestRasterTaskImpl(TestRasterTaskCompletionHandler* completion_handler, - std::unique_ptr<ScopedResource> resource, unsigned id, std::unique_ptr<RasterBuffer> raster_buffer, TileTask::Vector* dependencies) : TileTask(true, dependencies), completion_handler_(completion_handler), - resource_(std::move(resource)), id_(id), raster_buffer_(std::move(raster_buffer)), raster_source_(FakeRasterSource::CreateFilled(gfx::Size(1, 1))) {} @@ -96,7 +97,6 @@ private: TestRasterTaskCompletionHandler* completion_handler_; - std::unique_ptr<ScopedResource> resource_; unsigned id_; std::unique_ptr<RasterBuffer> raster_buffer_; scoped_refptr<RasterSource> raster_source_; @@ -108,13 +108,11 @@ public: BlockingTestRasterTaskImpl( TestRasterTaskCompletionHandler* completion_handler, - std::unique_ptr<ScopedResource> resource, unsigned id, std::unique_ptr<RasterBuffer> raster_buffer, base::Lock* lock, TileTask::Vector* dependencies) : TestRasterTaskImpl(completion_handler, - std::move(resource), id, std::move(raster_buffer), dependencies), @@ -172,12 +170,26 @@ kMaxBytesPerCopyOperation, false, kMaxStagingBuffers, PlatformColor::BestTextureFormat(), false); break; + case RASTER_BUFFER_PROVIDER_TYPE_ASYNC_ONE_COPY: + Create3dResourceProvider(); + raster_buffer_provider_ = base::MakeUnique<OneCopyRasterBufferProvider>( + base::ThreadTaskRunnerHandle::Get().get(), context_provider_.get(), + worker_context_provider_.get(), resource_provider_.get(), + kMaxBytesPerCopyOperation, false, kMaxStagingBuffers, + PlatformColor::BestTextureFormat(), true); + break; case RASTER_BUFFER_PROVIDER_TYPE_GPU: Create3dResourceProvider(); raster_buffer_provider_ = base::MakeUnique<GpuRasterBufferProvider>( context_provider_.get(), worker_context_provider_.get(), resource_provider_.get(), false, 0, false); break; + case RASTER_BUFFER_PROVIDER_TYPE_ASYNC_GPU: + Create3dResourceProvider(); + raster_buffer_provider_ = base::MakeUnique<GpuRasterBufferProvider>( + context_provider_.get(), worker_context_provider_.get(), + resource_provider_.get(), false, 0, true); + break; case RASTER_BUFFER_PROVIDER_TYPE_BITMAP: CreateSoftwareResourceProvider(); raster_buffer_provider_ = @@ -191,6 +203,7 @@ } void TearDown() override { + resources_.clear(); tile_task_manager_->Shutdown(); tile_task_manager_->CheckForCompletedTasks(); @@ -233,8 +246,9 @@ std::unique_ptr<RasterBuffer> raster_buffer = raster_buffer_provider_->AcquireBufferForRaster(resource.get(), 0, 0); TileTask::Vector empty; - tasks_.push_back(new TestRasterTaskImpl(this, std::move(resource), id, - std::move(raster_buffer), &empty)); + tasks_.push_back( + new TestRasterTaskImpl(this, id, std::move(raster_buffer), &empty)); + resources_.push_back(std::move(resource)); } void AppendTask(unsigned id) { AppendTask(id, gfx::Size(1, 1)); } @@ -251,7 +265,8 @@ raster_buffer_provider_->AcquireBufferForRaster(resource.get(), 0, 0); TileTask::Vector empty; tasks_.push_back(new BlockingTestRasterTaskImpl( - this, std::move(resource), id, std::move(raster_buffer), lock, &empty)); + this, id, std::move(raster_buffer), lock, &empty)); + resources_.push_back(std::move(resource)); } const std::vector<RasterTaskResult>& completed_tasks() const { @@ -313,6 +328,7 @@ bool timed_out_; RasterTaskVector tasks_; std::vector<RasterTaskResult> completed_tasks_; + std::vector<std::unique_ptr<ScopedResource>> resources_; TaskGraph graph_; }; @@ -382,12 +398,65 @@ EXPECT_FALSE(completed_tasks()[1].canceled); } -INSTANTIATE_TEST_CASE_P(RasterBufferProviderTests, - RasterBufferProviderTest, - ::testing::Values(RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY, - RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY, - RASTER_BUFFER_PROVIDER_TYPE_GPU, - RASTER_BUFFER_PROVIDER_TYPE_BITMAP)); +TEST_P(RasterBufferProviderTest, ReadyToDrawCallback) { + AppendTask(0u); + ScheduleTasks(); + RunMessageLoopUntilAllTasksHaveCompleted(); + + ResourceProvider::ResourceIdArray array; + for (const auto& resource : resources_) { + array.push_back(resource->id()); + } + base::RunLoop run_loop; + uint64_t callback_id = raster_buffer_provider_->SetReadyToDrawCallback( + array, + base::Bind([](base::RunLoop* run_loop) { run_loop->Quit(); }, &run_loop), + 0); + + if (GetParam() == RASTER_BUFFER_PROVIDER_TYPE_ASYNC_GPU || + GetParam() == RASTER_BUFFER_PROVIDER_TYPE_ASYNC_ONE_COPY) + EXPECT_TRUE(callback_id); + + if (!callback_id) + return; + + run_loop.Run(); +} + +TEST_P(RasterBufferProviderTest, ReadyToDrawCallbackNoDuplicate) { + AppendTask(0u); + ScheduleTasks(); + RunMessageLoopUntilAllTasksHaveCompleted(); + + ResourceProvider::ResourceIdArray array; + for (const auto& resource : resources_) { + array.push_back(resource->id()); + } + + uint64_t callback_id = raster_buffer_provider_->SetReadyToDrawCallback( + array, base::Bind([]() {}), 0); + + // Calling SetReadyToDrawCallback a second time for the same resources + // should return the same callback ID. + uint64_t callback_id_2 = raster_buffer_provider_->SetReadyToDrawCallback( + array, base::Bind([]() {}), 0); + + EXPECT_EQ(callback_id, callback_id_2); + + if (GetParam() == RASTER_BUFFER_PROVIDER_TYPE_ASYNC_GPU || + GetParam() == RASTER_BUFFER_PROVIDER_TYPE_ASYNC_ONE_COPY) + EXPECT_TRUE(callback_id); +} + +INSTANTIATE_TEST_CASE_P( + RasterBufferProviderTests, + RasterBufferProviderTest, + ::testing::Values(RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY, + RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY, + RASTER_BUFFER_PROVIDER_TYPE_ASYNC_ONE_COPY, + RASTER_BUFFER_PROVIDER_TYPE_GPU, + RASTER_BUFFER_PROVIDER_TYPE_ASYNC_GPU, + RASTER_BUFFER_PROVIDER_TYPE_BITMAP)); } // namespace } // namespace cc
diff --git a/cc/raster/zero_copy_raster_buffer_provider.cc b/cc/raster/zero_copy_raster_buffer_provider.cc index 17ef437..a4d02c65 100644 --- a/cc/raster/zero_copy_raster_buffer_provider.cc +++ b/cc/raster/zero_copy_raster_buffer_provider.cc
@@ -125,6 +125,20 @@ return false; } +bool ZeroCopyRasterBufferProvider::IsResourceReadyToDraw( + ResourceId resource_id) const { + // Zero-copy resources are immediately ready to draw. + return true; +} + +uint64_t ZeroCopyRasterBufferProvider::SetReadyToDrawCallback( + const ResourceProvider::ResourceIdArray& resource_ids, + const base::Closure& callback, + uint64_t pending_callback_id) const { + // Zero-copy resources are immediately ready to draw. + return 0; +} + void ZeroCopyRasterBufferProvider::Shutdown() {} } // namespace cc
diff --git a/cc/raster/zero_copy_raster_buffer_provider.h b/cc/raster/zero_copy_raster_buffer_provider.h index 6abf129..686ba7a 100644 --- a/cc/raster/zero_copy_raster_buffer_provider.h +++ b/cc/raster/zero_copy_raster_buffer_provider.h
@@ -39,6 +39,11 @@ ResourceFormat GetResourceFormat(bool must_support_alpha) const override; bool IsResourceSwizzleRequired(bool must_support_alpha) const override; bool CanPartialRasterIntoProvidedResource() const override; + bool IsResourceReadyToDraw(ResourceId id) const override; + uint64_t SetReadyToDrawCallback( + const ResourceProvider::ResourceIdArray& resource_ids, + const base::Closure& callback, + uint64_t pending_callback_id) const override; void Shutdown() override; protected:
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index 68311f8c..d0733c9f 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc
@@ -974,6 +974,17 @@ } } +gpu::SyncToken ResourceProvider::GetSyncTokenForResources( + const ResourceIdArray& resource_ids) { + gpu::SyncToken latest_sync_token; + for (ResourceId id : resource_ids) { + const gpu::SyncToken& sync_token = GetResource(id)->mailbox().sync_token(); + if (sync_token.release_count() > latest_sync_token.release_count()) + latest_sync_token = sync_token; + } + return latest_sync_token; +} + ResourceProvider::Resource* ResourceProvider::InsertResource( ResourceId id, Resource resource) {
diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h index 7f265b7..f03da6f 100644 --- a/cc/resources/resource_provider.h +++ b/cc/resources/resource_provider.h
@@ -165,6 +165,9 @@ void GenerateSyncTokenForResource(ResourceId resource_id); void GenerateSyncTokenForResources(const ResourceIdArray& resource_ids); + // Gets the most recent sync token from the indicated resources. + gpu::SyncToken GetSyncTokenForResources(const ResourceIdArray& resource_ids); + // Creates accounting for a child. Returns a child ID. int CreateChild(const ReturnCallback& return_callback);
diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc index 3351282..c4777b70d 100644 --- a/cc/resources/resource_provider_unittest.cc +++ b/cc/resources/resource_provider_unittest.cc
@@ -3784,5 +3784,35 @@ } } +TEST_P(ResourceProviderTest, GetSyncTokenForResources) { + if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) + return; + + gfx::Size size(1, 1); + ResourceFormat format = RGBA_8888; + + // ~Random set of |release_count|s to set on sync tokens. + uint64_t release_counts[5] = {7, 3, 10, 2, 5}; + + ResourceProvider::ResourceIdArray array; + for (uint32_t i = 0; i < arraysize(release_counts); ++i) { + ResourceId id = resource_provider_->CreateResource( + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); + array.push_back(id); + + ResourceProvider::ScopedWriteLockGL lock(resource_provider_.get(), id, + false); + gpu::SyncToken token; + token.Set(gpu::CommandBufferNamespace::INVALID, 0, gpu::CommandBufferId(), + release_counts[i]); + lock.set_sync_token(token); + } + + gpu::SyncToken last_token = + resource_provider_->GetSyncTokenForResources(array); + EXPECT_EQ(last_token.release_count(), 10u); +} + } // namespace } // namespace cc
diff --git a/cc/test/fake_raster_buffer_provider.cc b/cc/test/fake_raster_buffer_provider.cc index 20c91fa..3a5db5f 100644 --- a/cc/test/fake_raster_buffer_provider.cc +++ b/cc/test/fake_raster_buffer_provider.cc
@@ -38,6 +38,18 @@ return true; } +bool FakeRasterBufferProviderImpl::IsResourceReadyToDraw( + ResourceId resource_id) const { + return true; +} + +uint64_t FakeRasterBufferProviderImpl::SetReadyToDrawCallback( + const ResourceProvider::ResourceIdArray& resource_ids, + const base::Callback<void()>& callback, + uint64_t pending_callback_id) const { + return 0; +} + void FakeRasterBufferProviderImpl::Shutdown() {} } // namespace cc
diff --git a/cc/test/fake_raster_buffer_provider.h b/cc/test/fake_raster_buffer_provider.h index cb0c634..e28713f 100644 --- a/cc/test/fake_raster_buffer_provider.h +++ b/cc/test/fake_raster_buffer_provider.h
@@ -25,6 +25,11 @@ ResourceFormat GetResourceFormat(bool must_support_alpha) const override; bool IsResourceSwizzleRequired(bool must_support_alpha) const override; bool CanPartialRasterIntoProvidedResource() const override; + bool IsResourceReadyToDraw(ResourceId id) const override; + uint64_t SetReadyToDrawCallback( + const ResourceProvider::ResourceIdArray& resource_ids, + const base::Callback<void()>& callback, + uint64_t pending_callback_id) const override; void Shutdown() override; };
diff --git a/cc/tiles/picture_layer_tiling.h b/cc/tiles/picture_layer_tiling.h index 16d7983..0c9b57a 100644 --- a/cc/tiles/picture_layer_tiling.h +++ b/cc/tiles/picture_layer_tiling.h
@@ -247,6 +247,8 @@ void AsValueInto(base::trace_event::TracedValue* array) const; size_t GPUMemoryUsageInBytes() const; + void UpdateRequiredStatesOnTile(Tile* tile) const; + protected: friend class CoverageIterator; friend class PrioritizedTile; @@ -290,7 +292,6 @@ Tile::CreateInfo CreateInfoForTile(int i, int j) const; bool ShouldCreateTileAt(const Tile::CreateInfo& info) const; bool IsTileOccluded(const Tile* tile) const; - void UpdateRequiredStatesOnTile(Tile* tile) const; PrioritizedTile MakePrioritizedTile( Tile* tile, PriorityRectType priority_rect_type) const;
diff --git a/cc/tiles/tile_draw_info.cc b/cc/tiles/tile_draw_info.cc index 29f2cc83..560345ad 100644 --- a/cc/tiles/tile_draw_info.cc +++ b/cc/tiles/tile_draw_info.cc
@@ -10,11 +10,7 @@ namespace cc { TileDrawInfo::TileDrawInfo() - : mode_(RESOURCE_MODE), - solid_color_(SK_ColorWHITE), - resource_(nullptr), - contents_swizzled_(false), - was_ever_ready_to_draw_(false), + : was_ever_ready_to_draw_(false), was_ever_used_to_draw_(false), was_a_prepaint_tile_(false) {} @@ -32,4 +28,10 @@ mode_ == SOLID_COLOR_MODE && !SkColorGetA(solid_color_)); } +Resource* TileDrawInfo::TakeResource() { + Resource* resource = resource_; + set_resource(nullptr); + return resource; +} + } // namespace cc
diff --git a/cc/tiles/tile_draw_info.h b/cc/tiles/tile_draw_info.h index a51d27b..0a4db758 100644 --- a/cc/tiles/tile_draw_info.h +++ b/cc/tiles/tile_draw_info.h
@@ -27,7 +27,7 @@ bool IsReadyToDraw() const { switch (mode_) { case RESOURCE_MODE: - return !!resource_; + return is_resource_ready_to_draw_; case SOLID_COLOR_MODE: case OOM_MODE: return true; @@ -81,7 +81,6 @@ void AsValueInto(base::trace_event::TracedValue* state) const; - void set_was_ever_ready_to_draw() { was_ever_ready_to_draw_ = true; } void set_was_ever_used_to_draw() { was_ever_used_to_draw_ = true; } void set_was_a_prepaint_tile() { was_a_prepaint_tile_ = true; } @@ -89,19 +88,34 @@ friend class Tile; friend class TileManager; - void set_use_resource() { mode_ = RESOURCE_MODE; } + const Resource* resource() const { return resource_; } + + void set_resource(Resource* resource) { + mode_ = RESOURCE_MODE; + is_resource_ready_to_draw_ = false; + resource_ = resource; + } + + void set_resource_ready_for_draw() { + is_resource_ready_to_draw_ = true; + was_ever_ready_to_draw_ = true; + } + + Resource* TakeResource(); void set_solid_color(const SkColor& color) { mode_ = SOLID_COLOR_MODE; solid_color_ = color; + was_ever_ready_to_draw_ = true; } void set_oom() { mode_ = OOM_MODE; } - Mode mode_; - SkColor solid_color_; - Resource* resource_; - bool contents_swizzled_; + Mode mode_ = RESOURCE_MODE; + SkColor solid_color_ = SK_ColorWHITE; + Resource* resource_ = nullptr; + bool contents_swizzled_ = false; + bool is_resource_ready_to_draw_ = false; // Used for gathering UMA stats. bool was_ever_ready_to_draw_ : 1;
diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc index a20df654..12f3dfd 100644 --- a/cc/tiles/tile_manager.cc +++ b/cc/tiles/tile_manager.cc
@@ -372,7 +372,8 @@ prepare_tiles_count_(0u), next_tile_id_(0u), check_tile_priority_inversion_(check_tile_priority_inversion), - task_set_finished_weak_ptr_factory_(this) {} + task_set_finished_weak_ptr_factory_(this), + ready_to_draw_callback_weak_ptr_factory_(this) {} TileManager::~TileManager() { FinishTasksAndCleanUp(); @@ -397,6 +398,7 @@ more_tiles_need_prepare_check_notifier_.Cancel(); signals_check_notifier_.Cancel(); task_set_finished_weak_ptr_factory_.InvalidateWeakPtrs(); + ready_to_draw_callback_weak_ptr_factory_.InvalidateWeakPtrs(); raster_buffer_provider_ = nullptr; image_controller_.SetImageDecodeCache(nullptr); @@ -423,6 +425,7 @@ void TileManager::Release(Tile* tile) { FreeResourcesForTile(tile); tiles_.erase(tile->id()); + pending_gpu_work_tiles_.erase(tile); } void TileManager::DidFinishRunningTileTasksRequiredForActivation() { @@ -518,12 +521,17 @@ tile_task_manager_->CheckForCompletedTasks(); did_check_for_completed_tasks_since_last_schedule_tasks_ = true; + CheckPendingGpuWorkTiles(true /* issue_signals */); TRACE_EVENT_INSTANT1("cc", "DidFlush", TRACE_EVENT_SCOPE_THREAD, "stats", RasterTaskCompletionStatsAsValue(flush_stats_)); flush_stats_ = RasterTaskCompletionStats(); } +void TileManager::DidModifyTilePriorities() { + pending_tile_requirements_dirty_ = true; +} + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> TileManager::BasicStateAsValue() const { std::unique_ptr<base::trace_event::TracedValue> value( @@ -661,7 +669,6 @@ tile->content_rect(), tile->contents_scale(), &color); if (is_solid_color) { tile->draw_info().set_solid_color(color); - tile->draw_info().set_was_ever_ready_to_draw(); if (!tile_is_needed_now) tile->draw_info().set_was_a_prepaint_tile(); client_->NotifyTileStateChanged(tile); @@ -794,10 +801,9 @@ void TileManager::FreeResourcesForTile(Tile* tile) { TileDrawInfo& draw_info = tile->draw_info(); - if (draw_info.resource_) { - resource_pool_->ReleaseResource(draw_info.resource_); - draw_info.resource_ = nullptr; - } + Resource* resource = draw_info.TakeResource(); + if (resource) + resource_pool_->ReleaseResource(resource); } void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw( @@ -855,7 +861,7 @@ Tile* tile = prioritized_tile.tile(); DCHECK(tile->draw_info().requires_resource()); - DCHECK(!tile->draw_info().resource_); + DCHECK(!tile->draw_info().resource()); if (!tile->raster_task_) tile->raster_task_ = CreateRasterTask( @@ -1063,12 +1069,18 @@ } TileDrawInfo& draw_info = tile->draw_info(); - draw_info.set_use_resource(); - draw_info.resource_ = resource; + draw_info.set_resource(resource); draw_info.contents_swizzled_ = DetermineResourceRequiresSwizzle(tile); - DCHECK(draw_info.IsReadyToDraw()); - draw_info.set_was_ever_ready_to_draw(); + // In SMOOTHNESS_TAKES_PRIORITY mode, we wait for GPU work to complete for a + // tile before setting it as ready to draw. + if (global_state_.tree_priority == SMOOTHNESS_TAKES_PRIORITY && + !raster_buffer_provider_->IsResourceReadyToDraw(resource->id())) { + pending_gpu_work_tiles_.insert(tile); + return; + } + + draw_info.set_resource_ready_for_draw(); client_->NotifyTileStateChanged(tile); } @@ -1125,14 +1137,16 @@ bool TileManager::IsReadyToActivate() const { TRACE_EVENT0("cc", "TileManager::IsReadyToActivate"); - return AreRequiredTilesReadyToDraw( - RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION); + return pending_required_for_activation_callback_id_ == 0 && + AreRequiredTilesReadyToDraw( + RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION); } bool TileManager::IsReadyToDraw() const { TRACE_EVENT0("cc", "TileManager::IsReadyToDraw"); - return AreRequiredTilesReadyToDraw( - RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW); + return pending_required_for_draw_callback_id_ == 0 && + AreRequiredTilesReadyToDraw( + RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW); } void TileManager::CheckAndIssueSignals() { @@ -1140,6 +1154,8 @@ tile_task_manager_->CheckForCompletedTasks(); did_check_for_completed_tasks_since_last_schedule_tasks_ = true; + CheckPendingGpuWorkTiles(false /* issue_signals */); + // Ready to activate. if (signals_.ready_to_activate && !signals_.did_notify_ready_to_activate) { signals_.ready_to_activate = false; @@ -1289,6 +1305,71 @@ raster_buffer_provider_->CanPartialRasterIntoProvidedResource(); } +void TileManager::CheckPendingGpuWorkTiles(bool issue_signals) { + ResourceProvider::ResourceIdArray required_for_activation_ids; + ResourceProvider::ResourceIdArray required_for_draw_ids; + + for (auto it = pending_gpu_work_tiles_.begin(); + it != pending_gpu_work_tiles_.end();) { + Tile* tile = *it; + const Resource* resource = tile->draw_info().resource(); + + if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY || + raster_buffer_provider_->IsResourceReadyToDraw(resource->id())) { + tile->draw_info().set_resource_ready_for_draw(); + client_->NotifyTileStateChanged(tile); + it = pending_gpu_work_tiles_.erase(it); + continue; + } + + // TODO(ericrk): If a tile in our list no longer has valid tile priorities, + // it may still report that it is required, and unnecessarily delay + // activation. crbug.com/687265 + if (pending_tile_requirements_dirty_) + tile->tiling()->UpdateRequiredStatesOnTile(tile); + if (tile->required_for_activation()) + required_for_activation_ids.push_back(resource->id()); + if (tile->required_for_draw()) + required_for_draw_ids.push_back(resource->id()); + + ++it; + } + + if (required_for_activation_ids.empty()) { + pending_required_for_activation_callback_id_ = 0; + } else { + pending_required_for_activation_callback_id_ = + raster_buffer_provider_->SetReadyToDrawCallback( + required_for_activation_ids, + base::Bind(&TileManager::CheckPendingGpuWorkTiles, + ready_to_draw_callback_weak_ptr_factory_.GetWeakPtr(), + true /* issue_signals */), + pending_required_for_activation_callback_id_); + } + + pending_required_for_draw_callback_id_ = 0; + if (!required_for_draw_ids.empty()) { + pending_required_for_draw_callback_id_ = + raster_buffer_provider_->SetReadyToDrawCallback( + required_for_draw_ids, + base::Bind(&TileManager::CheckPendingGpuWorkTiles, + ready_to_draw_callback_weak_ptr_factory_.GetWeakPtr(), + true /* issue_signals */), + pending_required_for_draw_callback_id_); + } + + // Update our signals now that we know whether we have pending resources. + signals_.ready_to_activate = + (pending_required_for_activation_callback_id_ == 0); + signals_.ready_to_draw = (pending_required_for_draw_callback_id_ == 0); + + if (issue_signals && (signals_.ready_to_activate || signals_.ready_to_draw)) + signals_check_notifier_.Schedule(); + + // We've just updated all pending tile requirements if necessary. + pending_tile_requirements_dirty_ = false; +} + // Utility function that can be used to create a "Task set finished" task that // posts |callback| to |task_runner| when run. scoped_refptr<TileTask> TileManager::CreateTaskSetFinishedTask( @@ -1307,8 +1388,8 @@ resource_count_(static_cast<int>(resource_count)) { // MemoryUsage is constructed using size_ts, since it deals with memory and // the inputs are typically size_t. However, during the course of usage (in - // particular operator-=) can cause internal values to become negative. Thus, - // member variables are signed. + // particular operator-=) can cause internal values to become negative. + // Thus, member variables are signed. DCHECK_LE(memory_bytes, static_cast<size_t>(std::numeric_limits<int64_t>::max())); DCHECK_LE(resource_count, @@ -1320,7 +1401,8 @@ const gfx::Size& size, ResourceFormat format) { // We can use UncheckedSizeInBytes here since this is used with a tile - // size which is determined by the compositor (it's at most max texture size). + // size which is determined by the compositor (it's at most max texture + // size). return MemoryUsage(ResourceUtil::UncheckedSizeInBytes<size_t>(size, format), 1); } @@ -1328,9 +1410,9 @@ // static TileManager::MemoryUsage TileManager::MemoryUsage::FromTile(const Tile* tile) { const TileDrawInfo& draw_info = tile->draw_info(); - if (draw_info.resource_) { - return MemoryUsage::FromConfig(draw_info.resource_->size(), - draw_info.resource_->format()); + if (draw_info.resource()) { + return MemoryUsage::FromConfig(draw_info.resource()->size(), + draw_info.resource()->format()); } return MemoryUsage(); }
diff --git a/cc/tiles/tile_manager.h b/cc/tiles/tile_manager.h index f1a933e..90041452 100644 --- a/cc/tiles/tile_manager.h +++ b/cc/tiles/tile_manager.h
@@ -132,6 +132,10 @@ // date draw information. void Flush(); + // Called when the required-for-activation/required-for-draw state of tiles + // may have changed. + void DidModifyTilePriorities(); + std::unique_ptr<Tile> CreateTile(const Tile::CreateInfo& info, int layer_id, int source_frame_number, @@ -151,10 +155,11 @@ void InitializeTilesWithResourcesForTesting(const std::vector<Tile*>& tiles) { for (size_t i = 0; i < tiles.size(); ++i) { TileDrawInfo& draw_info = tiles[i]->draw_info(); - draw_info.resource_ = resource_pool_->AcquireResource( + draw_info.set_resource(resource_pool_->AcquireResource( tiles[i]->desired_texture_size(), raster_buffer_provider_->GetResourceFormat(false), - client_->GetTileColorSpace()); + client_->GetTileColorSpace())); + draw_info.set_resource_ready_for_draw(); } } @@ -302,6 +307,8 @@ bool UsePartialRaster() const; + void CheckPendingGpuWorkTiles(bool issue_signals); + TileManagerClient* client_; base::SequencedTaskRunner* task_runner_; ResourcePool* resource_pool_; @@ -337,11 +344,24 @@ uint64_t prepare_tiles_count_; uint64_t next_tile_id_; + std::unordered_set<Tile*> pending_gpu_work_tiles_; + uint64_t pending_required_for_activation_callback_id_ = 0; + uint64_t pending_required_for_draw_callback_id_ = 0; + // If true, we should re-compute tile requirements in + // CheckPendingGpuWorkTiles. + bool pending_tile_requirements_dirty_ = false; + std::unordered_map<Tile::Id, std::vector<DrawImage>> scheduled_draw_images_; std::vector<scoped_refptr<TileTask>> locked_image_tasks_; const bool check_tile_priority_inversion_; + // We need two WeakPtrFactory objects as the invalidation pattern of each is + // different. The |task_set_finished_weak_ptr_factory_| is invalidated any + // time new tasks are scheduled, preventing a race when the callback has + // been scheduled but not yet executed. base::WeakPtrFactory<TileManager> task_set_finished_weak_ptr_factory_; + // The |ready_to_draw_callback_weak_ptr_factory_| is never invalidated. + base::WeakPtrFactory<TileManager> ready_to_draw_callback_weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(TileManager); };
diff --git a/cc/tiles/tile_manager_unittest.cc b/cc/tiles/tile_manager_unittest.cc index 73460f67..b657339 100644 --- a/cc/tiles/tile_manager_unittest.cc +++ b/cc/tiles/tile_manager_unittest.cc
@@ -5,6 +5,8 @@ #include <stddef.h> #include <stdint.h> +#include "base/bind.h" +#include "base/callback.h" #include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/threading/thread_task_runner_handle.h" @@ -39,6 +41,11 @@ #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkSurface.h" +using testing::_; +using testing::Invoke; +using testing::Return; +using testing::StrictMock; + namespace cc { namespace { @@ -1489,7 +1496,7 @@ const LayerTreeSettings& settings, TaskRunnerProvider* task_runner_provider, TaskGraphRunner* task_graph_runner) override { - return base::MakeUnique<MockLayerTreeHostImpl>( + return base::MakeUnique<testing::NiceMock<MockLayerTreeHostImpl>>( settings, task_runner_provider, task_graph_runner); } @@ -1925,5 +1932,336 @@ RunPartialRasterCheck(TakeHostImpl(), false /* partial_raster_enabled */); } +// FakeRasterBufferProviderImpl that allows us to mock ready to draw +// functionality. +class MockReadyToDrawRasterBufferProviderImpl + : public FakeRasterBufferProviderImpl { + public: + MOCK_CONST_METHOD1(IsResourceReadyToDraw, bool(ResourceId resource_id)); + MOCK_CONST_METHOD3( + SetReadyToDrawCallback, + uint64_t(const ResourceProvider::ResourceIdArray& resource_ids, + const base::Closure& callback, + uint64_t pending_callback_id)); + + std::unique_ptr<RasterBuffer> AcquireBufferForRaster( + const Resource* resource, + uint64_t resource_content_id, + uint64_t previous_content_id) override { + return base::MakeUnique<FakeRasterBuffer>(); + } + + private: + class FakeRasterBuffer : public RasterBuffer { + public: + void Playback( + const RasterSource* raster_source, + const gfx::Rect& raster_full_rect, + const gfx::Rect& raster_dirty_rect, + uint64_t new_content_id, + float scale, + const RasterSource::PlaybackSettings& playback_settings) override {} + }; +}; + +class TileManagerReadyToDrawTest : public TileManagerTest { + public: + ~TileManagerReadyToDrawTest() override { + // Ensure that the host impl doesn't outlive |raster_buffer_provider_|. + TakeHostImpl(); + } + + void SetUp() override { + TileManagerTest::SetUp(); + host_impl()->tile_manager()->SetRasterBufferProviderForTesting( + &mock_raster_buffer_provider_); + + const gfx::Size layer_bounds(1000, 1000); + + solid_color_recording_source_ = + FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); + + SkPaint solid_paint; + SkColor solid_color = SkColorSetARGB(255, 12, 23, 34); + solid_paint.setColor(solid_color); + solid_color_recording_source_->add_draw_rect_with_paint( + gfx::Rect(layer_bounds), solid_paint); + + solid_color_recording_source_->Rerecord(); + + recording_source_ = + FakeRecordingSource::CreateFilledRecordingSource(layer_bounds); + SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67); + SkPaint non_solid_paint; + non_solid_paint.setColor(non_solid_color); + + for (int i = 0; i < 100; ++i) { + for (int j = 0; j < 100; ++j) { + recording_source_->add_draw_rect_with_paint( + gfx::Rect(10 * i, 10 * j, 5, 5), non_solid_paint); + } + } + recording_source_->Rerecord(); + } + + LayerTreeSettings CreateSettings() override { + LayerTreeSettingsForTesting settings; + settings.renderer_settings.buffer_to_texture_target_map = + DefaultBufferToTextureTargetMapForTesting(); + return settings; + } + + void SetupTreesWithActiveTreeTiles() { + scoped_refptr<RasterSource> active_tree_raster_source = + RasterSource::CreateFromRecordingSource(recording_source_.get(), false); + scoped_refptr<RasterSource> pending_tree_raster_source = + RasterSource::CreateFromRecordingSource( + solid_color_recording_source_.get(), false); + + SetupTrees(pending_tree_raster_source, active_tree_raster_source); + } + + void SetupTreesWithPendingTreeTiles() { + scoped_refptr<RasterSource> active_tree_raster_source = + RasterSource::CreateFromRecordingSource( + solid_color_recording_source_.get(), false); + scoped_refptr<RasterSource> pending_tree_raster_source = + RasterSource::CreateFromRecordingSource(recording_source_.get(), false); + + SetupTrees(pending_tree_raster_source, active_tree_raster_source); + } + + TileManager* tile_manager() { return host_impl()->tile_manager(); } + MockReadyToDrawRasterBufferProviderImpl* mock_raster_buffer_provider() { + return &mock_raster_buffer_provider_; + } + + private: + StrictMock<MockReadyToDrawRasterBufferProviderImpl> + mock_raster_buffer_provider_; + std::unique_ptr<FakeRecordingSource> recording_source_; + std::unique_ptr<FakeRecordingSource> solid_color_recording_source_; +}; + +TEST_F(TileManagerReadyToDrawTest, SmoothActivationWaitsOnCallback) { + host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY); + SetupTreesWithPendingTreeTiles(); + + base::Closure callback; + { + base::RunLoop run_loop; + + // Until we activate our ready to draw callback, treat all resources as not + // ready to draw. + EXPECT_CALL(*mock_raster_buffer_provider(), + IsResourceReadyToDraw(testing::_)) + .WillRepeatedly(Return(false)); + + EXPECT_CALL(*mock_raster_buffer_provider(), SetReadyToDrawCallback(_, _, 0)) + .WillOnce(testing::Invoke([&run_loop, &callback]( + const ResourceProvider::ResourceIdArray& resource_ids, + const base::Closure& callback_in, uint64_t pending_callback_id) { + callback = callback_in; + run_loop.Quit(); + return 1; + })); + host_impl()->tile_manager()->DidModifyTilePriorities(); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); + run_loop.Run(); + } + + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw()); + EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToActivate()); + + { + base::RunLoop run_loop; + EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate()) + .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); + EXPECT_CALL(*mock_raster_buffer_provider(), + IsResourceReadyToDraw(testing::_)) + .WillRepeatedly(Return(true)); + callback.Run(); + run_loop.Run(); + } + + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw()); + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); +} + +TEST_F(TileManagerReadyToDrawTest, NonSmoothActivationDoesNotWaitOnCallback) { + SetupTreesWithPendingTreeTiles(); + + // We're using a StrictMock on the RasterBufferProvider, so any function call + // will cause a test failure. + base::RunLoop run_loop; + + host_impl()->tile_manager()->DidModifyTilePriorities(); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); + EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate()) + .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); + run_loop.Run(); + + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw()); + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); +} + +TEST_F(TileManagerReadyToDrawTest, SmoothDrawWaitsOnCallback) { + host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY); + SetupTreesWithActiveTreeTiles(); + + base::Closure callback; + { + base::RunLoop run_loop; + + // Until we activate our ready to draw callback, treat all resources as not + // ready to draw. + EXPECT_CALL(*mock_raster_buffer_provider(), + IsResourceReadyToDraw(testing::_)) + .WillRepeatedly(Return(false)); + + EXPECT_CALL(*mock_raster_buffer_provider(), SetReadyToDrawCallback(_, _, 0)) + .WillOnce(Invoke([&run_loop, &callback]( + const ResourceProvider::ResourceIdArray& resource_ids, + const base::Closure& callback_in, uint64_t pending_callback_id) { + callback = callback_in; + run_loop.Quit(); + return 1; + })); + host_impl()->tile_manager()->DidModifyTilePriorities(); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); + run_loop.Run(); + } + + EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToDraw()); + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); + + { + base::RunLoop run_loop; + EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw()) + .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); })); + EXPECT_CALL(*mock_raster_buffer_provider(), + IsResourceReadyToDraw(testing::_)) + .WillRepeatedly(Return(true)); + callback.Run(); + run_loop.Run(); + } + + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw()); + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); +} + +TEST_F(TileManagerReadyToDrawTest, NonSmoothDrawDoesNotWaitOnCallback) { + SetupTreesWithActiveTreeTiles(); + + // We're using a StrictMock on the RasterBufferProvider, so any function call + // will cause a test failure. + base::RunLoop run_loop; + + host_impl()->tile_manager()->DidModifyTilePriorities(); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); + EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw()) + .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); + run_loop.Run(); + + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw()); + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); +} + +TEST_F(TileManagerReadyToDrawTest, NoCallbackWhenAlreadyReadyToDraw) { + host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY); + SetupTreesWithPendingTreeTiles(); + + base::RunLoop run_loop; + host_impl()->tile_manager()->DidModifyTilePriorities(); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); + EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate()) + .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); + EXPECT_CALL(*mock_raster_buffer_provider(), IsResourceReadyToDraw(_)) + .WillRepeatedly(Return(true)); + run_loop.Run(); + + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw()); + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); +} + +void UpdateVisibleRect(FakePictureLayerImpl* layer, + const gfx::Rect visible_rect) { + PictureLayerTilingSet* tiling_set = layer->tilings(); + for (size_t j = 0; j < tiling_set->num_tilings(); ++j) { + PictureLayerTiling* tiling = tiling_set->tiling_at(j); + tiling->SetTilePriorityRectsForTesting( + visible_rect, // Visible rect. + visible_rect, // Skewport rect. + visible_rect, // Soon rect. + gfx::Rect(0, 0, 1000, 1000)); // Eventually rect. + } +} + +TEST_F(TileManagerReadyToDrawTest, ReadyToDrawRespectsRequirementChange) { + host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY); + SetupTreesWithPendingTreeTiles(); + + // Initially create a tiling with a visible rect of (0, 0, 100, 100) and + // a soon rect of the rest of the layer. + UpdateVisibleRect(pending_layer(), gfx::Rect(0, 0, 100, 100)); + + // Mark all these tiles as ready to draw. + base::RunLoop run_loop; + host_impl()->tile_manager()->DidModifyTilePriorities(); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); + EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate()) + .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); + EXPECT_CALL(*mock_raster_buffer_provider(), IsResourceReadyToDraw(_)) + .WillRepeatedly(Return(true)); + run_loop.Run(); + + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw()); + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); + + // Move the viewport to (900, 900, 100, 100), so that we need a different set + // of tilings. + UpdateVisibleRect(pending_layer(), gfx::Rect(900, 900, 100, 100)); + + EXPECT_CALL(*mock_raster_buffer_provider(), IsResourceReadyToDraw(testing::_)) + .WillRepeatedly(Return(false)); + + base::Closure callback; + { + base::RunLoop run_loop; + + EXPECT_CALL(*mock_raster_buffer_provider(), SetReadyToDrawCallback(_, _, 0)) + .WillOnce(testing::Invoke([&run_loop, &callback]( + const ResourceProvider::ResourceIdArray& resource_ids, + const base::Closure& callback_in, uint64_t pending_callback_id) { + callback = callback_in; + run_loop.Quit(); + return 1; + })); + host_impl()->tile_manager()->DidModifyTilePriorities(); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); + run_loop.Run(); + } + + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw()); + EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToActivate()); + + // Now switch back to our original tiling. We should be immediately able to + // activate, as we still have the original tile, and no longer need the + // tiles from the previous callback. + UpdateVisibleRect(pending_layer(), gfx::Rect(0, 0, 100, 100)); + + { + base::RunLoop run_loop; + host_impl()->tile_manager()->DidModifyTilePriorities(); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); + EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate()) + .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); + run_loop.Run(); + } + + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw()); + EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); +} + } // namespace } // namespace cc
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index 23444716..3e11243 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -634,13 +634,6 @@ android:exported="false" > </activity> - <!-- Opt-in activity for Physical Web --> - <activity android:name="org.chromium.chrome.browser.physicalweb.PhysicalWebOptInActivity" - android:label="@string/physical_web_list_urls_activity_title" - android:theme="@style/PhysicalWebOptInStyle" - android:exported="false"> - </activity> - <!-- Service for handling Nearby Messages --> <service android:name="org.chromium.chrome.browser.physicalweb.NearbyMessageIntentService" android:exported="false" />
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeCallback.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeCallback.java index a5255a61..291faa36 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeCallback.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeCallback.java
@@ -87,7 +87,7 @@ RecordUserAction.record("MobileActionMode.WebSearch"); if (mTab.getTabModelSelector() == null) return; - String query = mHelper.sanitizeQuery(mHelper.getSelectedText(), + String query = ActionModeCallbackHelper.sanitizeQuery(mHelper.getSelectedText(), ActionModeCallbackHelper.MAX_SEARCH_QUERY_LENGTH); if (TextUtils.isEmpty(query)) return;
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 1e88167..8df645a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -1825,7 +1825,7 @@ mUmaSessionStats = new UmaSessionStats(this); } - mUmaSessionStats.updateMetricsServiceState(); + UmaSessionStats.updateMetricsServiceState(); mUmaSessionStats.startNewSession(getTabModelSelector()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java index 4325a36..5428229e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -48,6 +48,23 @@ return sTestEnabledFeatures.contains(featureName); } + /** + * Returns a field trial param as an int for the specified feature. + * + * Note: Features queried through this API must be added to the array + * |kFeaturesExposedToJava| in chrome/browser/android/chrome_feature_list.cc + * + * @param featureName The name of the feature to retrieve a param for. + * @param paramName The name of the param for which to get as an integer. + * @param defaultValue The integer value to use if the param is not available. + * @return The parameter value as an int. Default value if the feature does not exist or the + * specified parameter does not exist. + */ + public static long getFieldTrialParamByFeatureAsInt( + String featureName, String paramName, int defaultValue) { + return nativeGetFieldTrialParamByFeatureAsInt(featureName, paramName, defaultValue); + } + // Alphabetical: public static final String ANDROID_PAY_INTEGRATION_V1 = "AndroidPayIntegrationV1"; public static final String ANDROID_PAY_INTEGRATION_V2 = "AndroidPayIntegrationV2"; @@ -77,6 +94,9 @@ public static final String WEB_PAYMENTS = "WebPayments"; public static final String WEB_PAYMENTS_MODIFIERS = "WebPaymentsModifiers"; public static final String WEB_PAYMENTS_SINGLE_APP_UI_SKIP = "WebPaymentsSingleAppUiSkip"; + public static final String WEBVR_CARDBOARD_SUPPORT = "WebVRCardboardSupport"; private static native boolean nativeIsEnabled(String featureName); + private static native int nativeGetFieldTrialParamByFeatureAsInt( + String featureName, String paramName, int defaultValue); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java b/chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java index 628b54f3..30dfc81 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java
@@ -402,7 +402,7 @@ Log.w(TAG, "Could not find a crash dump with local ID " + localId); return; } - File renamedMinidumpFile = fileManager.trySetForcedUpload(minidumpFile); + File renamedMinidumpFile = CrashFileManager.trySetForcedUpload(minidumpFile); if (renamedMinidumpFile == null) { Log.w(TAG, "Could not rename the file " + minidumpFile.getName() + " for re-upload"); return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java index 2ff6b14..6c986de 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java
@@ -212,7 +212,7 @@ ChromeSwitches.ENABLE_LIGHTWEIGHT_FIRST_RUN_EXPERIENCE)) { // Launch the First Run Experience for VIEW Intents with URLs before launching // ChromeTabbedActivity if necessary. - if (getIntent() != null && getIntent().getAction() == Intent.ACTION_VIEW + if (getIntent() != null && Intent.ACTION_VIEW.equals(getIntent().getAction()) && IntentHandler.getUrlFromIntent(getIntent()) != null) { if (launchFirstRunExperience(true)) { finish();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java index fc9ed5b..c33e7ac 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java
@@ -184,7 +184,7 @@ DownloadResumptionScheduler.getDownloadResumptionScheduler(mContext).cancelTask(); // Limit the number of auto resumption attempts in case Chrome falls into a vicious // cycle. - if (intent.getAction() == ACTION_DOWNLOAD_RESUME_ALL) { + if (ACTION_DOWNLOAD_RESUME_ALL.equals(intent.getAction())) { if (mNumAutoResumptionAttemptLeft > 0) { mNumAutoResumptionAttemptLeft--; updateResumptionAttemptLeft(); @@ -613,7 +613,7 @@ * @param intent Intent that contains the download action. */ private DownloadSharedPreferenceEntry getDownloadEntryFromIntent(Intent intent) { - if (intent.getAction() == ACTION_DOWNLOAD_RESUME_ALL) return null; + if (ACTION_DOWNLOAD_RESUME_ALL.equals(intent.getAction())) return null; String guid = IntentUtils.safeGetStringExtra(intent, EXTRA_DOWNLOAD_GUID); return mDownloadSharedPreferenceHelper.getDownloadSharedPreferenceEntry(guid); } @@ -634,14 +634,14 @@ return; } - if (intent.getAction() == ACTION_DOWNLOAD_PAUSE) { + if (ACTION_DOWNLOAD_PAUSE.equals(intent.getAction())) { // If browser process already goes away, the download should have already paused. Do // nothing in that case. if (!DownloadManagerService.hasDownloadManagerService()) { notifyDownloadPaused(entry.downloadGuid, !entry.isOffTheRecord, false); return; } - } else if (intent.getAction() == ACTION_DOWNLOAD_RESUME) { + } else if (ACTION_DOWNLOAD_RESUME.equals(intent.getAction())) { boolean metered = DownloadManagerService.isActiveNetworkMetered(mContext); if (!entry.canDownloadWhileMetered) { // If user manually resumes a download, update the network type if it @@ -651,11 +651,11 @@ entry.isAutoResumable = true; // Update the SharedPreference entry. mDownloadSharedPreferenceHelper.addOrReplaceSharedPreferenceEntry(entry); - } else if (intent.getAction() == ACTION_DOWNLOAD_RESUME_ALL + } else if (ACTION_DOWNLOAD_RESUME_ALL.equals(intent.getAction()) && (mDownloadSharedPreferenceHelper.getEntries().isEmpty() || DownloadManagerService.hasDownloadManagerService())) { return; - } else if (intent.getAction() == ACTION_DOWNLOAD_OPEN) { + } else if (ACTION_DOWNLOAD_OPEN.equals(intent.getAction())) { // TODO(fgorski): Do we even need to do anything special here, before we launch Chrome? } @@ -668,14 +668,13 @@ @Override public void finishNativeInitialization() { int itemType = entry != null ? entry.itemType - : (intent.getAction() == ACTION_DOWNLOAD_OPEN + : (ACTION_DOWNLOAD_OPEN.equals(intent.getAction()) ? DownloadSharedPreferenceEntry.ITEM_TYPE_OFFLINE_PAGE : DownloadSharedPreferenceEntry.ITEM_TYPE_DOWNLOAD); DownloadServiceDelegate downloadServiceDelegate = - intent.getAction() == ACTION_DOWNLOAD_OPEN ? null + ACTION_DOWNLOAD_OPEN.equals(intent.getAction()) ? null : getServiceDelegate(itemType); - switch (intent.getAction()) { - case ACTION_DOWNLOAD_CANCEL: + if (ACTION_DOWNLOAD_CANCEL.equals(intent.getAction())) { // TODO(qinmin): Alternatively, we can delete the downloaded content on // SD card, and remove the download ID from the SharedPreferences so we // don't need to restart the browser process. http://crbug.com/579643. @@ -683,30 +682,24 @@ downloadServiceDelegate.cancelDownload(entry.downloadGuid, entry.isOffTheRecord, IntentUtils.safeGetBooleanExtra( intent, EXTRA_NOTIFICATION_DISMISSED, false)); - break; - case ACTION_DOWNLOAD_PAUSE: + } else if (ACTION_DOWNLOAD_PAUSE.equals(intent.getAction())) { downloadServiceDelegate.pauseDownload(entry.downloadGuid, entry.isOffTheRecord); - break; - case ACTION_DOWNLOAD_RESUME: + } else if (ACTION_DOWNLOAD_RESUME.equals(intent.getAction())) { notifyDownloadPending(entry.downloadGuid, entry.fileName, entry.isOffTheRecord, entry.canDownloadWhileMetered, entry.isOfflinePage()); downloadServiceDelegate.resumeDownload(entry.buildDownloadItem(), true); - break; - case ACTION_DOWNLOAD_RESUME_ALL: + } else if (ACTION_DOWNLOAD_RESUME_ALL.equals(intent.getAction())) { assert entry == null; resumeAllPendingDownloads(); - break; - case ACTION_DOWNLOAD_OPEN: + } else if (ACTION_DOWNLOAD_OPEN.equals(intent.getAction())) { OfflinePageDownloadBridge.openDownloadedPage( IntentUtils.safeGetStringExtra(intent, EXTRA_DOWNLOAD_GUID)); - break; - default: + } else { Log.e(TAG, "Unrecognized intent action.", intent); - break; } - if (intent.getAction() != ACTION_DOWNLOAD_OPEN) { + if (!ACTION_DOWNLOAD_OPEN.equals(intent.getAction())) { downloadServiceDelegate.destroyServiceDelegate(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java index 0273b15..fa9c7a6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java
@@ -580,7 +580,7 @@ Intent intent = tab.getTabRedirectHandler() != null ? tab.getTabRedirectHandler().getInitialIntent() : null; // TODO(mariakhomenko): consider also handling NDEF_DISCOVER action redirects. - if (isIncomingRedirect && intent != null && intent.getAction() == Intent.ACTION_VIEW) { + if (isIncomingRedirect && intent != null && Intent.ACTION_VIEW.equals(intent.getAction())) { // Set the URL the redirect was resolved to for checking the existence of the // instant app inside handleIncomingIntent(). Intent resolvedIntent = new Intent(intent);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/mojo/ChromeInterfaceRegistrar.java b/chrome/android/java/src/org/chromium/chrome/browser/mojo/ChromeInterfaceRegistrar.java index bb0353c8..f30ab895 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/mojo/ChromeInterfaceRegistrar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/mojo/ChromeInterfaceRegistrar.java
@@ -19,6 +19,8 @@ import org.chromium.shape_detection.mojom.TextDetection; import org.chromium.webshare.mojom.ShareService; +@SuppressWarnings("MultipleTopLevelClassesInFile") + /** Registers mojo interface implementations exposed to C++ code at the Chrome layer. */ class ChromeInterfaceRegistrar { @CalledByNative
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/pageinfo/CertificateViewer.java b/chrome/android/java/src/org/chromium/chrome/browser/pageinfo/CertificateViewer.java index e0f722e..c5770f3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/pageinfo/CertificateViewer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/pageinfo/CertificateViewer.java
@@ -8,7 +8,6 @@ import android.content.Context; import android.graphics.Typeface; import android.net.http.SslCertificate; -import android.text.format.DateFormat; import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -30,6 +29,7 @@ import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.text.DateFormat; import java.util.ArrayList; /** @@ -170,7 +170,7 @@ sslCert.getIssuedBy().getUName()); addSectionTitle(certificateView, nativeGetCertValidityText()); - java.text.DateFormat dateFormat = DateFormat.getDateFormat(mContext); + DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM); addItem(certificateView, nativeGetCertIssuedOnText(), dateFormat.format(sslCert.getValidNotBeforeDate())); addItem(certificateView, nativeGetCertExpiresOnText(),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PhysicalWebOptInActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PhysicalWebOptInActivity.java deleted file mode 100644 index e8fe2e3..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PhysicalWebOptInActivity.java +++ /dev/null
@@ -1,95 +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. - -package org.chromium.chrome.browser.physicalweb; - -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.text.SpannableString; -import android.text.TextPaint; -import android.text.method.LinkMovementMethod; -import android.text.style.ClickableSpan; -import android.view.View; -import android.widget.Button; -import android.widget.TextView; - -import org.chromium.chrome.R; -import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferencesManager; -import org.chromium.ui.text.SpanApplier; -import org.chromium.ui.text.SpanApplier.SpanInfo; - -/** - * This activity invites the user to opt-in to the Physical Web feature. - */ -public class PhysicalWebOptInActivity extends AppCompatActivity { - private static final String EXTRA_CUSTOM_TABS_SESSION = - "android.support.customtabs.extra.SESSION"; - private static final String PHYSICAL_WEB_LEARN_MORE_URL = - "https://support.google.com/chrome/answer/6239299/"; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.physical_web_optin); - - TextView description = (TextView) findViewById(R.id.physical_web_optin_description); - description.setMovementMethod(LinkMovementMethod.getInstance()); - description.setText(getDescriptionText()); - - Button declineButton = (Button) findViewById(R.id.physical_web_decline); - declineButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - PhysicalWebUma.onOptInDeclineButtonPressed(); - PrivacyPreferencesManager.getInstance().setPhysicalWebEnabled(false); - finish(); - } - }); - - Button enableButton = (Button) findViewById(R.id.physical_web_enable); - enableButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - PhysicalWebUma.onOptInEnableButtonPressed(); - PrivacyPreferencesManager.getInstance().setPhysicalWebEnabled(true); - startActivity(createListUrlsIntent(PhysicalWebOptInActivity.this)); - finish(); - } - }); - } - - private static Intent createListUrlsIntent(Context context) { - Intent intent = new Intent(context, ListUrlsActivity.class); - intent.putExtra(ListUrlsActivity.REFERER_KEY, - ListUrlsActivity.OPTIN_REFERER); - return intent; - } - - private SpannableString getDescriptionText() { - return SpanApplier.applySpans( - getString(R.string.physical_web_optin_description), - new SpanInfo("<learnmore>", "</learnmore>", new ClickableSpan() { - @Override - public void onClick(View v) { - Intent intent = new Intent(Intent.ACTION_VIEW, - Uri.parse(PHYSICAL_WEB_LEARN_MORE_URL)); - // Add the SESSION extra to indicate we want a Chrome custom tab. This - // allows the help page to open in the same task as the opt-in activity so - // they can share a back stack. - String session = null; - intent.putExtra(EXTRA_CUSTOM_TABS_SESSION, session); - PhysicalWebOptInActivity.this.startActivity(intent); - } - - @Override - public void updateDrawState(TextPaint ds) { - // Color links but do not underline them. - ds.setColor(ds.linkColor); - } - })); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java index 2f80c7f..b46bfe2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
@@ -60,6 +60,7 @@ import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.chrome.browser.util.MathUtils; import org.chromium.chrome.browser.widget.TintedImageButton; +import org.chromium.chrome.browser.widget.animation.CancelAwareAnimatorListener; import org.chromium.chrome.browser.widget.newtab.NewTabButton; import org.chromium.ui.base.LocalizationUtils; import org.chromium.ui.interpolators.BakedBezierInterpolator; @@ -1750,11 +1751,9 @@ mUrlFocusLayoutAnimator.playTogether(animators); mUrlFocusChangeInProgress = true; - mUrlFocusLayoutAnimator.addListener(new AnimatorListenerAdapter() { - private boolean mCanceled; - + mUrlFocusLayoutAnimator.addListener(new CancelAwareAnimatorListener() { @Override - public void onAnimationStart(Animator animation) { + public void onStart(Animator animation) { if (!hasFocus) { mDisableLocationBarRelayout = true; } else { @@ -1764,14 +1763,12 @@ } @Override - public void onAnimationCancel(Animator animation) { - mCanceled = true; + public void onCancel(Animator animation) { + if (!hasFocus) mDisableLocationBarRelayout = false; } @Override - public void onAnimationEnd(Animator animation) { - if (mCanceled) return; - + public void onEnd(Animator animation) { if (!hasFocus) { mDisableLocationBarRelayout = false; mLayoutLocationBarInFocusedMode = false;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java index 8f0b7f14..acead93 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -10,6 +10,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; +import android.os.Build; import android.os.Handler; import android.os.StrictMode; import android.os.SystemClock; @@ -73,6 +74,8 @@ private static final String DAYDREAM_CATEGORY = "com.google.intent.category.DAYDREAM"; private static final String CARDBOARD_CATEGORY = "com.google.intent.category.CARDBOARD"; + private static final String MIN_SDK_VERSION_PARAM_NAME = "min_sdk_version"; + private static final String VR_ACTIVITY_ALIAS = "org.chromium.chrome.browser.VRChromeTabbedActivity"; @@ -126,6 +129,26 @@ mVrDaydreamApi = mVrClassesWrapper.createVrDaydreamApi(); } + // Check cardboard support for non-daydream devices. + if (!mVrDaydreamApi.isDaydreamReadyDevice()) { + // Native libraries may not be ready in which case skip for now and check later. + if (LibraryLoader.isInitialized()) { + // Supported Build version is determined by the webvr cardboard support feature. + // Default is KITKAT unless specified via server side finch config. + if (Build.VERSION.SDK_INT + < ChromeFeatureList.getFieldTrialParamByFeatureAsInt( + ChromeFeatureList.WEBVR_CARDBOARD_SUPPORT, + MIN_SDK_VERSION_PARAM_NAME, + Build.VERSION_CODES.KITKAT)) { + mVrSupportLevel = VR_NOT_AVAILABLE; + mEnterVRIntent = null; + mTabObserver = null; + mTabModelSelectorObserver = null; + return; + } + } + } + if (mEnterVRIntent == null) { mEnterVRIntent = mVrDaydreamApi.createVrIntent(new ComponentName(mActivity, VR_ACTIVITY_ALIAS)); @@ -172,6 +195,8 @@ * can be initialized. */ public void onNativeLibraryReady() { + // Libraries may not have been loaded when we first set the support level, so check again. + updateVrSupportLevel(); if (mVrSupportLevel == VR_NOT_AVAILABLE) return; mNativeVrShellDelegate = nativeInit(); Choreographer choreographer = Choreographer.getInstance();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java index 4c73c02f..6757f218 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
@@ -54,8 +54,8 @@ private static final float WEBVR_DPR = 1.0f; // Fairly arbitrary values that put a good amount of content on the screen without making the // text too small to read. - private static final float DEFAULT_CONTENT_WIDTH = 1024f; - private static final float DEFAULT_CONTENT_HEIGHT = 576f; + private static final float DEFAULT_CONTENT_WIDTH = 960f; + private static final float DEFAULT_CONTENT_HEIGHT = 640f; // Temporary values that will be changed when the UI loads and figures out how what size it // needs to be. private static final float DEFAULT_UI_WIDTH = 1920f;
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 97ac3fdff..6bb282b 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -743,7 +743,6 @@ "java/src/org/chromium/chrome/browser/physicalweb/PhysicalWebBleClient.java", "java/src/org/chromium/chrome/browser/physicalweb/PhysicalWebDiagnosticsPage.java", "java/src/org/chromium/chrome/browser/physicalweb/PhysicalWebEnvironment.java", - "java/src/org/chromium/chrome/browser/physicalweb/PhysicalWebOptInActivity.java", "java/src/org/chromium/chrome/browser/physicalweb/PhysicalWebUma.java", "java/src/org/chromium/chrome/browser/physicalweb/PwCollection.java", "java/src/org/chromium/chrome/browser/physicalweb/PwsClient.java",
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandlerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandlerTest.java index ac43c54..29028b7 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandlerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandlerTest.java
@@ -23,11 +23,6 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import org.chromium.base.test.util.Feature; -import org.chromium.chrome.browser.media.router.cast.CastMessageHandler.RequestRecord; -import org.chromium.chrome.browser.media.router.cast.JSONTestUtils.JSONObjectLike; -import org.chromium.chrome.browser.media.router.cast.JSONTestUtils.JSONStringLike; -import org.chromium.testing.local.LocalRobolectricTestRunner; import org.json.JSONException; import org.json.JSONObject; import org.junit.Before; @@ -38,6 +33,12 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowLog; +import org.chromium.base.test.util.Feature; +import org.chromium.chrome.browser.media.router.cast.CastMessageHandler.RequestRecord; +import org.chromium.chrome.browser.media.router.cast.JSONTestUtils.JSONObjectLike; +import org.chromium.chrome.browser.media.router.cast.JSONTestUtils.JSONStringLike; +import org.chromium.testing.local.LocalRobolectricTestRunner; + import java.util.ArrayDeque; import java.util.HashMap; import java.util.HashSet; @@ -273,7 +274,7 @@ any(JSONObject.class), anyString(), anyString(), anyInt()); for (String messageType : CastMessageHandler.getMediaMessageTypesForTest()) { // TODO(zqzhang): SET_VOLUME and STOP should not reach here? - if (messageType == "MEDIA_SET_VOLUME" || messageType == "STOP_MEDIA") + if ("MEDIA_SET_VOLUME".equals(messageType) || "STOP_MEDIA".equals(messageType)) continue; JSONObject innerMessage = new JSONObject().put("type", messageType); JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/BackgroundSchedulerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/BackgroundSchedulerTest.java index 2e8ab62..0e22add 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/BackgroundSchedulerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/BackgroundSchedulerTest.java
@@ -14,8 +14,6 @@ import com.google.android.gms.gcm.GcmNetworkManager; import com.google.android.gms.gcm.Task; -import org.chromium.base.BaseChromiumApplication; -import org.chromium.base.test.util.Feature; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -23,6 +21,9 @@ import org.robolectric.annotation.Config; import org.robolectric.internal.ShadowExtractor; +import org.chromium.base.BaseChromiumApplication; +import org.chromium.base.test.util.Feature; + /** * Unit tests for BackgroundScheduler. */ @@ -47,9 +48,8 @@ @Test @Feature({"OfflinePages"}) public void testSchedule() { - BackgroundScheduler scheduler = new BackgroundScheduler(); assertNull(mGcmNetworkManager.getScheduledTask()); - scheduler.schedule(mContext, mConditions1); + BackgroundScheduler.schedule(mContext, mConditions1); // Check with gcmNetworkManagerShadow that schedule got called. assertNotNull(mGcmNetworkManager.getScheduledTask()); @@ -65,13 +65,12 @@ @Test @Feature({"OfflinePages"}) public void testUnschedule() { - BackgroundScheduler scheduler = new BackgroundScheduler(); assertNull(mGcmNetworkManager.getScheduledTask()); - scheduler.schedule(mContext, mConditions1); + BackgroundScheduler.schedule(mContext, mConditions1); assertNotNull(mGcmNetworkManager.getScheduledTask()); assertNull(mGcmNetworkManager.getCanceledTask()); - scheduler.unschedule(mContext); + BackgroundScheduler.unschedule(mContext); assertNotNull(mGcmNetworkManager.getCanceledTask()); } }
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 8fb5016..87ac87bf 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -1434,6 +1434,12 @@ <message name="IDS_FLAGS_QUICK_UNLOCK_PIN_DESCRIPTION" desc="Description of the flag used to enable quick unlock pin."> Enabling PIN quick unlock allows you to use a PIN to unlock your Chromebook on the lock screen after you have signed into your device. </message> + <message name="IDS_FLAGS_QUICK_UNLOCK_FINGERPRINT" desc="Title of the flag used to enable quick unlock fingerprint."> + Quick Unlock (Fingerprint) + </message> + <message name="IDS_FLAGS_QUICK_UNLOCK_FINGERPRINT_DESCRIPTION" desc="Description of the flag used to enable quick unlock fingerprint."> + Enabling fingerprint quick unlock allows you to setup and use a fingerprint to unlock your Chromebook on the lock screen after you have signed into your device. + </message> <message name="IDS_OFFERS_CONSENT_INFOBAR_LABEL_LEARN_MORE" desc="Text of the Learn More link in the echo dialog."> Learn More </message>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index d4adc756..cf3abaf 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -2136,6 +2136,24 @@ <message name="IDS_SETTINGS_PEOPLE_LOCK_SCREEN_SETUP_PIN_BUTTON" desc="Button that is used to setup a new PIN when the user does not have a PIN yet."> Set up PIN </message> + <message name="IDS_SETTINGS_PEOPLE_LOCK_SCREEN_REGISTERED_FINGERPRINTS_LABEL" desc="Text above fingerprint list that tells users their registered fingerprints."> + Registered fingerprints: + </message> + <message name="IDS_SETTINGS_PEOPLE_LOCK_SCREEN_ADD_FINGERPRINT_BUTTON" desc="Button that is used to add a new fingerprint."> + Add Fingerprint + </message> + <message name="IDS_SETTINGS_PEOPLE_LOCK_SCREEN_CANNOT_ADD_NEW_FINGERPRINT" desc="Text telling users they have reached the maximum allowed fingerprints."> + You can only add <ph name="MAX_FINGERPRINTS">$1<ex>5</ex></ph> fingerprints. + </message> + <message name="IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_LESS_SECURE" desc="Text telling users that fingerprints might be less secure than strong PINs or passwords."> + Note: Your fingerprint may be less secure than a strong password or PIN. + </message> + <message name="IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NEW_FINGERPRINT_DEFAULT_NAME" desc="The default name (plus a number for a newly added fingerprint)."> + Finger <ph name="NEW_FINGER_NUMBER">$1<ex>1</ex></ph> + </message> + <message name="IDS_SETTINGS_PEOPLE_LOCK_SCREEN_ENABLE_FINGERPRINT_CHECKBOX_LABEL" desc="The text on the label of the checkbox which allows users to enable or disable fingerprint usage."> + Enable fingerprint login and authentication + </message> <message name="IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_TITLE" desc="Title of the password prompt dialog popup."> Confirm your password </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 38d3592..561d9e3 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2061,6 +2061,9 @@ {"quick-unlock-pin", IDS_FLAGS_QUICK_UNLOCK_PIN, IDS_FLAGS_QUICK_UNLOCK_PIN_DESCRIPTION, kOsCrOS, FEATURE_VALUE_TYPE(features::kQuickUnlockPin)}, + {"quick-unlock-fingerprint", IDS_FLAGS_QUICK_UNLOCK_FINGERPRINT, + IDS_FLAGS_QUICK_UNLOCK_FINGERPRINT_DESCRIPTION, kOsCrOS, + FEATURE_VALUE_TYPE(features::kQuickUnlockFingerprint)}, #endif // OS_CHROMEOS {"browser-task-scheduler", IDS_FLAGS_BROWSER_TASK_SCHEDULER_NAME, IDS_FLAGS_BROWSER_TASK_SCHEDULER_DESCRIPTION, kOsAll,
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index d237ad8..c2886e3 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -11,6 +11,7 @@ #include "base/android/jni_string.h" #include "base/feature_list.h" #include "base/macros.h" +#include "base/metrics/field_trial_params.h" #include "chrome/common/chrome_features.h" #include "components/autofill/core/browser/autofill_experiments.h" #include "components/ntp_snippets/features.h" @@ -60,6 +61,7 @@ &kTabReparenting, &kWebPaymentsModifiers, &kWebPaymentsSingleAppUiSkip, + &kWebVRCardboardSupport, &ntp_snippets::kIncreasedVisibility, &ntp_snippets::kForeignSessionsSuggestionsFeature, &ntp_snippets::kOfflineBadgeFeature, @@ -144,6 +146,9 @@ const base::Feature kWebPaymentsSingleAppUiSkip{ "WebPaymentsSingleAppUiSkip", base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kWebVRCardboardSupport{ + "WebVRCardboardSupport", base::FEATURE_ENABLED_BY_DEFAULT}; + static jboolean IsEnabled(JNIEnv* env, const JavaParamRef<jclass>& clazz, const JavaParamRef<jstring>& jfeature_name) { @@ -157,6 +162,26 @@ return false; } +static jint GetFieldTrialParamByFeatureAsInt( + JNIEnv* env, + const JavaParamRef<jclass>& clazz, + const JavaParamRef<jstring>& jfeature_name, + const JavaParamRef<jstring>& jparam_name, + const jint jdefault_value) { + const std::string feature_name = ConvertJavaStringToUTF8(env, jfeature_name); + const std::string param_name = ConvertJavaStringToUTF8(env, jparam_name); + int default_value = static_cast<int>(jdefault_value); + + for (size_t i = 0; i < arraysize(kFeaturesExposedToJava); ++i) { + if (kFeaturesExposedToJava[i]->name == feature_name) + return base::GetFieldTrialParamByFeatureAsInt( + *kFeaturesExposedToJava[i], param_name, default_value); + } + // Features queried via this API must be present in |kFeaturesExposedToJava|. + NOTREACHED(); + return jdefault_value; +} + bool RegisterChromeFeatureListJni(JNIEnv* env) { return RegisterNativesImpl(env); }
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index e7e6ea2c..00fff86 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -36,6 +36,7 @@ extern const base::Feature kUserMediaScreenCapturing; extern const base::Feature kWebPaymentsModifiers; extern const base::Feature kWebPaymentsSingleAppUiSkip; +extern const base::Feature kWebVRCardboardSupport; bool RegisterChromeFeatureListJni(JNIEnv* env);
diff --git a/chrome/browser/android/vr_shell/ui_interface.h b/chrome/browser/android/vr_shell/ui_interface.h index 85b2c862..d31995d8 100644 --- a/chrome/browser/android/vr_shell/ui_interface.h +++ b/chrome/browser/android/vr_shell/ui_interface.h
@@ -26,7 +26,7 @@ class UiInterface { public: enum Mode { - STANDARD, + STANDARD = 0, WEB_VR };
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index 6c43cf7..f6268fe2 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -562,6 +562,11 @@ } bool AccessibilityManager::ShouldToggleSpokenFeedbackViaTouch() { +#if 1 + // Temporarily disabling this feature until UI feedback is fixed. + // http://crbug.com/662501 + return false; +#else policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos(); if (!connector) @@ -582,6 +587,7 @@ KioskAppManager::App app; CHECK(manager->GetApp(manager->GetAutoLaunchApp(), &app)); return app.was_auto_launched_with_zero_delay; +#endif } bool AccessibilityManager::PlaySpokenFeedbackToggleCountdown(int tick_count) {
diff --git a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc index 653539f..79307a47 100644 --- a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc +++ b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc
@@ -36,6 +36,8 @@ // 0 indicates no maximum length for the pin. registry->RegisterIntegerPref(prefs::kPinUnlockMaximumLength, 0); registry->RegisterBooleanPref(prefs::kPinUnlockWeakPinsAllowed, true); + + registry->RegisterBooleanPref(prefs::kEnableQuickUnlockFingerprint, false); } bool IsPinUnlockEnabled(PrefService* pref_service) { @@ -64,6 +66,11 @@ return base::FeatureList::IsEnabled(features::kQuickUnlockPin); } +bool IsFingerprintUnlockEnabled() { + // Enable fingerprint unlock only if the switch is present. + return base::FeatureList::IsEnabled(features::kQuickUnlockFingerprint); +} + void EnableQuickUnlockForTesting() { enable_for_testing_ = true; }
diff --git a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h index 845574e..979d4eec 100644 --- a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h +++ b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h
@@ -28,6 +28,9 @@ // flag is present. bool IsPinUnlockEnabled(PrefService* pref_service); +// Returns true if the fingerprint unlock feature flag is present. +bool IsFingerprintUnlockEnabled(); + // Forcibly enable quick-unlock for testing. void EnableQuickUnlockForTesting();
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index 00d49ea5..7848899 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -208,6 +208,8 @@ settings_private::PrefType::PREF_TYPE_LIST; (*s_whitelist)[::prefs::kEnableAutoScreenLock] = settings_private::PrefType::PREF_TYPE_BOOLEAN; + (*s_whitelist)[::prefs::kEnableQuickUnlockFingerprint] = + settings_private::PrefType::PREF_TYPE_BOOLEAN; // Accessibility. (*s_whitelist)[::prefs::kAccessibilitySpokenFeedbackEnabled] =
diff --git a/chrome/browser/extensions/updater/local_extension_cache.cc b/chrome/browser/extensions/updater/local_extension_cache.cc index 84295d7..ee92b47 100644 --- a/chrome/browser/extensions/updater/local_extension_cache.cc +++ b/chrome/browser/extensions/updater/local_extension_cache.cc
@@ -560,7 +560,8 @@ CacheMap::iterator it = InsertCacheEntry(cached_extensions_, id, info, false); if (it == cached_extensions_.end()) { - DCHECK(0) << "Cache contains newer or the same version"; + LOG(WARNING) << "Cache contains newer or the same version for extension " + << id << " version " << info.version; callback.Run(info.file_path, true); return; }
diff --git a/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win_unittest.cc b/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win_unittest.cc index 3b97bc2..7d0f923 100644 --- a/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win_unittest.cc +++ b/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win_unittest.cc
@@ -111,11 +111,6 @@ } void MTPDeviceDelegateImplWinTest::TearDown() { - // The MediaFileSystemRegistry owned by the TestingBrowserProcess must be - // destroyed before the StorageMonitor because it calls - // StorageMonitor::RemoveObserver() in its destructor. - TestingBrowserProcess::DeleteInstance(); - // Windows storage monitor must be destroyed on the same thread // as construction. TestStorageMonitor::Destroy();
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index f352d9c..a13f2b9 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -742,6 +742,21 @@ ASSERT_MULTILINE_STREQ(kExpectedPDFAXTree, ax_tree_dump); } +#if defined(GOOGLE_CHROME_BUILD) +// Test a particular PDF encountered in the wild that triggered a crash +// when accessibility is enabled. (http://crbug.com/668724) +IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilityTextRunCrash) { + content::BrowserAccessibilityState::GetInstance()->EnableAccessibility(); + GURL test_pdf_url(embedded_test_server()->GetURL( + "/pdf_private/accessibility_crash_2.pdf")); + + content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url); + ASSERT_TRUE(guest_contents); + + WaitForAccessibilityTreeToContainNodeWithName(guest_contents, "Page 1"); +} +#endif + IN_PROC_BROWSER_TEST_F(PDFExtensionTest, LinkCtrlLeftClick) { host_resolver()->AddRule("www.example.com", "127.0.0.1"); GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-link.pdf"));
diff --git a/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.js b/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.js index ade63273..b6d0678 100644 --- a/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.js +++ b/chrome/browser/resources/options/chromeos/quick_unlock_configure_overlay.js
@@ -66,7 +66,8 @@ var lockScreen = document.querySelector('settings-lock-screen'); var checkbox = - lockScreen.root.querySelector('div.settings-box'); + lockScreen.root.querySelector( + 'div.settings-box.single-column.screen-lock'); checkbox.hidden = true; var passwordPrompt = lockScreen.root.
diff --git a/chrome/browser/resources/options_resources.grd b/chrome/browser/resources/options_resources.grd index ae79ee13..afb6dcd 100644 --- a/chrome/browser/resources/options_resources.grd +++ b/chrome/browser/resources/options_resources.grd
@@ -64,6 +64,12 @@ type="chrome_html" flattenhtml="true" allowexternalscript="true" /> + <structure name="IDR_OPTIONS_FINGERPRINT_LIST_JS" + file="settings/people_page/fingerprint_list.js" + type="chrome_html" /> + <structure name="IDR_OPTIONS_FINGERPRINT_LIST_HTML" + file="settings/people_page/fingerprint_list.html" + type="chrome_html" /> <structure name="IDR_OPTIONS_LOCK_SCREEN_JS" file="settings/people_page/lock_screen.js" type="chrome_html" />
diff --git a/chrome/browser/resources/settings/people_page/fingerprint_list.html b/chrome/browser/resources/settings/people_page/fingerprint_list.html new file mode 100644 index 0000000..5483336 --- /dev/null +++ b/chrome/browser/resources/settings/people_page/fingerprint_list.html
@@ -0,0 +1,36 @@ +<link rel="import" href="chrome://resources/cr_elements/icons.html"> +<link rel="import" href="chrome://resources/html/i18n_behavior.html"> +<link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html"> +<link rel="import" href="/settings_shared_css.html"> + +<dom-module id="settings-fingerprint-list"> + <template> + <style include="settings-shared"></style> + + <div>$i18n{lockScreenRegisteredFingerprints}</div> + <iron-list id="fingerprintsList" items="[[fingerprints_]]"> + <template> + <div class="list-item"> + <paper-input value="{{item}}"></paper-input> + <button is="paper-icon-button-light" + on-tap="onFingerprintDelete_"> + <iron-icon icon="cr:delete"></iron-icon> + </button> + </paper-icon-button> + </div> + </template> + </iron-list> + <div class="settings-box first radio-indent"> + <paper-button class="action-button" on-tap="onAddFingerprint_" + disabled="[[!canAddNewFingerprint_(fingerprints_.*)]]"> + [[getFingerprintButtonText_(fingerprints_.*)]] + </paper-button> + </div> + <i>$i18n{lockScreenFingerprintWarning}</i> + </template> + <script src="fingerprint_list.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/settings/people_page/fingerprint_list.js b/chrome/browser/resources/settings/people_page/fingerprint_list.js new file mode 100644 index 0000000..46deca9 --- /dev/null +++ b/chrome/browser/resources/settings/people_page/fingerprint_list.js
@@ -0,0 +1,82 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(function() { +'use strict'; + +/** + * The max number of fingerprints this list can hold. + * @const {number} + */ +var MAX_NUMBER_FINGERPRINTS_ALLOWED = 5; + +Polymer({ + is: 'settings-fingerprint-list', + + behaviors: [ + I18nBehavior, + ], + + properties: { + /** + * The list of fingerprint objects. + * @private {!Array<string>} + */ + fingerprints_: { + type: Array, + value: function() { + return []; + } + } + }, + + /** + * Adds a fingerprint with a default name. + * @private + */ + onAddFingerprint_: function() { + // Determines what the newly added fingerprint's name should be. + // TODO(sammiequon): Add fingerprint using private API once it is ready. + + for (var i = 1; i <= MAX_NUMBER_FINGERPRINTS_ALLOWED; ++i) { + var fingerprintName = this.i18n('lockScreenFingerprintNewName', i); + if (!this.fingerprints_.includes(fingerprintName)) { + this.push('fingerprints_', fingerprintName); + break; + } + } + }, + + /** + * Deletes a fingerprint from |fingerprints_|. + * @private + */ + onFingerprintDelete_: function(e) { + // TODO(sammiequon): Remove fingerprint using private API once it is ready. + this.splice('fingerprints_', e.model.index, 1); + }, + + /** + * Returns the text to be displayed for the add fingerprint button. + * @return {string} + * @private + */ + getFingerprintButtonText_: function() { + if (this.canAddNewFingerprint_()) + return this.i18n('lockScreenAddFingerprint'); + + return this.i18n('lockScreenCannotAddFingerprint', + MAX_NUMBER_FINGERPRINTS_ALLOWED); + }, + + /** + * Checks whether another fingerprint can be added. + * @return {boolean} + * @private + */ + canAddNewFingerprint_: function() { + return this.fingerprints_.length < MAX_NUMBER_FINGERPRINTS_ALLOWED; + } +}); +})();
diff --git a/chrome/browser/resources/settings/people_page/lock_screen.html b/chrome/browser/resources/settings/people_page/lock_screen.html index b55127bc97..63b6748a 100644 --- a/chrome/browser/resources/settings/people_page/lock_screen.html +++ b/chrome/browser/resources/settings/people_page/lock_screen.html
@@ -4,6 +4,7 @@ <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html"> <link rel="import" href="/controls/settings_toggle_button.html"> +<link rel="import" href="/people_page/fingerprint_list.html"> <link rel="import" href="/people_page/lock_screen_constants.html"> <link rel="import" href="/people_page/lock_state_behavior.html"> <link rel="import" href="/people_page/password_prompt_dialog.html"> @@ -38,6 +39,21 @@ </div> </div> + <template is="dom-if" if="[[fingerprintUnlockEnabled_]]"> + <div class="settings-box"> + <settings-toggle-button class="start" + pref="{{prefs.settings.enable_quick_unlock_fingerprint}}" + label="$i18n{lockScreenFingerprintEnable}"> + </settings-toggle-button> + </div> + <iron-collapse + opened="[[prefs.settings.enable_quick_unlock_fingerprint.value]]"> + <div class="settings-box continuation"> + <settings-fingerprint-list></settings-fingerprint-list> + </div> + </iron-collapse> + </template> + <div class="settings-box"> <settings-toggle-button class="start" pref="{{prefs.settings.enable_screen_lock}}"
diff --git a/chrome/browser/resources/settings/people_page/lock_screen.js b/chrome/browser/resources/settings/people_page/lock_screen.js index 73fcdb6..0ea3d20 100644 --- a/chrome/browser/resources/settings/people_page/lock_screen.js +++ b/chrome/browser/resources/settings/people_page/lock_screen.js
@@ -48,7 +48,31 @@ writeUma_: { type: Object, value: function() { return settings.recordLockScreenProgress; } - } + }, + + /** + * True if pin unlock settings should be displayed on this machine. + * @private + */ + pinUnlockEnabled_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('pinUnlockEnabled'); + }, + readOnly: true, + }, + + /** + * True if fingerprint unlock settings should be displayed on this machine. + * @private + */ + fingerprintUnlockEnabled_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('fingerprintUnlockEnabled'); + }, + readOnly: true, + }, }, /** selectedUnlockType is defined in LockStateBehavior. */
diff --git a/chrome/browser/resources/settings/people_page/people_page.js b/chrome/browser/resources/settings/people_page/people_page.js index d019e75..76115fdd 100644 --- a/chrome/browser/resources/settings/people_page/people_page.js +++ b/chrome/browser/resources/settings/people_page/people_page.js
@@ -89,7 +89,8 @@ quickUnlockEnabled_: { type: Boolean, value: function() { - return loadTimeData.getBoolean('pinUnlockEnabled'); + return loadTimeData.getBoolean('pinUnlockEnabled') || + loadTimeData.getBoolean('fingerprintUnlockEnabled'); }, readOnly: true, },
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd index ef20bb8..5b6389b 100644 --- a/chrome/browser/resources/settings/settings_resources.grd +++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -1187,6 +1187,12 @@ type="chrome_html" preprocess="true" allowexternalscript="true" /> + <structure name="IDR_SETTINGS_PEOPLE_FINGERPRINT_LIST_JS" + file="people_page/fingerprint_list.js" + type="chrome_html" /> + <structure name="IDR_SETTINGS_PEOPLE_FINGERPRINT_LIST_HTML" + file="people_page/fingerprint_list.html" + type="chrome_html" /> <structure name="IDR_SETTINGS_KEYBOARD_PIN_JS" file="people_page/pin_keyboard.js" type="chrome_html"
diff --git a/chrome/browser/resources/vr_shell/vr_shell_ui.js b/chrome/browser/resources/vr_shell/vr_shell_ui.js index df4c561..86cc664a 100644 --- a/chrome/browser/resources/vr_shell/vr_shell_ui.js +++ b/chrome/browser/resources/vr_shell/vr_shell_ui.js
@@ -31,6 +31,9 @@ /** @const */ this.SCREEN_RATIO = 16 / 9; /** @const */ this.BROWSING_SCREEN_DISTANCE = 2.0; /** @const */ this.FULLSCREEN_DISTANCE = 3.0; + /** @const */ this.CSS_WIDTH_PIXELS = 960.0; + /** @const */ this.CSS_HEIGHT_PIXELS = 640.0; + /** @const */ this.DPR = 1.2; let element = new api.UiElement(0, 0, 0, 0); element.setIsContentQuad(); @@ -45,6 +48,13 @@ let update = new api.UiElementUpdate(); update.setVisible(enabled); ui.updateElement(this.elementId, update); + if (enabled) { + api.setContentCssSize( + this.CSS_WIDTH_PIXELS, this.CSS_HEIGHT_PIXELS, this.DPR); + } else { + // TODO(mthiesse): Restore the webVR resolution (which matches native + // display resolution). + } } setOpacity(opacity) {
diff --git a/chrome/browser/resources/vr_shell/vr_shell_ui_api.js b/chrome/browser/resources/vr_shell/vr_shell_ui_api.js index 5424ca723..2979532 100644 --- a/chrome/browser/resources/vr_shell/vr_shell_ui_api.js +++ b/chrome/browser/resources/vr_shell/vr_shell_ui_api.js
@@ -99,6 +99,16 @@ }; /** + * Sets the CSS size for the content window. + * @param {number} width + * @param {number} height + * @param {number} dpr + */ +api.setContentCssSize = function(width, height, dpr) { + chrome.send('setContentCssSize', [width, height, dpr]); +}; + +/** * Sets the CSS size for this page. * @param {number} width * @param {number} height
diff --git a/chrome/browser/safe_browsing/download_protection_service.cc b/chrome/browser/safe_browsing/download_protection_service.cc index beb0d06..570dd2c 100644 --- a/chrome/browser/safe_browsing/download_protection_service.cc +++ b/chrome/browser/safe_browsing/download_protection_service.cc
@@ -1065,10 +1065,12 @@ ReferrerChainData* referrer_chain_data = static_cast<ReferrerChainData*>( item_->GetUserData(kDownloadReferrerChainDataKey)); - if (referrer_chain_data && - !referrer_chain_data->GetReferrerChain()->empty()) { - request.mutable_referrer_chain()->Swap( - referrer_chain_data->GetReferrerChain()); + if (referrer_chain_data) { + request.set_download_attribution_finch_enabled(true); + if (!referrer_chain_data->GetReferrerChain()->empty()) { + request.mutable_referrer_chain()->Swap( + referrer_chain_data->GetReferrerChain()); + } } if (archive_is_valid_ != ArchiveValid::UNSET) @@ -1300,6 +1302,8 @@ scoped_refptr<SafeBrowsingDatabaseManager> database_manager) : requestor_url_(requestor_url), initiating_frame_url_(initiating_frame_url), + initiating_main_frame_url_( + web_contents ? web_contents->GetLastCommittedURL() : GURL()), tab_id_(SessionTabHelper::IdForTab(web_contents)), default_file_path_(default_file_path), alternate_extensions_(alternate_extensions), @@ -1433,10 +1437,8 @@ } service_->AddReferrerChainToPPAPIClientDownloadRequest( - initiating_frame_url_, - tab_id_, - has_user_gesture_, - &request); + initiating_frame_url_, initiating_main_frame_url_, tab_id_, + has_user_gesture_, &request); if (!request.SerializeToString(&client_download_request_data_)) { // More of an internal error than anything else. Note that the UNKNOWN @@ -1560,9 +1562,12 @@ // URL of document that requested the PPAPI download. const GURL requestor_url_; - // URL of the frame that hosted the PPAPI plugin. + // URL of the frame that hosts the PPAPI plugin. const GURL initiating_frame_url_; + // URL of the tab that contains the initialting_frame. + const GURL initiating_main_frame_url_; + // Tab id that associated with the PPAPI plugin, computed by // SessionTabHelper::IdForTab(). int tab_id_; @@ -1906,10 +1911,11 @@ } void DownloadProtectionService::AddReferrerChainToPPAPIClientDownloadRequest( - const GURL& initiating_frame_url, - int tab_id, - bool has_user_gesture, - ClientDownloadRequest* out_request) { + const GURL& initiating_frame_url, + const GURL& initiating_main_frame_url, + int tab_id, + bool has_user_gesture, + ClientDownloadRequest* out_request) { if (!base::FeatureList::IsEnabled( SafeBrowsingNavigationObserverManager::kDownloadAttribution) || !navigation_observer_manager_) { @@ -1921,10 +1927,8 @@ tab_id == -1); SafeBrowsingNavigationObserverManager::AttributionResult result = navigation_observer_manager_->IdentifyReferrerChainForPPAPIDownload( - initiating_frame_url, - tab_id, - has_user_gesture, - kDownloadAttributionUserGestureLimit, + initiating_frame_url, initiating_main_frame_url, tab_id, + has_user_gesture, kDownloadAttributionUserGestureLimit, out_request->mutable_referrer_chain()); UMA_HISTOGRAM_COUNTS_100( "SafeBrowsing.ReferrerURLChainSize.PPAPIDownloadAttribution", @@ -1932,6 +1936,7 @@ UMA_HISTOGRAM_ENUMERATION( "SafeBrowsing.ReferrerAttributionResult.PPAPIDownloadAttribution", result, SafeBrowsingNavigationObserverManager::ATTRIBUTION_FAILURE_TYPE_MAX); + out_request->set_download_attribution_finch_enabled(true); } } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/download_protection_service.h b/chrome/browser/safe_browsing/download_protection_service.h index 6bbbb4c..4272abc 100644 --- a/chrome/browser/safe_browsing/download_protection_service.h +++ b/chrome/browser/safe_browsing/download_protection_service.h
@@ -308,10 +308,11 @@ // Then add referrer chain info to ClientDownloadRequest proto. This function // also records UMA stats of download attribution result. void AddReferrerChainToPPAPIClientDownloadRequest( - const GURL& initiating_frame_url, - int tab_id, - bool has_user_gesture, - ClientDownloadRequest* out_request); + const GURL& initiating_frame_url, + const GURL& initiating_main_frame_url, + int tab_id, + bool has_user_gesture, + ClientDownloadRequest* out_request); // These pointers may be NULL if SafeBrowsing is disabled. scoped_refptr<SafeBrowsingUIManager> ui_manager_;
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc index 7e0b419..9dd7af90 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc
@@ -31,40 +31,36 @@ : source_url(), source_main_frame_url(), original_request_url(), - destination_url(), source_tab_id(-1), target_tab_id(-1), frame_id(-1), last_updated(base::Time::Now()), is_user_initiated(false), - has_committed(false), - has_server_redirect(false) {} + has_committed(false) {} NavigationEvent::NavigationEvent(NavigationEvent&& nav_event) : source_url(std::move(nav_event.source_url)), source_main_frame_url(std::move(nav_event.source_main_frame_url)), original_request_url(std::move(nav_event.original_request_url)), - destination_url(std::move(nav_event.destination_url)), + server_redirect_urls(std::move(nav_event.server_redirect_urls)), source_tab_id(std::move(nav_event.source_tab_id)), target_tab_id(std::move(nav_event.target_tab_id)), frame_id(nav_event.frame_id), last_updated(nav_event.last_updated), is_user_initiated(nav_event.is_user_initiated), - has_committed(nav_event.has_committed), - has_server_redirect(nav_event.has_server_redirect) {} + has_committed(nav_event.has_committed) {} NavigationEvent& NavigationEvent::operator=(NavigationEvent&& nav_event) { source_url = std::move(nav_event.source_url); source_main_frame_url = std::move(nav_event.source_main_frame_url); original_request_url = std::move(nav_event.original_request_url); - destination_url = std::move(nav_event.destination_url); source_tab_id = nav_event.source_tab_id; target_tab_id = nav_event.target_tab_id; frame_id = nav_event.frame_id; last_updated = nav_event.last_updated; is_user_initiated = nav_event.is_user_initiated; has_committed = nav_event.has_committed; - has_server_redirect = nav_event.has_server_redirect; + server_redirect_urls = std::move(nav_event.server_redirect_urls); return *this; } @@ -160,7 +156,6 @@ nav_event.original_request_url = SafeBrowsingNavigationObserverManager::ClearEmptyRef( navigation_handle->GetURL()); - nav_event.destination_url = nav_event.original_request_url; nav_event.source_tab_id = SessionTabHelper::IdForTab(navigation_handle->GetWebContents()); @@ -185,10 +180,9 @@ } NavigationEvent* nav_event = &navigation_handle_map_[navigation_handle]; - nav_event->has_server_redirect = true; - nav_event->destination_url = + nav_event->server_redirect_urls.push_back( SafeBrowsingNavigationObserverManager::ClearEmptyRef( - navigation_handle->GetURL()); + navigation_handle->GetURL())); nav_event->last_updated = base::Time::Now(); } @@ -212,7 +206,7 @@ SessionTabHelper::IdForTab(navigation_handle->GetWebContents()); nav_event->last_updated = base::Time::Now(); - manager_->RecordNavigationEvent(nav_event->destination_url, nav_event); + manager_->RecordNavigationEvent(nav_event->GetDestinationUrl(), nav_event); navigation_handle_map_.erase(navigation_handle); }
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h index f08f42ef..cfeccac 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h
@@ -33,10 +33,10 @@ // same as source_url, if source_url was loaded // in main frame. GURL original_request_url; // The original request URL of this navigation. - GURL destination_url; // The actual destination url of this navigation - // event. If this navigation has server side - // redirect(s), actual_target_url will be - // different from initial_request_url. + std::vector<GURL> server_redirect_urls; // Server redirect url chain. + // Empty if there is no server + // redirect. If set, last url in this + // vector is the destination url. int source_tab_id; // Which tab contains the frame with source_url. Tab ID is // returned by SessionTabHelper::IdForTab. This ID is // immutable for a given tab and unique across Chrome @@ -47,7 +47,13 @@ base::Time last_updated; // When this NavigationEvent was last updated. bool is_user_initiated; // browser_initiated || has_user_gesture. bool has_committed; - bool has_server_redirect; + + const GURL& GetDestinationUrl() const { + if (!server_redirect_urls.empty()) + return server_redirect_urls.back(); + else + return original_request_url; + } }; // Structure to keep track of resolved IP address of a host.
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc index 4846488..48c91f7 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
@@ -221,21 +221,31 @@ actual_nav_event.source_main_frame_url); EXPECT_EQ(expected_original_request_url, actual_nav_event.original_request_url); - EXPECT_EQ(expected_destination_url, actual_nav_event.destination_url); + EXPECT_EQ(expected_destination_url, actual_nav_event.GetDestinationUrl()); EXPECT_EQ(expected_is_user_initiated, actual_nav_event.is_user_initiated); EXPECT_EQ(expected_has_committed, actual_nav_event.has_committed); EXPECT_EQ(expected_has_server_redirect, - actual_nav_event.has_server_redirect); + !actual_nav_event.server_redirect_urls.empty()); } - void VerifyReferrerChainEntry(const GURL& expected_url, - ReferrerChainEntry::URLType expected_type, - const std::string& expected_ip_address, - const GURL& expected_referrer_url, - const GURL& expected_referrer_main_frame_url, - bool expected_is_retargeting, - const ReferrerChainEntry& actual_entry) { + void VerifyReferrerChainEntry( + const GURL& expected_url, + const GURL& expected_main_frame_url, + ReferrerChainEntry::URLType expected_type, + const std::string& expected_ip_address, + const GURL& expected_referrer_url, + const GURL& expected_referrer_main_frame_url, + bool expected_is_retargeting, + const std::vector<GURL>& expected_server_redirects, + const ReferrerChainEntry& actual_entry) { EXPECT_EQ(expected_url.spec(), actual_entry.url()); + if (expected_main_frame_url.is_empty()) { + EXPECT_FALSE(actual_entry.has_main_frame_url()); + } else { + // main_frame_url only set if it is different from url. + EXPECT_EQ(expected_main_frame_url.spec(), actual_entry.main_frame_url()); + EXPECT_NE(expected_main_frame_url.spec(), actual_entry.url()); + } EXPECT_EQ(expected_type, actual_entry.type()); if (expected_ip_address.empty()) { ASSERT_EQ(0, actual_entry.ip_addresses_size()); @@ -244,9 +254,26 @@ EXPECT_EQ(expected_ip_address, actual_entry.ip_addresses(0)); } EXPECT_EQ(expected_referrer_url.spec(), actual_entry.referrer_url()); - EXPECT_EQ(expected_referrer_main_frame_url.spec(), - actual_entry.referrer_main_frame_url()); + if (expected_referrer_main_frame_url.is_empty()) { + EXPECT_FALSE(actual_entry.has_referrer_main_frame_url()); + } else { + // referrer_main_frame_url only set if it is different from referrer_url. + EXPECT_EQ(expected_referrer_main_frame_url.spec(), + actual_entry.referrer_main_frame_url()); + EXPECT_NE(expected_referrer_main_frame_url.spec(), + actual_entry.referrer_url()); + } EXPECT_EQ(expected_is_retargeting, actual_entry.is_retargeting()); + if (expected_server_redirects.empty()) { + EXPECT_EQ(0, actual_entry.server_redirect_chain_size()); + } else { + ASSERT_EQ(static_cast<int>(expected_server_redirects.size()), + actual_entry.server_redirect_chain_size()); + for (int i = 0; i < actual_entry.server_redirect_chain_size(); i++) { + EXPECT_EQ(expected_server_redirects[i].spec(), + actual_entry.server_redirect_chain(i).url()); + } + } } // Identify referrer chain of a DownloadItem and populate |referrer_chain|. @@ -273,9 +300,8 @@ bool has_user_gesture = observer_manager_->HasUserGesture(web_contents); observer_manager_->OnUserGestureConsumed(web_contents, base::Time::Now()); EXPECT_LE(observer_manager_->IdentifyReferrerChainForPPAPIDownload( - initiating_frame_url, - tab_id, - has_user_gesture, + initiating_frame_url, web_contents->GetLastCommittedURL(), + tab_id, has_user_gesture, 2, // kDownloadAttributionUserGestureLimit) referrer_chain), SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_REFERRER); @@ -350,11 +376,13 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); ASSERT_EQ(1, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type test_server_ip, // ip_address GURL(), // referrer_url - GURL(), // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); } // Click on a link and start download on the same page. @@ -390,18 +418,22 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); ASSERT_EQ(2, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type test_server_ip, // ip_address initial_url, // referrer_url - initial_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); VerifyReferrerChainEntry(initial_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address GURL(), // referrer_url - GURL(), // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); } @@ -440,18 +472,22 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); ASSERT_EQ(2, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type test_server_ip, // ip_address initial_url, // referrer_url - initial_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); VerifyReferrerChainEntry(initial_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address GURL(), // referrer_url - GURL(), // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); } @@ -504,18 +540,22 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); ASSERT_EQ(2, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type test_server_ip, // ip_address initial_url, // referrer_url - initial_url, // referrer_main_frame_url - true, // is_retargeting + GURL(), // referrer_main_frame_url + true, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); VerifyReferrerChainEntry(initial_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address GURL(), // referrer_url - GURL(), // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); } @@ -566,25 +606,31 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); ASSERT_EQ(3, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type test_server_ip, // ip_address redirect_url, // referrer_url - redirect_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); - VerifyReferrerChainEntry(redirect_url, // url + VerifyReferrerChainEntry(redirect_url, // url + GURL(), // main_frame_url ReferrerChainEntry::CLIENT_REDIRECT, // type test_server_ip, // ip_address initial_url, // referrer_url - initial_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); VerifyReferrerChainEntry(initial_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address GURL(), // referrer_url - GURL(), // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(2)); } @@ -644,25 +690,31 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); ASSERT_EQ(3, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type test_server_ip, // ip_address redirect_url, // referrer_url - redirect_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); - VerifyReferrerChainEntry(redirect_url, // url + VerifyReferrerChainEntry(redirect_url, // url + GURL(), // main_frame_url ReferrerChainEntry::CLIENT_REDIRECT, // type test_server_ip, // ip_address initial_url, // referrer_url - initial_url, // referrer_main_frame_url - true, // is_retargeting + GURL(), // referrer_main_frame_url + true, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); VerifyReferrerChainEntry(initial_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address GURL(), // referrer_url - GURL(), // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(2)); } @@ -723,32 +775,40 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); ASSERT_EQ(4, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type test_server_ip, // ip_address second_redirect_url, // referrer_url - second_redirect_url, // referrer_main_frame_url + GURL(), // referrer_main_frame_url false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); - VerifyReferrerChainEntry(second_redirect_url, // url + VerifyReferrerChainEntry(second_redirect_url, // url + GURL(), // main_frame_url ReferrerChainEntry::CLIENT_REDIRECT, // type test_server_ip, // ip_address first_redirect_url, // referrer_url - first_redirect_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); - VerifyReferrerChainEntry(first_redirect_url, // url + VerifyReferrerChainEntry(first_redirect_url, // url + GURL(), // main_frame_url ReferrerChainEntry::CLIENT_REDIRECT, // type test_server_ip, // ip_address initial_url, // referrer_url - initial_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(2)); VerifyReferrerChainEntry(initial_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address GURL(), // referrer_url - GURL(), // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(3)); } @@ -786,18 +846,22 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); ASSERT_EQ(2, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type test_server_ip, // ip_address initial_url, // referrer_url - initial_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); VerifyReferrerChainEntry(initial_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address GURL(), // referrer_url - GURL(), // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); } @@ -846,25 +910,31 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); ASSERT_EQ(3, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type test_server_ip, // ip_address redirect_url, // referrer_url - redirect_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); - VerifyReferrerChainEntry(redirect_url, // url + VerifyReferrerChainEntry(redirect_url, // url + GURL(), // main_frame_url ReferrerChainEntry::CLIENT_REDIRECT, // type test_server_ip, // ip_address initial_url, // referrer_url - initial_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); VerifyReferrerChainEntry(initial_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address GURL(), // referrer_url - GURL(), // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(2)); } @@ -926,25 +996,31 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); ASSERT_EQ(3, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type test_server_ip, // ip_address blank_url, // referrer_url - blank_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); - VerifyReferrerChainEntry(blank_url, // url + VerifyReferrerChainEntry(blank_url, // url + GURL(), // main_frame_url ReferrerChainEntry::CLIENT_REDIRECT, // type "", // ip_address initial_url, // referrer_url - initial_url, // referrer_main_frame_url - true, // is_retargeting + GURL(), // referrer_main_frame_url + true, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); VerifyReferrerChainEntry(initial_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address GURL(), // referrer_url - GURL(), // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(2)); } @@ -1008,25 +1084,31 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); ASSERT_EQ(3, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type "", // ip_address blank_url, // referrer_url - blank_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); - VerifyReferrerChainEntry(blank_url, // url + VerifyReferrerChainEntry(blank_url, // url + GURL(), // main_frame_url ReferrerChainEntry::CLIENT_REDIRECT, // type "", // ip_address initial_url, // referrer_url - initial_url, // referrer_main_frame_url - true, // is_retargeting + GURL(), // referrer_main_frame_url + true, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); VerifyReferrerChainEntry(initial_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address GURL(), // referrer_url - GURL(), // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(2)); } @@ -1070,18 +1152,22 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); ASSERT_EQ(2, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type "", // ip_address initial_url, // referrer_url - initial_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); VerifyReferrerChainEntry(initial_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address GURL(), // referrer_url - GURL(), // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); } @@ -1154,32 +1240,40 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); ASSERT_EQ(4, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type test_server_ip, // ip_address iframe_url, // referrer_url multi_frame_test_url, // referrer_main_frame_url false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); VerifyReferrerChainEntry(iframe_url, // url + multi_frame_test_url, // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address GURL(), // referrer_url multi_frame_test_url, // referrer_main_frame_url false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); - VerifyReferrerChainEntry(multi_frame_test_url, // url + VerifyReferrerChainEntry(multi_frame_test_url, // url + GURL(), // main_frame_url ReferrerChainEntry::CLIENT_REDIRECT, // type test_server_ip, // ip_address - initial_url, // referrer_url - initial_url, // referrer_main_frame_url - false, // is_retargeting + initial_url, // referrer_url + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(2)); - VerifyReferrerChainEntry(initial_url, // url + VerifyReferrerChainEntry(initial_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_REFERRER, // type test_server_ip, // ip_address - GURL(), // referrer_url - GURL(), // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_url + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(3)); } @@ -1270,39 +1364,49 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); EXPECT_EQ(5, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type test_server_ip, // ip_address blank_url, // referrer_url - blank_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); - VerifyReferrerChainEntry(blank_url, // url + VerifyReferrerChainEntry(blank_url, // url + GURL(), // main_frame_url ReferrerChainEntry::CLIENT_REDIRECT, // type "", // ip_address iframe_retargeting_url, // referrer_url multi_frame_test_url, // referrer_main_frame_url true, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); VerifyReferrerChainEntry(iframe_retargeting_url, // url + multi_frame_test_url, // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address GURL(), // referrer_url multi_frame_test_url, // referrer_main_frame_url false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(2)); - VerifyReferrerChainEntry(multi_frame_test_url, // url + VerifyReferrerChainEntry(multi_frame_test_url, // url + GURL(), // main_frame_url ReferrerChainEntry::CLIENT_REDIRECT, // type test_server_ip, // ip_address - initial_url, // referrer_url - initial_url, // referrer_main_frame_url - false, // is_retargeting + initial_url, // referrer_url + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(3)); - VerifyReferrerChainEntry(initial_url, // url + VerifyReferrerChainEntry(initial_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_REFERRER, // type test_server_ip, // ip_address - GURL(), // referrer_url - GURL(), // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_url + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(4)); } @@ -1361,33 +1465,41 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); EXPECT_EQ(4, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type test_server_ip, // ip_address landing_url, // referrer_url - landing_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); VerifyReferrerChainEntry(landing_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address redirect_url, // referrer_url - redirect_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); - VerifyReferrerChainEntry(redirect_url, // url + VerifyReferrerChainEntry(redirect_url, // url + GURL(), // main_frame_url ReferrerChainEntry::CLIENT_REDIRECT, // type test_server_ip, // ip_address initial_url, // referrer_url - initial_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(2)); VerifyReferrerChainEntry( initial_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_REFERRER, // type test_server_ip, // ip_address GURL(), // referrer_url is empty since this beyonds 2 clicks. GURL(), // referrer_main_frame_url is empty for the same reason. false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(3)); } @@ -1461,26 +1573,32 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); EXPECT_EQ(3, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type test_server_ip, // ip_address landing_url, // referrer_url - landing_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); VerifyReferrerChainEntry(landing_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address landing_referrer_url, // referrer_url - landing_referrer_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); VerifyReferrerChainEntry( landing_referrer_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_REFERRER, // type test_server_ip, // ip_address GURL(), // referrer_url is empty since this beyonds 2 clicks. GURL(), // referrer_main_frame_url is empty for the same reason. false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(2)); // page_before_landing_referrer_url is not in referrer chain. } @@ -1535,26 +1653,32 @@ &referrer_chain); EXPECT_EQ(3, referrer_chain.size()); VerifyReferrerChainEntry(landing_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address redirect_url, // referrer_url - redirect_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); - VerifyReferrerChainEntry(redirect_url, // url + VerifyReferrerChainEntry(redirect_url, // url + GURL(), // main_frame_url ReferrerChainEntry::CLIENT_REDIRECT, // type test_server_ip, // ip_address initial_url, // referrer_url - initial_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); VerifyReferrerChainEntry( initial_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_REFERRER, // type test_server_ip, // ip_address GURL(), // referrer_url is empty since this beyonds 2 clicks. GURL(), // referrer_main_frame_url is empty for the same reason. false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(2)); } @@ -1606,26 +1730,32 @@ browser()->tab_strip_model()->GetActiveWebContents(), &referrer_chain); EXPECT_EQ(3, referrer_chain.size()); - VerifyReferrerChainEntry(hosting_url, // url + VerifyReferrerChainEntry(hosting_url, // url + GURL(), // main_frame_url ReferrerChainEntry::CLIENT_REDIRECT, // type - test_server_ip, // ip_address - redirect_url, // referrer_url - redirect_url, // referrer_main_frame_url - false, // is_retargeting + test_server_ip, // ip_address + redirect_url, // referrer_url + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(0)); - VerifyReferrerChainEntry(redirect_url, // url + VerifyReferrerChainEntry(redirect_url, // url + GURL(), // main_frame_url ReferrerChainEntry::CLIENT_REDIRECT, // type test_server_ip, // ip_address landing_url, // referrer_url - landing_url, // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); VerifyReferrerChainEntry(landing_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address GURL(), // no more referrer before landing_url GURL(), - false, // is_retargeting + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(2)); } @@ -1663,11 +1793,64 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); ASSERT_EQ(1, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type test_server_ip, // ip_address GURL(), // referrer_url GURL(), // referrer_main_frame_url false, // is_retargeting + {request_url, download_url}, // server redirects + referrer_chain.Get(0)); +} + +// 2 consecutive server-side redirects. +IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, TwoServerRedirects) { + GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL); + GURL destination_url = embedded_test_server()->GetURL(kDownloadItemURL); + GURL redirect_url = embedded_test_server()->GetURL("/server-redirect?" + + destination_url.spec()); + GURL request_url = + embedded_test_server()->GetURL("/server-redirect?" + redirect_url.spec()); + ui_test_utils::NavigateToURL(browser(), request_url); + std::string test_server_ip(embedded_test_server()->host_port_pair().host()); + auto nav_map = navigation_map(); + ASSERT_TRUE(nav_map); + ASSERT_EQ(2U, nav_map->size()); + ASSERT_EQ(1U, nav_map->at(destination_url).size()); + ASSERT_EQ(1U, nav_map->at(initial_url).size()); + VerifyNavigationEvent(GURL(), // source_url + GURL(), // source_main_frame_url + initial_url, // original_request_url + initial_url, // destination_url + true, // is_user_initiated, + true, // has_committed + false, // has_server_redirect + nav_map->at(initial_url).at(0)); + VerifyNavigationEvent(GURL(), // source_url + GURL(), // source_main_frame_url + request_url, // original_request_url + destination_url, // destination_url + true, // is_user_initiated, + false, // has_committed + true, // has_server_redirect + nav_map->at(destination_url).at(0)); + const auto redirect_vector = + nav_map->at(destination_url).at(0).server_redirect_urls; + ASSERT_EQ(2U, redirect_vector.size()); + EXPECT_EQ(redirect_url, redirect_vector.at(0)); + EXPECT_EQ(destination_url, redirect_vector.at(1)); + + ReferrerChain referrer_chain; + IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); + ASSERT_EQ(1, referrer_chain.size()); + VerifyReferrerChainEntry(destination_url, // url + GURL(), // main_frame_url + ReferrerChainEntry::DOWNLOAD_URL, // type + test_server_ip, // ip_address + GURL(), // referrer_url + GURL(), // referrer_main_frame_url + false, // is_retargeting + {request_url, redirect_url, destination_url}, referrer_chain.Get(0)); } @@ -1715,18 +1898,22 @@ IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); ASSERT_EQ(2, referrer_chain.size()); VerifyReferrerChainEntry(download_url, // url + GURL(), // main_frame_url ReferrerChainEntry::DOWNLOAD_URL, // type test_server_ip, // ip_address initial_url, // referrer_url - initial_url, // referrer_main_frame_url - true, // is_retargeting + GURL(), // referrer_main_frame_url + true, // is_retargeting + {request_url, download_url}, // server redirects referrer_chain.Get(0)); VerifyReferrerChainEntry(initial_url, // url + GURL(), // main_frame_url ReferrerChainEntry::LANDING_PAGE, // type test_server_ip, // ip_address GURL(), // referrer_url - GURL(), // referrer_main_frame_url - false, // is_retargeting + GURL(), // referrer_main_frame_url + false, // is_retargeting + std::vector<GURL>(), // server redirects referrer_chain.Get(1)); }
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc index e3fd42f..a003bac7 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc
@@ -175,7 +175,7 @@ // host_to_ip_map already contains this key. // If this IP is already in the vector, we update its timestamp. for (auto& vector_entry : insert_result.first->second) { - if (vector_entry.ip == host) { + if (vector_entry.ip == ip) { vector_entry.timestamp = base::Time::Now(); return; } @@ -217,7 +217,7 @@ return NAVIGATION_EVENT_NOT_FOUND; } AttributionResult result = SUCCESS; - AddToReferrerChain(out_referrer_chain, nav_event, + AddToReferrerChain(out_referrer_chain, nav_event, GURL(), ReferrerChainEntry::DOWNLOAD_URL); int user_gesture_count = 0; GetRemainingReferrerChain( @@ -232,6 +232,7 @@ SafeBrowsingNavigationObserverManager::AttributionResult SafeBrowsingNavigationObserverManager::IdentifyReferrerChainForPPAPIDownload( const GURL& initiating_frame_url, + const GURL& initiating_main_frame_url, int tab_id, bool has_user_gesture, int user_gesture_count_limit, @@ -253,15 +254,13 @@ // page of the PPAPI download. if (has_user_gesture) { user_gesture_count = 1; - AddToReferrerChain(out_referrer_chain, nav_event, - GetURLTypeAndAdjustAttributionResult( - user_gesture_count == user_gesture_count_limit, - &result)); + AddToReferrerChain( + out_referrer_chain, nav_event, initiating_main_frame_url, + GetURLTypeAndAdjustAttributionResult( + user_gesture_count == user_gesture_count_limit, &result)); } else { - AddToReferrerChain(out_referrer_chain, nav_event, - nav_event->has_server_redirect - ? ReferrerChainEntry::SERVER_REDIRECT - : ReferrerChainEntry::CLIENT_REDIRECT); + AddToReferrerChain(out_referrer_chain, nav_event, initiating_main_frame_url, + ReferrerChainEntry::CLIENT_REDIRECT); } GetRemainingReferrerChain( @@ -314,7 +313,6 @@ SafeBrowsingNavigationObserverManager::ClearEmptyRef( source_contents->GetLastCommittedURL()); nav_event.original_request_url = target_url; - nav_event.destination_url = target_url; nav_event.target_tab_id = SessionTabHelper::IdForTab(target_contents); nav_event.frame_id = rfh ? rfh->GetFrameTreeNodeId() : -1; auto it = user_gesture_map_.find(source_contents); @@ -335,7 +333,9 @@ void SafeBrowsingNavigationObserverManager::CleanUpNavigationEvents() { // Remove any stale NavigationEnvent, if it is older than // kNavigationFootprintTTLInSecond. + std::size_t remove_count = 0; for (auto it = navigation_map_.begin(); it != navigation_map_.end();) { + std::size_t size_before_removal = it->second.size(); it->second.erase(std::remove_if(it->second.begin(), it->second.end(), [](const NavigationEvent& nav_event) { return IsEventExpired( @@ -343,11 +343,16 @@ kNavigationFootprintTTLInSecond); }), it->second.end()); - if (it->second.size() == 0) + std::size_t size_after_removal = it->second.size(); + remove_count += (size_before_removal - size_after_removal); + if (size_after_removal == 0) it = navigation_map_.erase(it); else ++it; } + UMA_HISTOGRAM_COUNTS_10000( + "SafeBrowsing.NavigationObserver.NavigationEventCleanUpCount", + remove_count); } void SafeBrowsingNavigationObserverManager::CleanUpUserGestures() { @@ -360,7 +365,9 @@ } void SafeBrowsingNavigationObserverManager::CleanUpIpAddresses() { + std::size_t remove_count = 0; for (auto it = host_to_ip_map_.begin(); it != host_to_ip_map_.end();) { + std::size_t size_before_removal = it->second.size(); it->second.erase(std::remove_if(it->second.begin(), it->second.end(), [](const ResolvedIPAddress& resolved_ip) { return IsEventExpired( @@ -368,11 +375,15 @@ kNavigationFootprintTTLInSecond); }), it->second.end()); - if (it->second.size() == 0) + std::size_t size_after_removal = it->second.size(); + remove_count += (size_before_removal - size_after_removal); + if (size_after_removal == 0) it = host_to_ip_map_.erase(it); else ++it; } + UMA_HISTOGRAM_COUNTS_10000( + "SafeBrowsing.NavigationObserver.IPAddressCleanUpCount", remove_count); } bool SafeBrowsingNavigationObserverManager::IsCleanUpScheduled() const { @@ -407,7 +418,7 @@ // the vector in reverse order to get the latest match. for (auto rit = it->second.rbegin(); rit != it->second.rend(); ++rit) { // If tab id is not valid, we only compare url, otherwise we compare both. - if (rit->destination_url == search_url && + if (rit->GetDestinationUrl() == search_url && (target_tab_id == -1 || rit->target_tab_id == target_tab_id)) { // If both source_url and source_main_frame_url are empty, and this // navigation is not triggered by user, a retargeting navigation probably @@ -417,7 +428,7 @@ !rit->is_user_initiated) { // If there is a server redirection immediately after retargeting, we // need to adjust our search url to the original request. - if (rit->has_server_redirect){ + if (!rit->server_redirect_urls.empty()) { NavigationEvent* retargeting_nav_event = FindNavigationEvent(rit->original_request_url, GURL(), @@ -425,8 +436,8 @@ if (!retargeting_nav_event) return nullptr; // Adjust retargeting navigation event's attributes. - retargeting_nav_event->has_server_redirect = true; - retargeting_nav_event->destination_url = search_url; + retargeting_nav_event->server_redirect_urls.push_back( + std::move(search_url)); return retargeting_nav_event; } else { continue; @@ -442,28 +453,49 @@ void SafeBrowsingNavigationObserverManager::AddToReferrerChain( ReferrerChain* referrer_chain, NavigationEvent* nav_event, + const GURL& destination_main_frame_url, ReferrerChainEntry::URLType type) { - ReferrerChainEntry referrer_chain_entry; - referrer_chain_entry.set_url(nav_event->destination_url.spec()); - referrer_chain_entry.set_type(type); - auto ip_it = host_to_ip_map_.find(nav_event->destination_url.host()); + std::unique_ptr<ReferrerChainEntry> referrer_chain_entry = + base::MakeUnique<ReferrerChainEntry>(); + const GURL destination_url = nav_event->GetDestinationUrl(); + referrer_chain_entry->set_url(destination_url.spec()); + if (destination_main_frame_url.is_valid() && + destination_url != destination_main_frame_url) + referrer_chain_entry->set_main_frame_url(destination_main_frame_url.spec()); + referrer_chain_entry->set_type(type); + auto ip_it = host_to_ip_map_.find(destination_url.host()); if (ip_it != host_to_ip_map_.end()) { for (ResolvedIPAddress entry : ip_it->second) { - referrer_chain_entry.add_ip_addresses(entry.ip); + referrer_chain_entry->add_ip_addresses(entry.ip); } } // Since we only track navigation to landing referrer, we will not log the // referrer of the landing referrer page. if (type != ReferrerChainEntry::LANDING_REFERRER) { - referrer_chain_entry.set_referrer_url(nav_event->source_url.spec()); - referrer_chain_entry.set_referrer_main_frame_url( - nav_event->source_main_frame_url.spec()); + referrer_chain_entry->set_referrer_url(nav_event->source_url.spec()); + // Only set |referrer_main_frame_url| if it is diff from |referrer_url|. + if (nav_event->source_main_frame_url.is_valid() && + nav_event->source_url != nav_event->source_main_frame_url) { + referrer_chain_entry->set_referrer_main_frame_url( + nav_event->source_main_frame_url.spec()); + } } - referrer_chain_entry.set_is_retargeting(nav_event->source_tab_id != - nav_event->target_tab_id); - referrer_chain_entry.set_navigation_time_msec( + referrer_chain_entry->set_is_retargeting(nav_event->source_tab_id != + nav_event->target_tab_id); + referrer_chain_entry->set_navigation_time_msec( nav_event->last_updated.ToJavaTime()); - referrer_chain->Add()->Swap(&referrer_chain_entry); + if (!nav_event->server_redirect_urls.empty()) { + // The first entry in |server_redirect_chain| should be the original request + // url. + ReferrerChainEntry::ServerRedirect* server_redirect = + referrer_chain_entry->add_server_redirect_chain(); + server_redirect->set_url(nav_event->original_request_url.spec()); + for (const GURL& redirect : nav_event->server_redirect_urls) { + server_redirect = referrer_chain_entry->add_server_redirect_chain(); + server_redirect->set_url(redirect.spec()); + } + } + referrer_chain->Add()->Swap(referrer_chain_entry.get()); } void SafeBrowsingNavigationObserverManager::GetRemainingReferrerChain( @@ -472,7 +504,7 @@ int user_gesture_count_limit, ReferrerChain* out_referrer_chain, SafeBrowsingNavigationObserverManager::AttributionResult* out_result) { - + GURL last_main_frame_url_traced(last_nav_event_traced->source_main_frame_url); while (current_user_gesture_count < user_gesture_count_limit) { // Back trace to the next nav_event that was initiated by the user. while (!last_nav_event_traced->is_user_initiated) { @@ -483,9 +515,9 @@ if (!last_nav_event_traced) return; AddToReferrerChain(out_referrer_chain, last_nav_event_traced, - last_nav_event_traced->has_server_redirect - ? ReferrerChainEntry::SERVER_REDIRECT - : ReferrerChainEntry::CLIENT_REDIRECT); + last_main_frame_url_traced, + ReferrerChainEntry::CLIENT_REDIRECT); + last_main_frame_url_traced = last_nav_event_traced->source_main_frame_url; } current_user_gesture_count++; @@ -508,11 +540,12 @@ if (!last_nav_event_traced) return; - AddToReferrerChain(out_referrer_chain, last_nav_event_traced, - GetURLTypeAndAdjustAttributionResult( - current_user_gesture_count == - user_gesture_count_limit, - out_result)); + AddToReferrerChain( + out_referrer_chain, last_nav_event_traced, last_main_frame_url_traced, + GetURLTypeAndAdjustAttributionResult( + current_user_gesture_count == user_gesture_count_limit, + out_result)); + last_main_frame_url_traced = last_nav_event_traced->source_main_frame_url; } }
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h index 1321c43..f8d2910 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h
@@ -118,6 +118,7 @@ // to |out_referrer_chain|. AttributionResult IdentifyReferrerChainForPPAPIDownload( const GURL& initiating_frame_url, + const GURL& initiating_main_frame_url, int tab_id, bool has_user_gesture, int user_gesture_count_limit, @@ -198,6 +199,7 @@ void AddToReferrerChain(ReferrerChain* referrer_chain, NavigationEvent* nav_event, + const GURL& destination_main_frame_url, ReferrerChainEntry::URLType type); // Helper function to get the remaining referrer chain when we've already
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc index f38dcf8e..87ad2a3a 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc
@@ -2,15 +2,25 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/test/histogram_tester.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h" #include "chrome/browser/sessions/session_tab_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/browser_with_test_window_test.h" #include "content/public/test/test_renderer_host.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/window_open_disposition.h" +namespace { + +const char kNavigationEventCleanUpHistogramName[] = + "SafeBrowsing.NavigationObserver.NavigationEventCleanUpCount"; +const char kIPAddressCleanUpHistogramName[] = + "SafeBrowsing.NavigationObserver.IPAddressCleanUpCount"; +} + namespace safe_browsing { class SBNavigationObserverTest : public BrowserWithTestWindowTest { @@ -43,13 +53,13 @@ actual_nav_event.source_main_frame_url); EXPECT_EQ(expected_original_request_url, actual_nav_event.original_request_url); - EXPECT_EQ(expected_destination_url, actual_nav_event.destination_url); + EXPECT_EQ(expected_destination_url, actual_nav_event.GetDestinationUrl()); EXPECT_EQ(expected_source_tab, actual_nav_event.source_tab_id); EXPECT_EQ(expected_target_tab, actual_nav_event.target_tab_id); EXPECT_EQ(expected_is_user_initiated, actual_nav_event.is_user_initiated); EXPECT_EQ(expected_has_committed, actual_nav_event.has_committed); EXPECT_EQ(expected_has_server_redirect, - actual_nav_event.has_server_redirect); + !actual_nav_event.server_redirect_urls.empty()); } SafeBrowsingNavigationObserverManager::NavigationMap* navigation_map() { @@ -64,10 +74,14 @@ return &navigation_observer_manager_->host_to_ip_map_; } + void RecordHostToIpMapping(const std::string& host, const std::string& ip) { + navigation_observer_manager_->RecordHostToIpMapping(host, ip); + } + NavigationEvent CreateNavigationEvent(const GURL& destination_url, const base::Time& timestamp) { NavigationEvent nav_event; - nav_event.destination_url = destination_url; + nav_event.original_request_url = destination_url; nav_event.last_updated = timestamp; return nav_event; } @@ -103,8 +117,8 @@ CommitPendingLoad(controller); int tab_id = SessionTabHelper::IdForTab(controller->GetWebContents()); auto nav_map = navigation_map(); - ASSERT_EQ(std::size_t(1), nav_map->size()); - ASSERT_EQ(std::size_t(1), nav_map->at(GURL("http://foo/1")).size()); + ASSERT_EQ(1U, nav_map->size()); + ASSERT_EQ(1U, nav_map->at(GURL("http://foo/1")).size()); VerifyNavigationEvent(GURL(), // source_url GURL(), // source_main_frame_url GURL("http://foo/1"), // original_request_url @@ -128,8 +142,8 @@ int tab_id = SessionTabHelper::IdForTab( browser()->tab_strip_model()->GetWebContentsAt(0)); auto nav_map = navigation_map(); - ASSERT_EQ(std::size_t(1), nav_map->size()); - ASSERT_EQ(std::size_t(1), nav_map->at(redirect).size()); + ASSERT_EQ(1U, nav_map->size()); + ASSERT_EQ(1U, nav_map->at(redirect).size()); VerifyNavigationEvent(GURL("http://foo/0"), // source_url GURL("http://foo/0"), // source_main_frame_url GURL("http://foo/3"), // original_request_url @@ -169,17 +183,22 @@ CreateNavigationEvent(url_0, one_hour_ago)); navigation_map()->at(url_1).push_back( CreateNavigationEvent(url_0, one_hour_ago)); - ASSERT_EQ(std::size_t(2), navigation_map()->size()); - ASSERT_EQ(std::size_t(4), navigation_map()->at(url_0).size()); - ASSERT_EQ(std::size_t(2), navigation_map()->at(url_1).size()); + ASSERT_EQ(2U, navigation_map()->size()); + ASSERT_EQ(4U, navigation_map()->at(url_0).size()); + ASSERT_EQ(2U, navigation_map()->at(url_1).size()); + + base::HistogramTester histograms; + histograms.ExpectTotalCount(kNavigationEventCleanUpHistogramName, 0); // Cleans up navigation events. CleanUpNavigationEvents(); // Verifies all stale and invalid navigation events are removed. - ASSERT_EQ(std::size_t(1), navigation_map()->size()); + ASSERT_EQ(1U, navigation_map()->size()); EXPECT_EQ(navigation_map()->end(), navigation_map()->find(url_1)); - EXPECT_EQ(std::size_t(2), navigation_map()->at(url_0).size()); + EXPECT_EQ(2U, navigation_map()->at(url_0).size()); + EXPECT_THAT(histograms.GetAllSamples(kNavigationEventCleanUpHistogramName), + testing::ElementsAre(base::Bucket(4, 1))); } TEST_F(SBNavigationObserverTest, TestCleanUpStaleUserGestures) { @@ -201,13 +220,13 @@ user_gesture_map()->insert(std::make_pair(content0, now)); user_gesture_map()->insert(std::make_pair(content1, one_minute_ago)); user_gesture_map()->insert(std::make_pair(content2, in_an_hour)); - ASSERT_EQ(std::size_t(3), user_gesture_map()->size()); + ASSERT_EQ(3U, user_gesture_map()->size()); // Cleans up user_gesture_map() CleanUpUserGestures(); // Verifies all stale and invalid user gestures are removed. - ASSERT_EQ(std::size_t(1), user_gesture_map()->size()); + ASSERT_EQ(1U, user_gesture_map()->size()); EXPECT_NE(user_gesture_map()->end(), user_gesture_map()->find(content0)); EXPECT_EQ(now, user_gesture_map()->at(content0)); } @@ -231,16 +250,57 @@ std::make_pair(host_1, std::vector<ResolvedIPAddress>())); host_to_ip_map()->at(host_1).push_back( ResolvedIPAddress(in_an_hour, "3.3.3.3")); - ASSERT_EQ(std::size_t(2), host_to_ip_map()->size()); + ASSERT_EQ(2U, host_to_ip_map()->size()); + + base::HistogramTester histograms; + histograms.ExpectTotalCount(kIPAddressCleanUpHistogramName, 0); // Cleans up host_to_ip_map() CleanUpIpAddresses(); // Verifies all stale and invalid IP addresses are removed. - ASSERT_EQ(std::size_t(1), host_to_ip_map()->size()); + ASSERT_EQ(1U, host_to_ip_map()->size()); EXPECT_EQ(host_to_ip_map()->end(), host_to_ip_map()->find(host_1)); - ASSERT_EQ(std::size_t(1), host_to_ip_map()->at(host_0).size()); + ASSERT_EQ(1U, host_to_ip_map()->at(host_0).size()); EXPECT_EQ(now, host_to_ip_map()->at(host_0).front().timestamp); + EXPECT_THAT(histograms.GetAllSamples(kIPAddressCleanUpHistogramName), + testing::ElementsAre(base::Bucket(2, 1))); +} + +TEST_F(SBNavigationObserverTest, TestRecordHostToIpMapping) { + // Setup host_to_ip_map(). + base::Time now = base::Time::Now(); // Fresh + base::Time one_hour_ago = + base::Time::FromDoubleT(now.ToDoubleT() - 60.0 * 60.0); // Stale + std::string host_0 = GURL("http://foo/0").host(); + host_to_ip_map()->insert( + std::make_pair(host_0, std::vector<ResolvedIPAddress>())); + host_to_ip_map()->at(host_0).push_back(ResolvedIPAddress(now, "1.1.1.1")); + host_to_ip_map()->at(host_0).push_back( + ResolvedIPAddress(one_hour_ago, "2.2.2.2")); + + // Record a host-IP pair, where host is already in the map, and IP has + // never been seen before. + RecordHostToIpMapping(host_0, "3.3.3.3"); + ASSERT_EQ(1U, host_to_ip_map()->size()); + EXPECT_EQ(3U, host_to_ip_map()->at(host_0).size()); + EXPECT_EQ("3.3.3.3", host_to_ip_map()->at(host_0).at(2).ip); + + // Record a host-IP pair which is already in the map. It should simply update + // its timestamp. + ASSERT_EQ(now, host_to_ip_map()->at(host_0).at(0).timestamp); + RecordHostToIpMapping(host_0, "1.1.1.1"); + ASSERT_EQ(1U, host_to_ip_map()->size()); + EXPECT_EQ(3U, host_to_ip_map()->at(host_0).size()); + EXPECT_LT(now, host_to_ip_map()->at(host_0).at(2).timestamp); + + // Record a host-ip pair, neither of which has been seen before. + std::string host_1 = GURL("http://bar/1").host(); + RecordHostToIpMapping(host_1, "9.9.9.9"); + ASSERT_EQ(2U, host_to_ip_map()->size()); + EXPECT_EQ(3U, host_to_ip_map()->at(host_0).size()); + EXPECT_EQ(1U, host_to_ip_map()->at(host_1).size()); + EXPECT_EQ("9.9.9.9", host_to_ip_map()->at(host_1).at(0).ip); } } // namespace safe_browsing
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc index 1196f4f..09c30ee 100644 --- a/chrome/browser/sync/chrome_sync_client.cc +++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/sync/chrome_sync_client.h" -#include <memory> #include <utility> #include "base/bind.h"
diff --git a/chrome/browser/sync/chrome_sync_client_unittest.cc b/chrome/browser/sync/chrome_sync_client_unittest.cc index 5f9b34e1..eba8a49b 100644 --- a/chrome/browser/sync/chrome_sync_client_unittest.cc +++ b/chrome/browser/sync/chrome_sync_client_unittest.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/sync/chrome_sync_client.h" -#include <memory> #include <string> #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/sync/glue/extensions_activity_monitor.cc b/chrome/browser/sync/glue/extensions_activity_monitor.cc index bb48f56c..c537aa0 100644 --- a/chrome/browser/sync/glue/extensions_activity_monitor.cc +++ b/chrome/browser/sync/glue/extensions_activity_monitor.cc
@@ -6,7 +6,6 @@ #include "components/sync/base/extensions_activity.h" #include "content/public/browser/browser_thread.h" -#include "extensions/features/features.h" #if BUILDFLAG(ENABLE_EXTENSIONS) #include "chrome/browser/chrome_notification_types.h"
diff --git a/chrome/browser/sync/glue/synced_tab_delegate_android.h b/chrome/browser/sync/glue/synced_tab_delegate_android.h index 4ed64f1c..21d7fa4 100644 --- a/chrome/browser/sync/glue/synced_tab_delegate_android.h +++ b/chrome/browser/sync/glue/synced_tab_delegate_android.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_SYNC_GLUE_SYNCED_TAB_DELEGATE_ANDROID_H_ #define CHROME_BROWSER_SYNC_GLUE_SYNCED_TAB_DELEGATE_ANDROID_H_ +#include <memory> #include <string> #include <vector>
diff --git a/chrome/browser/sync/profile_sync_service_factory_unittest.cc b/chrome/browser/sync/profile_sync_service_factory_unittest.cc index cf641806..b831543 100644 --- a/chrome/browser/sync/profile_sync_service_factory_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_factory_unittest.cc
@@ -6,7 +6,6 @@ #include <stddef.h> -#include <memory> #include <vector> #include "base/command_line.h"
diff --git a/chrome/browser/sync/test/integration/migration_waiter.cc b/chrome/browser/sync/test/integration/migration_waiter.cc index 3e9163d..37db9b30 100644 --- a/chrome/browser/sync/test/integration/migration_waiter.cc +++ b/chrome/browser/sync/test/integration/migration_waiter.cc
@@ -4,8 +4,6 @@ #include "chrome/browser/sync/test/integration/migration_waiter.h" -#include <string> - #include "base/logging.h" #include "chrome/browser/sync/test/integration/migration_watcher.h"
diff --git a/chrome/browser/sync/test/integration/multi_client_status_change_checker.cc b/chrome/browser/sync/test/integration/multi_client_status_change_checker.cc index 1b8868a5..6d03381e 100644 --- a/chrome/browser/sync/test/integration/multi_client_status_change_checker.cc +++ b/chrome/browser/sync/test/integration/multi_client_status_change_checker.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/sync/test/integration/multi_client_status_change_checker.h" #include "base/logging.h" -#include "base/scoped_observer.h" #include "components/browser_sync/profile_sync_service.h" MultiClientStatusChangeChecker::MultiClientStatusChangeChecker(
diff --git a/chrome/browser/sync/test/integration/passwords_helper.cc b/chrome/browser/sync/test/integration/passwords_helper.cc index 84b6cfaf..c666e53d 100644 --- a/chrome/browser/sync/test/integration/passwords_helper.cc +++ b/chrome/browser/sync/test/integration/passwords_helper.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/sync/test/integration/passwords_helper.h" #include <sstream> -#include <string> #include <utility> #include "base/compiler_specific.h"
diff --git a/chrome/browser/sync/test/integration/sync_integration_test_util.cc b/chrome/browser/sync/test/integration/sync_integration_test_util.cc index 9ce060f..42ef3e24 100644 --- a/chrome/browser/sync/test/integration/sync_integration_test_util.cc +++ b/chrome/browser/sync/test/integration/sync_integration_test_util.cc
@@ -4,10 +4,7 @@ #include "chrome/browser/sync/test/integration/sync_integration_test_util.h" -#include <string> - #include "base/strings/stringprintf.h" -#include "chrome/browser/sync/test/integration/fake_server_match_status_checker.h" #include "components/browser_sync/profile_sync_service.h" ServerCountMatchStatusChecker::ServerCountMatchStatusChecker(
diff --git a/chrome/browser/ui/cocoa/view_id_util.mm b/chrome/browser/ui/cocoa/view_id_util.mm index 6dd19ada..f97c795388 100644 --- a/chrome/browser/ui/cocoa/view_id_util.mm +++ b/chrome/browser/ui/cocoa/view_id_util.mm
@@ -9,7 +9,6 @@ #include <map> #include <utility> -#include "base/lazy_instance.h" #include "base/logging.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" @@ -21,7 +20,10 @@ // rather than using a separated map. typedef std::map<NSView*, ViewID> ViewIDMap; -static base::LazyInstance<ViewIDMap> g_view_id_map = LAZY_INSTANCE_INITIALIZER; +ViewIDMap* GetViewIDMap() { + static auto view_id_map = new ViewIDMap(); + return view_id_map; +} // Returns the view's nearest descendant (including itself) with a specific // ViewID, or nil if no subview has that ViewID. @@ -46,12 +48,12 @@ DCHECK(viewID != VIEW_ID_NONE); // We handle VIEW_ID_TAB_0 to VIEW_ID_TAB_LAST in GetView() function directly. DCHECK(!((viewID >= VIEW_ID_TAB_0) && (viewID <= VIEW_ID_TAB_LAST))); - g_view_id_map.Get()[view] = viewID; + (*GetViewIDMap())[view] = viewID; } void UnsetID(NSView* view) { DCHECK(view); - g_view_id_map.Get().erase(view); + GetViewIDMap()->erase(view); } NSView* GetView(NSWindow* window, ViewID viewID) { @@ -81,7 +83,7 @@ @implementation NSView (ViewID) - (ViewID)viewID { - ViewIDMap* map = g_view_id_map.Pointer(); + const ViewIDMap* map = GetViewIDMap(); ViewIDMap::const_iterator iter = map->find(self); return iter != map->end() ? iter->second : VIEW_ID_NONE; }
diff --git a/chrome/browser/ui/sync/browser_synced_window_delegate.cc b/chrome/browser/ui/sync/browser_synced_window_delegate.cc index 57232ef..26f812a 100644 --- a/chrome/browser/ui/sync/browser_synced_window_delegate.cc +++ b/chrome/browser/ui/sync/browser_synced_window_delegate.cc
@@ -10,7 +10,6 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/sync/tab_contents_synced_tab_delegate.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "components/sessions/core/session_id.h" BrowserSyncedWindowDelegate::BrowserSyncedWindowDelegate(Browser* browser) : browser_(browser) {}
diff --git a/chrome/browser/ui/sync/one_click_signin_links_delegate.h b/chrome/browser/ui/sync/one_click_signin_links_delegate.h index 57c0d55..3355446 100644 --- a/chrome/browser/ui/sync/one_click_signin_links_delegate.h +++ b/chrome/browser/ui/sync/one_click_signin_links_delegate.h
@@ -17,6 +17,7 @@ protected: OneClickSigninLinksDelegate() {} + private: DISALLOW_COPY_AND_ASSIGN(OneClickSigninLinksDelegate); };
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_observer.cc b/chrome/browser/ui/sync/one_click_signin_sync_observer.cc index 1606d38..443830b 100644 --- a/chrome/browser/ui/sync/one_click_signin_sync_observer.cc +++ b/chrome/browser/ui/sync/one_click_signin_sync_observer.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/ui/sync/one_click_signin_sync_observer.h" +#include <string> + #include "base/bind.h" #include "base/location.h" #include "base/single_thread_task_runner.h"
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_observer_unittest.cc b/chrome/browser/ui/sync/one_click_signin_sync_observer_unittest.cc index 7fcba1d3..8d0bff8 100644 --- a/chrome/browser/ui/sync/one_click_signin_sync_observer_unittest.cc +++ b/chrome/browser/ui/sync/one_click_signin_sync_observer_unittest.cc
@@ -10,7 +10,6 @@ #include "base/bind.h" #include "base/callback.h" -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" @@ -47,7 +46,7 @@ // navigation start is a sufficient signal for the purposes of this test. // Listening for this call also has the advantage of being synchronous. MOCK_METHOD1(DidStartNavigation, void(content::NavigationHandle*)); - // TODO: remove this method when PlzNavigate is turned on by default. + // TODO(jam): remove this method when PlzNavigate is turned on by default. MOCK_METHOD2(DidStartNavigationToPendingEntry, void(const GURL&, content::ReloadType)); };
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc index 75b3376..1ad06fa 100644 --- a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc +++ b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
@@ -11,7 +11,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/policy/cloud/user_policy_signin_service.h" #include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_attributes_entry.h" #include "chrome/browser/profiles/profile_attributes_storage.h" #include "chrome/browser/profiles/profile_avatar_icon_util.h"
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter_unittest.cc b/chrome/browser/ui/sync/one_click_signin_sync_starter_unittest.cc index aa78d980..9c19239 100644 --- a/chrome/browser/ui/sync/one_click_signin_sync_starter_unittest.cc +++ b/chrome/browser/ui/sync/one_click_signin_sync_starter_unittest.cc
@@ -4,11 +4,8 @@ #include "chrome/browser/ui/sync/one_click_signin_sync_starter.h" -#include <memory> - #include "base/command_line.h" #include "base/compiler_specific.h" -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/chrome_signin_client_factory.h"
diff --git a/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc b/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc index 5c81cb0..d6dd307 100644 --- a/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc +++ b/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
@@ -5,10 +5,10 @@ #include "chrome/browser/ui/sync/profile_signin_confirmation_helper.h" #include <memory> +#include <string> #include "base/bind.h" #include "base/bind_helpers.h" -#include "base/callback.h" #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/macros.h"
diff --git a/chrome/browser/ui/sync/sync_promo_ui.h b/chrome/browser/ui/sync/sync_promo_ui.h index 1af94bc..1acb3a2 100644 --- a/chrome/browser/ui/sync/sync_promo_ui.h +++ b/chrome/browser/ui/sync/sync_promo_ui.h
@@ -13,7 +13,6 @@ // Returns true if the sync promo should be visible. // |profile| is the profile for which the promo would be displayed. static bool ShouldShowSyncPromo(Profile* profile); - }; #endif // CHROME_BROWSER_UI_SYNC_SYNC_PROMO_UI_H_
diff --git a/chrome/browser/ui/sync/tab_contents_synced_tab_delegate.h b/chrome/browser/ui/sync/tab_contents_synced_tab_delegate.h index c5c6416..38e8a2e 100644 --- a/chrome/browser/ui/sync/tab_contents_synced_tab_delegate.h +++ b/chrome/browser/ui/sync/tab_contents_synced_tab_delegate.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_UI_SYNC_TAB_CONTENTS_SYNCED_TAB_DELEGATE_H_ #define CHROME_BROWSER_UI_SYNC_TAB_CONTENTS_SYNCED_TAB_DELEGATE_H_ +#include <memory> #include <string> #include <vector>
diff --git a/chrome/browser/ui/views/infobars/infobar_container_view.cc b/chrome/browser/ui/views/infobars/infobar_container_view.cc index 82f94a0e..bbe5606 100644 --- a/chrome/browser/ui/views/infobars/infobar_container_view.cc +++ b/chrome/browser/ui/views/infobars/infobar_container_view.cc
@@ -11,7 +11,7 @@ #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/canvas.h" -#include "ui/gfx/skia_util.h" +#include "ui/gfx/skia_paint_util.h" #include "ui/views/view_targeter.h" namespace {
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc index b8483264..3ae347c 100644 --- a/chrome/browser/ui/webui/options/browser_options_handler.cc +++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -519,12 +519,24 @@ { "configurePinTooShort", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_TOO_SHORT} , { "configurePinTooLong", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_TOO_LONG} , { "configurePinWeakPin", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_WEAK_PIN }, + { "lockScreenAddFingerprint", + IDS_SETTINGS_PEOPLE_LOCK_SCREEN_ADD_FINGERPRINT_BUTTON}, + { "lockScreenCannotAddFingerprint", + IDS_SETTINGS_PEOPLE_LOCK_SCREEN_CANNOT_ADD_NEW_FINGERPRINT}, { "lockScreenChangePinButton", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_CHANGE_PIN_BUTTON}, + { "lockScreenFingerprintEnable", + IDS_SETTINGS_PEOPLE_LOCK_SCREEN_ENABLE_FINGERPRINT_CHECKBOX_LABEL}, + { "lockScreenFingerprintNewName", + IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NEW_FINGERPRINT_DEFAULT_NAME}, + { "lockScreenFingerprintWarning", + IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_LESS_SECURE}, { "lockScreenNone", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NONE }, { "lockScreenPasswordOnly", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PASSWORD_ONLY }, { "lockScreenPinOrPassword", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PIN_OR_PASSWORD }, + { "lockScreenRegisteredFingerprints", + IDS_SETTINGS_PEOPLE_LOCK_SCREEN_REGISTERED_FINGERPRINTS_LABEL}, { "lockScreenSetupPinButton", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_SETUP_PIN_BUTTON }, { "lockScreenTitle", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_TITLE }, @@ -770,6 +782,8 @@ values->SetBoolean("showQuickUnlockSettings", chromeos::IsPinUnlockEnabled(profile->GetPrefs())); + values->SetBoolean("fingerprintUnlockEnabled", + chromeos::IsFingerprintUnlockEnabled()); if (chromeos::IsPinUnlockEnabled(profile->GetPrefs())) { values->SetString( "enableScreenlock",
diff --git a/chrome/browser/ui/webui/options/options_ui.cc b/chrome/browser/ui/webui/options/options_ui.cc index bfd84cf..91aca4e 100644 --- a/chrome/browser/ui/webui/options/options_ui.cc +++ b/chrome/browser/ui/webui/options/options_ui.cc
@@ -139,6 +139,8 @@ constexpr char kLockScreenJSPath[] = "people_page/lock_screen.js"; constexpr char kSetupPinHTMLPath[] = "people_page/setup_pin_dialog.html"; constexpr char kSetupPinJSPath[] = "people_page/setup_pin_dialog.js"; +constexpr char kFingerprintListHTMLPath[] = "people_page/fingerprint_list.html"; +constexpr char kFingerprintListJSPath[] = "people_page/fingerprint_list.js"; constexpr char kSettingsRouteHTMLPath[] = "route.html"; constexpr char kSettingsRouteJSPath[] = "route.js"; constexpr char kSettingsSharedCSSHTMLPath[] = "settings_shared_css.html"; @@ -269,6 +271,8 @@ void OptionsUIHTMLSource::CreateDataSourceMap() { #if defined(OS_CHROMEOS) path_to_idr_map_[kIconsHTMLPath] = IDR_OPTIONS_ICONS_HTML; + + // These are part of the LockScreen UI. path_to_idr_map_[kPinKeyboardHTMLPath] = IDR_OPTIONS_PIN_KEYBOARD_HTML; path_to_idr_map_[kPinKeyboardJSPath] = IDR_OPTIONS_PIN_KEYBOARD_JS; path_to_idr_map_[kPasswordPromptDialogHTMLPath] = @@ -287,6 +291,10 @@ path_to_idr_map_[kLockScreenJSPath] = IDR_OPTIONS_LOCK_SCREEN_JS; path_to_idr_map_[kSetupPinHTMLPath] = IDR_OPTIONS_SETUP_PIN_DIALOG_HTML; path_to_idr_map_[kSetupPinJSPath] = IDR_OPTIONS_SETUP_PIN_DIALOG_JS; + path_to_idr_map_[kFingerprintListHTMLPath] = + IDR_OPTIONS_FINGERPRINT_LIST_HTML; + path_to_idr_map_[kFingerprintListJSPath] = IDR_OPTIONS_FINGERPRINT_LIST_JS; + path_to_idr_map_[kSettingsRouteHTMLPath] = IDR_OPTIONS_ROUTE_HTML; path_to_idr_map_[kSettingsRouteJSPath] = IDR_OPTIONS_ROUTE_JS; path_to_idr_map_[kSettingsSharedCSSHTMLPath] = IDR_SETTINGS_SHARED_CSS_HTML;
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 80fd859..8351265a 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
@@ -1096,12 +1096,24 @@ {"configurePinTooLong", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_TOO_LONG}, {"configurePinWeakPin", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_WEAK_PIN}, {"enableScreenlock", IDS_SETTINGS_PEOPLE_ENABLE_SCREENLOCK}, + {"lockScreenAddFingerprint", + IDS_SETTINGS_PEOPLE_LOCK_SCREEN_ADD_FINGERPRINT_BUTTON}, + {"lockScreenCannotAddFingerprint", + IDS_SETTINGS_PEOPLE_LOCK_SCREEN_CANNOT_ADD_NEW_FINGERPRINT}, {"lockScreenChangePinButton", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_CHANGE_PIN_BUTTON}, {"lockScreenNone", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NONE}, + {"lockScreenFingerprintEnable", + IDS_SETTINGS_PEOPLE_LOCK_SCREEN_ENABLE_FINGERPRINT_CHECKBOX_LABEL}, + {"lockScreenFingerprintNewName", + IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NEW_FINGERPRINT_DEFAULT_NAME}, + {"lockScreenFingerprintWarning", + IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_LESS_SECURE}, {"lockScreenPasswordOnly", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PASSWORD_ONLY}, {"lockScreenPinOrPassword", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PIN_OR_PASSWORD}, + {"lockScreenRegisteredFingerprints", + IDS_SETTINGS_PEOPLE_LOCK_SCREEN_REGISTERED_FINGERPRINTS_LABEL}, {"lockScreenSetupPinButton", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_SETUP_PIN_BUTTON}, {"lockScreenTitle", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_TITLE},
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc index 7a1f403..3a38cae 100644 --- a/chrome/browser/ui/webui/settings/md_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc
@@ -155,6 +155,8 @@ html_source->AddBoolean("stylusAllowed", ash::IsPaletteFeatureEnabled()); html_source->AddBoolean("pinUnlockEnabled", chromeos::IsPinUnlockEnabled(profile->GetPrefs())); + html_source->AddBoolean("fingerprintUnlockEnabled", + chromeos::IsFingerprintUnlockEnabled()); html_source->AddBoolean("androidAppsAllowed", arc::IsArcAllowedForProfile(profile) && !arc::IsArcOptInVerificationDisabled());
diff --git a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.cc b/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.cc index 0ac26da..f8314db 100644 --- a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.cc +++ b/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.cc
@@ -36,6 +36,10 @@ "doAction", base::Bind(&VrShellUIMessageHandler::HandleDoAction, base::Unretained(this))); web_ui()->RegisterMessageCallback( + "setContentCssSize", + base::Bind(&VrShellUIMessageHandler::HandleSetContentCssSize, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( "setUiCssSize", base::Bind(&VrShellUIMessageHandler::HandleSetUiCssSize, base::Unretained(this))); } @@ -71,14 +75,30 @@ } } +void VrShellUIMessageHandler::HandleSetContentCssSize( + const base::ListValue* args) { + if (!vr_shell_) + return; + SetSize(args, false); +} + void VrShellUIMessageHandler::HandleSetUiCssSize(const base::ListValue* args) { + if (!vr_shell_) + return; + SetSize(args, true); +} + +void VrShellUIMessageHandler::SetSize(const base::ListValue* args, + bool for_ui) { CHECK(args->GetSize() == 3); double width, height, dpr; CHECK(args->GetDouble(0, &width)); CHECK(args->GetDouble(1, &height)); CHECK(args->GetDouble(2, &dpr)); - if (vr_shell_) { + if (for_ui) { vr_shell_->SetUiCssSize(width, height, dpr); + } else { + vr_shell_->SetContentCssSize(width, height, dpr); } }
diff --git a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.h b/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.h index 667ee3d..be0825e 100644 --- a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.h +++ b/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.h
@@ -34,7 +34,9 @@ void HandleDomLoaded(const base::ListValue* args); void HandleUpdateScene(const base::ListValue* args); void HandleDoAction(const base::ListValue* args); + void HandleSetContentCssSize(const base::ListValue* args); void HandleSetUiCssSize(const base::ListValue* args); + void SetSize(const base::ListValue* args, bool for_ui); base::WeakPtr<vr_shell::VrShell> vr_shell_;
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 15a6efb..810c6db 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -247,10 +247,14 @@ const base::Feature kOptInImeMenu{"OptInImeMenu", base::FEATURE_ENABLED_BY_DEFAULT}; -// Enables or disables PIN quick unlock settings integration. +// Enables or disables PIN quick unlock. const base::Feature kQuickUnlockPin{"QuickUnlockPin", base::FEATURE_ENABLED_BY_DEFAULT}; +// Enables or disables fingerprint quick unlock. +const base::Feature kQuickUnlockFingerprint{"QuickUnlockFingerprint", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables or disables emoji, handwriting and voice input on opt-in IME menu. const base::Feature kEHVInputOnImeMenu{"EmojiHandwritingVoiceInput", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 340aa7a..38bd2606 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -146,6 +146,8 @@ extern const base::Feature kQuickUnlockPin; +extern const base::Feature kQuickUnlockFingerprint; + extern const base::Feature kEHVInputOnImeMenu; extern const base::Feature kCrosCompUpdates;
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 4c599779..e4cd9d0 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -256,14 +256,12 @@ extern const char kAuthAndroidNegotiateAccountType[]; extern const char kDisableAppLink[]; extern const char kDisableContextualSearch[]; -extern const char kDisableVrShell[]; extern const char kEnableAccessibilityTabSwitcher[]; extern const char kEnableAppLink[]; extern const char kEnableContextualSearch[]; extern const char kEnableContextualSearchContextualCardsBarIntegration[]; extern const char kEnableHostedMode[]; extern const char kEnableHungRendererInfoBar[]; -extern const char kEnableVrShell[]; extern const char kForceShowUpdateMenuBadge[]; extern const char kForceShowUpdateMenuItem[]; extern const char kForceShowUpdateMenuItemCustomSummary[];
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index cdb94ce..d670a3e 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -944,6 +944,10 @@ const char kPinUnlockMaximumLength[] = "pin_unlock_maximum_length"; // Boolean pref indicating whether users are allowed to set easy pins. const char kPinUnlockWeakPinsAllowed[] = "pin_unlock_weak_pins_allowed"; + +// Boolean pref indicating whether fingerprint unlock is enabled. +const char kEnableQuickUnlockFingerprint[] = + "settings.enable_quick_unlock_fingerprint"; #endif // defined(OS_CHROMEOS) // A boolean pref set to true if a Home button to open the Home pages should be
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 3a2daef..3cc7fde 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -318,6 +318,7 @@ extern const char kPinUnlockMinimumLength[]; extern const char kPinUnlockMaximumLength[]; extern const char kPinUnlockWeakPinsAllowed[]; +extern const char kEnableQuickUnlockFingerprint[]; #endif // defined(OS_CHROMEOS) extern const char kShowHomeButton[]; extern const char kSpeechRecognitionFilterProfanities[];
diff --git a/chrome/common/safe_browsing/csd.proto b/chrome/common/safe_browsing/csd.proto index cfdb94e..4089e56 100644 --- a/chrome/common/safe_browsing/csd.proto +++ b/chrome/common/safe_browsing/csd.proto
@@ -386,6 +386,9 @@ // order, i.e. download url comes first in this list, and landing referrer // comes last. repeated ReferrerChainEntry referrer_chain = 36; + + // Whether DownloadAttribution Finch experiment is enabled for this ping. + optional bool download_attribution_finch_enabled = 39; } message ReferrerChainEntry { @@ -394,14 +397,24 @@ LANDING_PAGE = 2; LANDING_REFERRER = 3; CLIENT_REDIRECT = 4; - SERVER_REDIRECT = 5; + DEPRECATED_SERVER_REDIRECT = 5; // Deprecated + } + + message ServerRedirect { + // [required] server redirect url + optional string url = 1; + + // Additional fields for future expansion. } // [required] The url of this Entry. optional string url = 1; + // Only set if it is different from |url|. + optional string main_frame_url = 9; + // Type of URLs, such as download url, download referrer, etc. - optional URLType type = 2; + optional URLType type = 2 [default = CLIENT_REDIRECT]; // IP addresses corresponding to this host. repeated string ip_addresses = 3; @@ -410,13 +423,19 @@ optional string referrer_url = 4; // Main frame URL of referrer. + // Only set if it is different from |referrer_url|. optional string referrer_main_frame_url = 5; // If this URL loads in a different tab/frame from previous one. optional bool is_retargeting = 6; optional double navigation_time_msec = 7; -} // End of URLChainEntry + + // Set only if server redirects happened in navigation. + // The first entry in |server_redirect_chain| should be the original request + // url, and the last entry should be the same as |url|. + repeated ServerRedirect server_redirect_chain = 8; +} // End of ReferrerChainEntry message ClientDownloadResponse { enum Verdict {
diff --git a/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc index 104f0559..a4334ea 100644 --- a/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc +++ b/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc
@@ -34,7 +34,9 @@ using base::Time; using base::TimeDelta; using sync_pb::AutofillSpecifics; +using sync_pb::EntityMetadata; using sync_pb::EntitySpecifics; +using sync_pb::ModelTypeState; using syncer::DataBatch; using syncer::EntityChange; using syncer::EntityChangeList; @@ -132,20 +134,18 @@ db_.AddTable(&table_); db_.Init(temp_dir_.GetPath().AppendASCII("SyncTestWebDatabase")); backend_.SetWebDatabase(&db_); - - sync_pb::ModelTypeState model_type_state; - model_type_state.set_initial_sync_done(true); - table_.UpdateModelTypeState(syncer::AUTOFILL, model_type_state); - - bridge_.reset(new AutocompleteSyncBridge( - &backend_, - base::Bind( - &AutocompleteSyncBridgeTest::CreateModelTypeChangeProcessor, - base::Unretained(this)))); + ResetBridge(); } } ~AutocompleteSyncBridgeTest() override {} + void ResetBridge() { + bridge_.reset(new AutocompleteSyncBridge( + &backend_, + base::Bind(&AutocompleteSyncBridgeTest::CreateModelTypeChangeProcessor, + base::Unretained(this)))); + } + void SaveSpecificsToTable( const std::vector<AutofillSpecifics>& specifics_list) { std::vector<AutofillEntry> new_entries; @@ -582,8 +582,23 @@ } TEST_F(AutocompleteSyncBridgeTest, LoadMetadataCalled) { - EXPECT_NE(processor()->metadata(), nullptr); + EXPECT_NE(nullptr, processor()->metadata()); + EXPECT_FALSE( + processor()->metadata()->GetModelTypeState().initial_sync_done()); + EXPECT_EQ(0u, processor()->metadata()->TakeAllMetadata().size()); + + ModelTypeState model_type_state; + model_type_state.set_initial_sync_done(true); + EXPECT_TRUE( + table()->UpdateModelTypeState(syncer::AUTOFILL, model_type_state)); + EXPECT_TRUE( + table()->UpdateSyncMetadata(syncer::AUTOFILL, "key", EntityMetadata())); + + ResetBridge(); + + EXPECT_NE(nullptr, processor()->metadata()); EXPECT_TRUE(processor()->metadata()->GetModelTypeState().initial_sync_done()); + EXPECT_EQ(1u, processor()->metadata()->TakeAllMetadata().size()); } TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataEmpty) {
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc index 503eb0f..cdcfde8 100644 --- a/components/autofill/core/browser/webdata/autofill_table.cc +++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -11,8 +11,7 @@ #include <limits> #include <map> #include <set> -#include <string> -#include <vector> +#include <utility> #include "base/command_line.h" #include "base/guid.h" @@ -36,7 +35,6 @@ #include "components/autofill/core/common/form_field_data.h" #include "components/os_crypt/os_crypt.h" #include "components/sync/base/model_type.h" -#include "components/sync/model/metadata_batch.h" #include "components/sync/protocol/entity_metadata.pb.h" #include "components/sync/protocol/model_type_state.pb.h" #include "components/webdata/common/web_database.h" @@ -1686,7 +1684,7 @@ syncer::EntityMetadataMap metadata_records; if (GetAllSyncEntityMetadata(model_type, &metadata_records)) { for (const auto& pair : metadata_records) { - // todo(pnoland): add batch transfer of metadata map + // TODO(pnoland): Add batch transfer of metadata map. metadata_batch->AddMetadata(pair.first, pair.second); } } else { @@ -1762,7 +1760,7 @@ "SELECT value FROM autofill_model_type_state WHERE id=1")); if (!s.Step()) { - return false; + return true; } std::string serialized_state = s.ColumnString(0); @@ -2527,4 +2525,4 @@ return transaction.Commit(); } -} // namespace autofill \ No newline at end of file +} // namespace autofill
diff --git a/components/autofill/core/browser/webdata/autofill_table.h b/components/autofill/core/browser/webdata/autofill_table.h index 2f5fff15..dc08b9b5 100644 --- a/components/autofill/core/browser/webdata/autofill_table.h +++ b/components/autofill/core/browser/webdata/autofill_table.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include <memory> +#include <string> #include <vector> #include "base/gtest_prod_util.h" @@ -23,11 +24,6 @@ class Time; } -namespace sync_pb { -class EntityMetadata; -class ModelTypeState; -} - namespace autofill { class AutofillChange;
diff --git a/components/autofill/core/browser/webdata/autofill_table_unittest.cc b/components/autofill/core/browser/webdata/autofill_table_unittest.cc index cd93d29..2d784bb1e 100644 --- a/components/autofill/core/browser/webdata/autofill_table_unittest.cc +++ b/components/autofill/core/browser/webdata/autofill_table_unittest.cc
@@ -2,14 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <stddef.h> +#include "components/autofill/core/browser/webdata/autofill_table.h" #include <map> #include <set> -#include <string> #include <tuple> #include <utility> -#include <vector> #include "base/command_line.h" #include "base/files/file_util.h" @@ -29,7 +27,6 @@ #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/webdata/autofill_change.h" #include "components/autofill/core/browser/webdata/autofill_entry.h" -#include "components/autofill/core/browser/webdata/autofill_table.h" #include "components/autofill/core/common/autofill_constants.h" #include "components/autofill/core/common/autofill_switches.h" #include "components/autofill/core/common/autofill_util.h" @@ -44,6 +41,10 @@ using base::ASCIIToUTF16; using base::Time; using base::TimeDelta; +using sync_pb::EntityMetadata; +using sync_pb::ModelTypeState; +using syncer::EntityMetadataMap; +using syncer::MetadataBatch; namespace autofill { @@ -2021,8 +2022,16 @@ } } -TEST_F(AutofillTableTest, GetAllSyncMetadata) { - sync_pb::EntityMetadata metadata; +TEST_F(AutofillTableTest, AutofillNoMetadata) { + MetadataBatch metadata_batch; + EXPECT_TRUE(table_->GetAllSyncMetadata(syncer::AUTOFILL, &metadata_batch)); + EXPECT_EQ(0u, metadata_batch.TakeAllMetadata().size()); + EXPECT_EQ(ModelTypeState().SerializeAsString(), + metadata_batch.GetModelTypeState().SerializeAsString()); +} + +TEST_F(AutofillTableTest, AutofillGetAllSyncMetadata) { + EntityMetadata metadata; std::string storage_key = "storage_key"; std::string storage_key2 = "storage_key2"; metadata.set_sequence_number(1); @@ -2030,7 +2039,7 @@ EXPECT_TRUE( table_->UpdateSyncMetadata(syncer::AUTOFILL, storage_key, metadata)); - sync_pb::ModelTypeState model_type_state; + ModelTypeState model_type_state; model_type_state.set_initial_sync_done(true); EXPECT_TRUE(table_->UpdateModelTypeState(syncer::AUTOFILL, model_type_state)); @@ -2039,12 +2048,12 @@ EXPECT_TRUE( table_->UpdateSyncMetadata(syncer::AUTOFILL, storage_key2, metadata)); - syncer::MetadataBatch metadata_batch; + MetadataBatch metadata_batch; EXPECT_TRUE(table_->GetAllSyncMetadata(syncer::AUTOFILL, &metadata_batch)); EXPECT_TRUE(metadata_batch.GetModelTypeState().initial_sync_done()); - syncer::EntityMetadataMap metadata_records = metadata_batch.TakeAllMetadata(); + EntityMetadataMap metadata_records = metadata_batch.TakeAllMetadata(); EXPECT_EQ(metadata_records.size(), 2u); EXPECT_EQ(metadata_records[storage_key].sequence_number(), 1); @@ -2058,11 +2067,11 @@ EXPECT_FALSE(metadata_batch.GetModelTypeState().initial_sync_done()); } -TEST_F(AutofillTableTest, WriteThenDeleteSyncMetadata) { - sync_pb::EntityMetadata metadata; - syncer::MetadataBatch metadata_batch; +TEST_F(AutofillTableTest, AutofillWriteThenDeleteSyncMetadata) { + EntityMetadata metadata; + MetadataBatch metadata_batch; std::string storage_key = "storage_key"; - sync_pb::ModelTypeState model_type_state; + ModelTypeState model_type_state; model_type_state.set_initial_sync_done(true); @@ -2077,32 +2086,35 @@ // It shouldn't be there any more. EXPECT_TRUE(table_->GetAllSyncMetadata(syncer::AUTOFILL, &metadata_batch)); - syncer::EntityMetadataMap metadata_records = metadata_batch.TakeAllMetadata(); + EntityMetadataMap metadata_records = metadata_batch.TakeAllMetadata(); EXPECT_EQ(metadata_records.size(), 0u); // Now delete the model type state. EXPECT_TRUE(table_->ClearModelTypeState(syncer::AUTOFILL)); - EXPECT_FALSE(table_->GetAllSyncMetadata(syncer::AUTOFILL, &metadata_batch)); + EXPECT_TRUE(table_->GetAllSyncMetadata(syncer::AUTOFILL, &metadata_batch)); + EXPECT_EQ(ModelTypeState().SerializeAsString(), + metadata_batch.GetModelTypeState().SerializeAsString()); } -TEST_F(AutofillTableTest, CorruptSyncMetadata) { - syncer::MetadataBatch metadata_batch; - sync_pb::ModelTypeState state; - std::string storage_key = "storage_key"; - +TEST_F(AutofillTableTest, AutofillCorruptSyncMetadata) { + MetadataBatch metadata_batch; sql::Statement s(db_->GetSQLConnection()->GetUniqueStatement( "INSERT OR REPLACE INTO autofill_sync_metadata " "(storage_key, value) VALUES(?, ?)")); - s.BindString(0, storage_key); + s.BindString(0, "storage_key"); s.BindString(1, "unparseable"); + EXPECT_TRUE(s.Run()); - sql::Statement s2(db_->GetSQLConnection()->GetUniqueStatement( + EXPECT_FALSE(table_->GetAllSyncMetadata(syncer::AUTOFILL, &metadata_batch)); +} + +TEST_F(AutofillTableTest, AutofillCorruptModelTypeState) { + MetadataBatch metadata_batch; + sql::Statement s(db_->GetSQLConnection()->GetUniqueStatement( "INSERT OR REPLACE INTO autofill_model_type_state " "(rowid, value) VALUES(1, ?)")); - s2.BindString(0, "unparseable"); - + s.BindString(0, "unparseable"); EXPECT_TRUE(s.Run()); - EXPECT_TRUE(s2.Run()); EXPECT_FALSE(table_->GetAllSyncMetadata(syncer::AUTOFILL, &metadata_batch)); }
diff --git a/components/browser_sync/PRESUBMIT.py b/components/browser_sync/PRESUBMIT.py index ae61c433..c9212e9 100644 --- a/components/browser_sync/PRESUBMIT.py +++ b/components/browser_sync/PRESUBMIT.py
@@ -12,11 +12,16 @@ BROWSER_SYNC_SOURCE_FILES = (r'^components[\\/]browser_sync[\\/].*\.(cc|h)$',) +# The wrapper around lint that is called below disables a set of filters if the +# passed filter evaluates to false. Pass a junk filter to avoid this behavior. +LINT_FILTERS = ['+fake/filter'] + def CheckChangeLintsClean(input_api, output_api): source_filter = lambda x: input_api.FilterSourceFile( x, white_list=BROWSER_SYNC_SOURCE_FILES, black_list=None) return input_api.canned_checks.CheckChangeLintsClean( - input_api, output_api, source_filter, lint_filters=[], verbose_level=1) + input_api, output_api, source_filter, lint_filters=LINT_FILTERS, + verbose_level=1) def CheckChanges(input_api, output_api): results = []
diff --git a/components/crash/core/common/objc_zombie.mm b/components/crash/core/common/objc_zombie.mm index 7246b9b..c984dba 100644 --- a/components/crash/core/common/objc_zombie.mm +++ b/components/crash/core/common/objc_zombie.mm
@@ -14,7 +14,6 @@ #include "base/debug/crash_logging.h" #include "base/debug/stack_trace.h" -#include "base/lazy_instance.h" #include "base/logging.h" #include "base/posix/eintr_wrapper.h" #include "base/strings/stringprintf.h" @@ -74,7 +73,10 @@ BOOL g_zombieAllObjects = NO; // Protects |g_zombieCount|, |g_zombieIndex|, and |g_zombies|. -base::LazyInstance<base::Lock>::Leaky g_lock = LAZY_INSTANCE_INITIALIZER; +base::Lock& GetLock() { + static auto lock = new base::Lock(); + return *lock; +} // How many zombies to keep before freeing, and the current head of // the circular buffer. @@ -140,7 +142,7 @@ // Don't involve the lock when creating zombies without a treadmill. if (g_zombieCount > 0) { - base::AutoLock pin(g_lock.Get()); + base::AutoLock pin(GetLock()); // Check the count again in a thread-safe manner. if (g_zombieCount > 0) { @@ -163,7 +165,7 @@ BOOL GetZombieRecord(id object, ZombieRecord* record) { // Holding the lock is reasonable because this should be fast, and // the process is going to crash presently anyhow. - base::AutoLock pin(g_lock.Get()); + base::AutoLock pin(GetLock()); for (size_t i = 0; i < g_zombieCount; ++i) { if (g_zombies[i].object == object) { *record = g_zombies[i]; @@ -346,7 +348,7 @@ ZombieRecord* oldZombies = g_zombies; { - base::AutoLock pin(g_lock.Get()); + base::AutoLock pin(GetLock()); // Save the old index in case zombies need to be transferred. size_t oldIndex = g_zombieIndex; @@ -417,7 +419,7 @@ ZombieRecord* oldZombies = g_zombies; { - base::AutoLock pin(g_lock.Get()); // In case any -dealloc are in progress. + base::AutoLock pin(GetLock()); // In case any -dealloc are in progress. g_zombieCount = 0; g_zombies = NULL; }
diff --git a/components/exo/buffer.cc b/components/exo/buffer.cc index 430e66c..aa53bedb 100644 --- a/components/exo/buffer.cc +++ b/components/exo/buffer.cc
@@ -524,6 +524,10 @@ return gpu_memory_buffer_->GetSize(); } +gfx::BufferFormat Buffer::GetFormat() const { + return gpu_memory_buffer_->GetFormat(); +} + std::unique_ptr<base::trace_event::TracedValue> Buffer::AsTracedValue() const { std::unique_ptr<base::trace_event::TracedValue> value( new base::trace_event::TracedValue());
diff --git a/components/exo/buffer.h b/components/exo/buffer.h index 7ca10624..38be8a99 100644 --- a/components/exo/buffer.h +++ b/components/exo/buffer.h
@@ -67,6 +67,9 @@ // Returns the size of the buffer. gfx::Size GetSize() const; + // Returns the format of the buffer. + gfx::BufferFormat GetFormat() const; + // Returns a trace value representing the state of the buffer. std::unique_ptr<base::trace_event::TracedValue> AsTracedValue() const;
diff --git a/components/exo/surface.cc b/components/exo/surface.cc index fc958c4..f97b7a4 100644 --- a/components/exo/surface.cc +++ b/components/exo/surface.cc
@@ -67,6 +67,22 @@ return FindListEntry(list, key) != list.end(); } +// Helper function that returns true if |format| may have an alpha channel. +// Note: False positives are allowed but false negatives are not. +bool FormatHasAlpha(gfx::BufferFormat format) { + switch (format) { + case gfx::BufferFormat::BGR_565: + case gfx::BufferFormat::RGBX_8888: + case gfx::BufferFormat::BGRX_8888: + case gfx::BufferFormat::YVU_420: + case gfx::BufferFormat::YUV_420_BIPLANAR: + case gfx::BufferFormat::UYVY_422: + return false; + default: + return true; + } +} + class CustomWindowDelegate : public aura::WindowDelegate { public: explicit CustomWindowDelegate(Surface* surface) : surface_(surface) {} @@ -417,10 +433,14 @@ has_pending_layer_changes_ = true; if (has_pending_contents_) { - if (pending_buffer_.buffer() && - (current_resource_.size != pending_buffer_.buffer()->GetSize())) { - has_pending_layer_changes_ = true; - } else if (!pending_buffer_.buffer() && !current_resource_.size.IsEmpty()) { + if (pending_buffer_.buffer()) { + if (current_resource_.size != pending_buffer_.buffer()->GetSize()) + has_pending_layer_changes_ = true; + // Whether layer fills bounds opaquely or not might have changed. + if (current_resource_has_alpha_ != + FormatHasAlpha(pending_buffer_.buffer()->GetFormat())) + has_pending_layer_changes_ = true; + } else if (!current_resource_.size.IsEmpty()) { has_pending_layer_changes_ = true; } } @@ -471,6 +491,7 @@ content_size_), surface_reference_factory_); window_->layer()->SetFillsBoundsOpaquely( + !current_resource_has_alpha_ || state_.blend_mode == SkBlendMode::kSrc || state_.opaque_region.contains( gfx::RectToSkIRect(gfx::Rect(content_size_)))); @@ -732,13 +753,17 @@ } void Surface::UpdateResource(bool client_usage) { - if (!current_buffer_.buffer() || - !current_buffer_.buffer()->ProduceTransferableResource( + if (current_buffer_.buffer() && + current_buffer_.buffer()->ProduceTransferableResource( compositor_frame_sink_holder_.get(), next_resource_id_++, state_.only_visible_on_secure_output, client_usage, ¤t_resource_)) { + current_resource_has_alpha_ = + FormatHasAlpha(current_buffer_.buffer()->GetFormat()); + } else { current_resource_.id = 0; current_resource_.size = gfx::Size(); + current_resource_has_alpha_ = false; } } @@ -802,7 +827,8 @@ render_pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>(); float vertex_opacity[4] = {1.0, 1.0, 1.0, 1.0}; gfx::Rect opaque_rect; - if (state_.blend_mode == SkBlendMode::kSrc || + if (!current_resource_has_alpha_ || + state_.blend_mode == SkBlendMode::kSrc || state_.opaque_region.contains(gfx::RectToSkIRect(quad_rect))) { opaque_rect = quad_rect; } else if (state_.opaque_region.isRect()) {
diff --git a/components/exo/surface.h b/components/exo/surface.h index e50733e..14d7da0 100644 --- a/components/exo/surface.h +++ b/components/exo/surface.h
@@ -361,6 +361,9 @@ // The last resource that was sent to a surface. cc::TransferableResource current_resource_; + // Whether the last resource that was sent to a surface has an alpha channel. + bool current_resource_has_alpha_ = false; + // This is true if a call to Commit() as been made but // CommitSurfaceHierarchy() has not yet been called. bool needs_commit_surface_hierarchy_ = false;
diff --git a/components/exo/surface_unittest.cc b/components/exo/surface_unittest.cc index f48ea71..1112715 100644 --- a/components/exo/surface_unittest.cc +++ b/components/exo/surface_unittest.cc
@@ -93,14 +93,71 @@ EXPECT_TRUE(frame_time.is_null()); } +const cc::CompositorFrame& GetFrameFromSurface(Surface* surface) { + cc::SurfaceId surface_id = surface->GetSurfaceId(); + cc::SurfaceManager* surface_manager = + aura::Env::GetInstance()->context_factory_private()->GetSurfaceManager(); + const cc::CompositorFrame& frame = + surface_manager->GetSurfaceForId(surface_id)->GetEligibleFrame(); + return frame; +} + TEST_F(SurfaceTest, SetOpaqueRegion) { + gfx::Size buffer_size(1, 1); + std::unique_ptr<Buffer> buffer( + new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); std::unique_ptr<Surface> surface(new Surface); - // Setting a non-empty opaque region should succeed. - surface->SetOpaqueRegion(SkRegion(SkIRect::MakeWH(256, 256))); + // Attaching a buffer with alpha channel. + surface->Attach(buffer.get()); - // Setting an empty opaque region should succeed. + // Setting an opaque region that contains the buffer size doesn't require + // draw with blending. + surface->SetOpaqueRegion(SkRegion(SkIRect::MakeWH(256, 256))); + surface->Commit(); + RunAllPendingInMessageLoop(); + + { + const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get()); + ASSERT_EQ(1u, frame.render_pass_list.size()); + ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size()); + EXPECT_FALSE(frame.render_pass_list.back() + ->quad_list.back() + ->ShouldDrawWithBlending()); + } + + // Setting an empty opaque region requires draw with blending. surface->SetOpaqueRegion(SkRegion(SkIRect::MakeEmpty())); + surface->Commit(); + RunAllPendingInMessageLoop(); + + { + const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get()); + ASSERT_EQ(1u, frame.render_pass_list.size()); + ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size()); + EXPECT_TRUE(frame.render_pass_list.back() + ->quad_list.back() + ->ShouldDrawWithBlending()); + } + + std::unique_ptr<Buffer> buffer_without_alpha( + new Buffer(exo_test_helper()->CreateGpuMemoryBuffer( + buffer_size, gfx::BufferFormat::RGBX_8888))); + + // Attaching a buffer without an alpha channel doesn't require draw with + // blending. + surface->Attach(buffer_without_alpha.get()); + surface->Commit(); + RunAllPendingInMessageLoop(); + + { + const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get()); + ASSERT_EQ(1u, frame.render_pass_list.size()); + ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size()); + EXPECT_FALSE(frame.render_pass_list.back() + ->quad_list.back() + ->ShouldDrawWithBlending()); + } } TEST_F(SurfaceTest, SetInputRegion) { @@ -192,15 +249,6 @@ EXPECT_EQ(crop_size.ToString(), surface->content_size().ToString()); } -const cc::CompositorFrame& GetFrameFromSurface(Surface* surface) { - cc::SurfaceId surface_id = surface->GetSurfaceId(); - cc::SurfaceManager* surface_manager = - aura::Env::GetInstance()->context_factory_private()->GetSurfaceManager(); - const cc::CompositorFrame& frame = - surface_manager->GetSurfaceForId(surface_id)->GetEligibleFrame(); - return frame; -} - TEST_F(SurfaceTest, SetBlendMode) { gfx::Size buffer_size(1, 1); std::unique_ptr<Buffer> buffer(
diff --git a/components/exo/test/exo_test_helper.cc b/components/exo/test/exo_test_helper.cc index ed68406..d729b75 100644 --- a/components/exo/test/exo_test_helper.cc +++ b/components/exo/test/exo_test_helper.cc
@@ -61,12 +61,12 @@ ExoTestHelper::~ExoTestHelper() {} std::unique_ptr<gfx::GpuMemoryBuffer> ExoTestHelper::CreateGpuMemoryBuffer( - const gfx::Size& size) { + const gfx::Size& size, + gfx::BufferFormat format) { return aura::Env::GetInstance() ->context_factory() ->GetGpuMemoryBufferManager() - ->CreateGpuMemoryBuffer(size, gfx::BufferFormat::RGBA_8888, - gfx::BufferUsage::GPU_READ, + ->CreateGpuMemoryBuffer(size, format, gfx::BufferUsage::GPU_READ, gpu::kNullSurfaceHandle); }
diff --git a/components/exo/test/exo_test_helper.h b/components/exo/test/exo_test_helper.h index 11bc8d7..1ae8cb6e 100644 --- a/components/exo/test/exo_test_helper.h +++ b/components/exo/test/exo_test_helper.h
@@ -9,6 +9,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" +#include "ui/gfx/buffer_types.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/size.h" @@ -48,7 +49,8 @@ // Creates a GpuMemoryBuffer instance that can be used for tests. std::unique_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer( - const gfx::Size& size); + const gfx::Size& size, + gfx::BufferFormat format = gfx::BufferFormat::RGBA_8888); // Creates window of size (width, height) at center of screen. ExoTestWindow CreateWindow(int width, int height, bool is_modal);
diff --git a/components/metrics/net/network_metrics_provider.cc b/components/metrics/net/network_metrics_provider.cc index cd2f4f5..bf56530 100644 --- a/components/metrics/net/network_metrics_provider.cc +++ b/components/metrics/net/network_metrics_provider.cc
@@ -18,7 +18,6 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/task_runner_util.h" -#include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "net/base/net_errors.h" #include "net/nqe/network_quality_estimator.h"
diff --git a/components/ntp_tiles/most_visited_sites_unittest.cc b/components/ntp_tiles/most_visited_sites_unittest.cc index d660682b..9c16609 100644 --- a/components/ntp_tiles/most_visited_sites_unittest.cc +++ b/components/ntp_tiles/most_visited_sites_unittest.cc
@@ -21,7 +21,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/task/cancelable_task_tracker.h" #include "base/test/sequenced_worker_pool_owner.h" -#include "base/threading/thread_task_runner_handle.h" #include "components/history/core/browser/top_sites.h" #include "components/history/core/browser/top_sites_observer.h" #include "components/ntp_tiles/icon_cacher.h"
diff --git a/components/sync/PRESUBMIT.py b/components/sync/PRESUBMIT.py index b9b669f..276449b 100644 --- a/components/sync/PRESUBMIT.py +++ b/components/sync/PRESUBMIT.py
@@ -61,6 +61,10 @@ SYNC_SOURCE_FILES = (r'^components[\\/]sync[\\/].*\.(cc|h)$',) +# The wrapper around lint that is called below disables a set of filters if the +# passed filter evaluates to false. Pass a junk filter to avoid this behavior. +LINT_FILTERS = ['+fake/filter'] + def CheckModelTypeInfoMap(input_api, output_api, model_type_file): """Checks the kModelTypeInfoMap in model_type.cc follows conventions. Checks that the kModelTypeInfoMap follows the below rules: @@ -366,9 +370,9 @@ def CheckChangeLintsClean(input_api, output_api): source_filter = lambda x: input_api.FilterSourceFile( x, white_list=SYNC_SOURCE_FILES, black_list=None) - return input_api.canned_checks.CheckChangeLintsClean( - input_api, output_api, source_filter, lint_filters=[], verbose_level=1) + input_api, output_api, source_filter, lint_filters=LINT_FILTERS, + verbose_level=1) def CheckChanges(input_api, output_api): results = []
diff --git a/components/sync/base/hash_util_unittest.cc b/components/sync/base/hash_util_unittest.cc index e43dd52..c0925e89 100644 --- a/components/sync/base/hash_util_unittest.cc +++ b/components/sync/base/hash_util_unittest.cc
@@ -4,7 +4,6 @@ #include "components/sync/base/hash_util.h" -#include "components/sync/base/model_type.h" #include "testing/gtest/include/gtest/gtest.h" namespace syncer {
diff --git a/components/sync/base/sync_features.h b/components/sync/base/sync_features.h index 7abca4c..e3b0a67 100644 --- a/components/sync/base/sync_features.h +++ b/components/sync/base/sync_features.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 COMPONENETS_SYNC_BASE_SYNC_FEATURES_H_ -#define COMPONENETS_SYNC_BASE_SYNC_FEATURES_H_ +#ifndef COMPONENTS_SYNC_BASE_SYNC_FEATURES_H_ +#define COMPONENTS_SYNC_BASE_SYNC_FEATURES_H_ #include "base/feature_list.h" @@ -13,4 +13,4 @@ } // namespace syncer -#endif // COMPONENETS_SYNC_BASE_SYNC_FEATURES_H_ +#endif // COMPONENTS_SYNC_BASE_SYNC_FEATURES_H_
diff --git a/components/sync/device_info/device_info_sync_bridge.cc b/components/sync/device_info/device_info_sync_bridge.cc index 9490815..caba3632 100644 --- a/components/sync/device_info/device_info_sync_bridge.cc +++ b/components/sync/device_info/device_info_sync_bridge.cc
@@ -18,7 +18,6 @@ #include "components/sync/device_info/device_info_util.h" #include "components/sync/model/entity_change.h" #include "components/sync/model/metadata_batch.h" -#include "components/sync/model/model_error.h" #include "components/sync/model/mutable_data_batch.h" #include "components/sync/protocol/model_type_state.pb.h" #include "components/sync/protocol/sync.pb.h"
diff --git a/components/sync/driver/generic_change_processor_unittest.cc b/components/sync/driver/generic_change_processor_unittest.cc index c29dd7f..1bc4628e 100644 --- a/components/sync/driver/generic_change_processor_unittest.cc +++ b/components/sync/driver/generic_change_processor_unittest.cc
@@ -20,7 +20,6 @@ #include "components/sync/engine/attachments/fake_attachment_uploader.h" #include "components/sync/engine/sync_encryption_handler.h" #include "components/sync/model/attachments/attachment_id.h" -#include "components/sync/model/attachments/attachment_service.h" #include "components/sync/model/data_type_error_handler_mock.h" #include "components/sync/model/fake_syncable_service.h" #include "components/sync/model/sync_change.h"
diff --git a/components/sync/driver/glue/sync_backend_host_core.cc b/components/sync/driver/glue/sync_backend_host_core.cc index 0751ba2..4708a23 100644 --- a/components/sync/driver/glue/sync_backend_host_core.cc +++ b/components/sync/driver/glue/sync_backend_host_core.cc
@@ -10,7 +10,6 @@ #include "base/files/file_util.h" #include "base/location.h" #include "base/memory/ptr_util.h" -#include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/memory_dump_manager.h" #include "components/data_use_measurement/core/data_use_user_data.h"
diff --git a/components/sync/driver/model_type_controller.cc b/components/sync/driver/model_type_controller.cc index 7bced2e..4c5d56f 100644 --- a/components/sync/driver/model_type_controller.cc +++ b/components/sync/driver/model_type_controller.cc
@@ -10,7 +10,6 @@ #include "base/bind_helpers.h" #include "base/location.h" #include "base/memory/ptr_util.h" -#include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "components/sync/base/bind_to_task_runner.h" #include "components/sync/base/data_type_histogram.h"
diff --git a/components/sync/driver/model_type_controller_unittest.cc b/components/sync/driver/model_type_controller_unittest.cc index ba3610c..fad3071 100644 --- a/components/sync/driver/model_type_controller_unittest.cc +++ b/components/sync/driver/model_type_controller_unittest.cc
@@ -11,7 +11,6 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/sequenced_task_runner.h"
diff --git a/components/sync/driver/resources/about.js b/components/sync/driver/resources/about.js index f562c80..cebf496e 100644 --- a/components/sync/driver/resources/about.js +++ b/components/sync/driver/resources/about.js
@@ -41,8 +41,14 @@ var type_status_array = chrome.sync.aboutInfo.type_status; type_status_array.forEach(function(row) { if (row.name == modelType) { - row.num_entries = counters.numEntriesAndTombstones; - row.num_live = counters.numEntries; + // There are three types of counters, only "status" counters have these + // fields. Keep the old values if updated fields are not present. + if (counters.numEntriesAndTombstones) { + row.num_entries = counters.numEntriesAndTombstones; + } + if (counters.numEntries) { + row.num_live = counters.numEntries; + } } }); jstProcess(
diff --git a/components/sync/engine/attachments/fake_attachment_downloader_unittest.cc b/components/sync/engine/attachments/fake_attachment_downloader_unittest.cc index 200d6aa..cc5498bb 100644 --- a/components/sync/engine/attachments/fake_attachment_downloader_unittest.cc +++ b/components/sync/engine/attachments/fake_attachment_downloader_unittest.cc
@@ -4,6 +4,7 @@ #include "components/sync/engine/attachments/fake_attachment_downloader.h" +#include <memory> #include <utility> #include <vector>
diff --git a/components/sync/engine/attachments/in_memory_attachment_store.cc b/components/sync/engine/attachments/in_memory_attachment_store.cc index 9069464..7a82b55 100644 --- a/components/sync/engine/attachments/in_memory_attachment_store.cc +++ b/components/sync/engine/attachments/in_memory_attachment_store.cc
@@ -5,6 +5,7 @@ #include "components/sync/engine/attachments/in_memory_attachment_store.h" #include <memory> +#include <utility> #include "base/bind.h" #include "base/callback.h"
diff --git a/components/sync/engine/attachments/on_disk_attachment_store.cc b/components/sync/engine/attachments/on_disk_attachment_store.cc index 4afc78b5a..5ad339d4 100644 --- a/components/sync/engine/attachments/on_disk_attachment_store.cc +++ b/components/sync/engine/attachments/on_disk_attachment_store.cc
@@ -6,7 +6,6 @@ #include <stdint.h> -#include <memory> #include <utility> #include "base/bind.h"
diff --git a/components/sync/engine/browser_thread_model_worker.cc b/components/sync/engine/browser_thread_model_worker.cc index b1a90f22..3b29d85 100644 --- a/components/sync/engine/browser_thread_model_worker.cc +++ b/components/sync/engine/browser_thread_model_worker.cc
@@ -6,7 +6,6 @@ #include "base/bind.h" #include "base/callback.h" -#include "base/single_thread_task_runner.h" #include "base/synchronization/waitable_event.h" using base::SingleThreadTaskRunner;
diff --git a/components/sync/engine/browser_thread_model_worker_unittest.cc b/components/sync/engine/browser_thread_model_worker_unittest.cc index f05d2b8..f4417e9 100644 --- a/components/sync/engine/browser_thread_model_worker_unittest.cc +++ b/components/sync/engine/browser_thread_model_worker_unittest.cc
@@ -10,7 +10,6 @@ #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" -#include "base/single_thread_task_runner.h" #include "base/test/test_timeouts.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h"
diff --git a/components/sync/engine/cycle/sync_cycle_snapshot_unittest.cc b/components/sync/engine/cycle/sync_cycle_snapshot_unittest.cc index d7ebb76..2e7c2b9 100644 --- a/components/sync/engine/cycle/sync_cycle_snapshot_unittest.cc +++ b/components/sync/engine/cycle/sync_cycle_snapshot_unittest.cc
@@ -4,8 +4,6 @@ #include "components/sync/engine/cycle/sync_cycle_snapshot.h" -#include <memory> - #include "base/test/values_test_util.h" #include "base/values.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/sync/engine/engine_components_factory_impl.cc b/components/sync/engine/engine_components_factory_impl.cc index dd913f9..68fc139 100644 --- a/components/sync/engine/engine_components_factory_impl.cc +++ b/components/sync/engine/engine_components_factory_impl.cc
@@ -4,6 +4,9 @@ #include "components/sync/engine/engine_components_factory_impl.h" +#include <map> +#include <utility> + #include "base/memory/ptr_util.h" #include "components/sync/engine_impl/backoff_delay_provider.h" #include "components/sync/engine_impl/cycle/sync_cycle_context.h"
diff --git a/components/sync/engine/sync_backend_registrar_unittest.cc b/components/sync/engine/sync_backend_registrar_unittest.cc index 678aff2..5c42d6e 100644 --- a/components/sync/engine/sync_backend_registrar_unittest.cc +++ b/components/sync/engine/sync_backend_registrar_unittest.cc
@@ -4,8 +4,6 @@ #include "components/sync/engine/sync_backend_registrar.h" -#include <memory> - #include "base/location.h" #include "base/memory/ptr_util.h" #include "base/run_loop.h"
diff --git a/components/sync/engine/ui_model_worker_unittest.cc b/components/sync/engine/ui_model_worker_unittest.cc index 25483532..9411a67a 100644 --- a/components/sync/engine/ui_model_worker_unittest.cc +++ b/components/sync/engine/ui_model_worker_unittest.cc
@@ -10,7 +10,6 @@ #include "base/bind_helpers.h" #include "base/location.h" #include "base/memory/ptr_util.h" -#include "base/memory/ref_counted.h" #include "base/run_loop.h" #include "base/test/test_timeouts.h" #include "base/threading/platform_thread.h"
diff --git a/components/sync/engine_impl/cycle/non_blocking_type_debug_info_emitter.cc b/components/sync/engine_impl/cycle/non_blocking_type_debug_info_emitter.cc index 3674784..a3b5bdf 100644 --- a/components/sync/engine_impl/cycle/non_blocking_type_debug_info_emitter.cc +++ b/components/sync/engine_impl/cycle/non_blocking_type_debug_info_emitter.cc
@@ -4,11 +4,6 @@ #include "components/sync/engine_impl/cycle/non_blocking_type_debug_info_emitter.h" -#include <vector> - -#include "components/sync/engine/cycle/status_counters.h" -#include "components/sync/engine/cycle/type_debug_info_observer.h" - namespace syncer { NonBlockingTypeDebugInfoEmitter::NonBlockingTypeDebugInfoEmitter( @@ -19,14 +14,10 @@ NonBlockingTypeDebugInfoEmitter::~NonBlockingTypeDebugInfoEmitter() {} void NonBlockingTypeDebugInfoEmitter::EmitStatusCountersUpdate() { - // TODO(gangwu): this function is to show Total Entries on "Types" tab on - // chrome://sync-internals, we decide to show zero right now, because it is - // hard to let emitter to get object of SharedModelTypeProcessor or - // ModelTypeStore, and also people can get the numbers from "about" tab on - // chrome://sync-internals. - StatusCounters counters; - for (auto& observer : *type_debug_info_observers_) - observer.OnStatusCountersUpdated(type_, counters); + // TODO(gangwu): Allow driving emission of status counters from here. This is + // tricky because we do not have access to SharedModelTypeProcessor or + // ModelTypeStore currently. This method is fairly redundant since counters + // are also emitted from the UI thread, unclear how important this is. } } // namespace syncer
diff --git a/components/sync/engine_impl/cycle/nudge_tracker.cc b/components/sync/engine_impl/cycle/nudge_tracker.cc index 1cf2391..15e83e1c 100644 --- a/components/sync/engine_impl/cycle/nudge_tracker.cc +++ b/components/sync/engine_impl/cycle/nudge_tracker.cc
@@ -4,6 +4,7 @@ #include "components/sync/engine_impl/cycle/nudge_tracker.h" +#include <algorithm> #include <utility> #include "base/memory/ptr_util.h"
diff --git a/components/sync/engine_impl/loopback_server/loopback_connection_manager.cc b/components/sync/engine_impl/loopback_server/loopback_connection_manager.cc index d218b8f..ee1bd0f 100644 --- a/components/sync/engine_impl/loopback_server/loopback_connection_manager.cc +++ b/components/sync/engine_impl/loopback_server/loopback_connection_manager.cc
@@ -3,8 +3,6 @@ // found in the LICENSE file. #include "components/sync/engine_impl/loopback_server/loopback_connection_manager.h" -#include <string> - namespace syncer { LoopbackConnectionManager::LoopbackConnectionManager(
diff --git a/components/sync/engine_impl/loopback_server/loopback_server.cc b/components/sync/engine_impl/loopback_server/loopback_server.cc index 88eb7ca..8022b5b 100644 --- a/components/sync/engine_impl/loopback_server/loopback_server.cc +++ b/components/sync/engine_impl/loopback_server/loopback_server.cc
@@ -4,15 +4,10 @@ #include "components/sync/engine_impl/loopback_server/loopback_server.h" -#include <stdint.h> - #include <algorithm> #include <limits> -#include <memory> #include <set> -#include <string> #include <utility> -#include <vector> #include "base/files/file_util.h" #include "base/guid.h" @@ -23,7 +18,6 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/synchronization/lock.h" -#include "components/sync/base/model_type.h" #include "components/sync/engine_impl/loopback_server/persistent_bookmark_entity.h" #include "components/sync/engine_impl/loopback_server/persistent_permanent_entity.h" #include "components/sync/engine_impl/loopback_server/persistent_tombstone_entity.h"
diff --git a/components/sync/engine_impl/loopback_server/loopback_server.h b/components/sync/engine_impl/loopback_server/loopback_server.h index 20af7bc..a69c99e 100644 --- a/components/sync/engine_impl/loopback_server/loopback_server.h +++ b/components/sync/engine_impl/loopback_server/loopback_server.h
@@ -27,7 +27,7 @@ // A loopback version of the Sync server used for local profile serialization. class LoopbackServer { public: - LoopbackServer(const base::FilePath& persistent_file); + explicit LoopbackServer(const base::FilePath& persistent_file); virtual ~LoopbackServer(); // Handles a /command POST (with the given |request|) to the server. Three
diff --git a/components/sync/engine_impl/loopback_server/loopback_server_entity.cc b/components/sync/engine_impl/loopback_server/loopback_server_entity.cc index db5a193..c6e20fe 100644 --- a/components/sync/engine_impl/loopback_server/loopback_server_entity.cc +++ b/components/sync/engine_impl/loopback_server/loopback_server_entity.cc
@@ -4,11 +4,7 @@ #include "components/sync/engine_impl/loopback_server/loopback_server_entity.h" -#include <stdint.h> - #include <limits> -#include <memory> -#include <string> #include <vector> #include "base/guid.h" @@ -19,12 +15,10 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" -#include "components/sync/base/model_type.h" #include "components/sync/engine_impl/loopback_server/persistent_bookmark_entity.h" #include "components/sync/engine_impl/loopback_server/persistent_permanent_entity.h" #include "components/sync/engine_impl/loopback_server/persistent_tombstone_entity.h" #include "components/sync/engine_impl/loopback_server/persistent_unique_client_entity.h" -#include "components/sync/protocol/sync.pb.h" #include "net/base/net_errors.h" #include "net/http/http_status_code.h"
diff --git a/components/sync/engine_impl/loopback_server/loopback_server_entity.h b/components/sync/engine_impl/loopback_server/loopback_server_entity.h index 92b564e..2ad2547 100644 --- a/components/sync/engine_impl/loopback_server/loopback_server_entity.h +++ b/components/sync/engine_impl/loopback_server/loopback_server_entity.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include <map> +#include <memory> #include <string> #include "components/sync/base/model_type.h"
diff --git a/components/sync/engine_impl/loopback_server/persistent_bookmark_entity.cc b/components/sync/engine_impl/loopback_server/persistent_bookmark_entity.cc index 16728a9..f1e7377 100644 --- a/components/sync/engine_impl/loopback_server/persistent_bookmark_entity.cc +++ b/components/sync/engine_impl/loopback_server/persistent_bookmark_entity.cc
@@ -4,15 +4,7 @@ #include "components/sync/engine_impl/loopback_server/persistent_bookmark_entity.h" -#include <stdint.h> - -#include <memory> -#include <string> - #include "base/guid.h" -#include "components/sync/base/model_type.h" -#include "components/sync/engine_impl/loopback_server/loopback_server_entity.h" -#include "components/sync/protocol/sync.pb.h" using std::string;
diff --git a/components/sync/engine_impl/loopback_server/persistent_permanent_entity.cc b/components/sync/engine_impl/loopback_server/persistent_permanent_entity.cc index decea55..e85aa022 100644 --- a/components/sync/engine_impl/loopback_server/persistent_permanent_entity.cc +++ b/components/sync/engine_impl/loopback_server/persistent_permanent_entity.cc
@@ -4,14 +4,8 @@ #include "components/sync/engine_impl/loopback_server/persistent_permanent_entity.h" -#include <memory> -#include <string> - #include "base/logging.h" #include "base/memory/ptr_util.h" -#include "components/sync/base/model_type.h" -#include "components/sync/engine_impl/loopback_server/loopback_server_entity.h" -#include "components/sync/protocol/sync.pb.h" using std::string;
diff --git a/components/sync/engine_impl/loopback_server/persistent_tombstone_entity.cc b/components/sync/engine_impl/loopback_server/persistent_tombstone_entity.cc index 0d5b88d..a32b134c 100644 --- a/components/sync/engine_impl/loopback_server/persistent_tombstone_entity.cc +++ b/components/sync/engine_impl/loopback_server/persistent_tombstone_entity.cc
@@ -4,13 +4,6 @@ #include "components/sync/engine_impl/loopback_server/persistent_tombstone_entity.h" -#include <memory> -#include <string> - -#include "components/sync/base/model_type.h" -#include "components/sync/engine_impl/loopback_server/loopback_server_entity.h" -#include "components/sync/protocol/sync.pb.h" - using std::string; using syncer::ModelType;
diff --git a/components/sync/engine_impl/loopback_server/persistent_unique_client_entity.cc b/components/sync/engine_impl/loopback_server/persistent_unique_client_entity.cc index 402d817..9a2b872 100644 --- a/components/sync/engine_impl/loopback_server/persistent_unique_client_entity.cc +++ b/components/sync/engine_impl/loopback_server/persistent_unique_client_entity.cc
@@ -4,14 +4,7 @@ #include "components/sync/engine_impl/loopback_server/persistent_unique_client_entity.h" -#include <stdint.h> - -#include <memory> -#include <string> - #include "base/guid.h" -#include "components/sync/base/model_type.h" -#include "components/sync/engine_impl/loopback_server/loopback_server_entity.h" #include "components/sync/engine_impl/loopback_server/persistent_permanent_entity.h" #include "components/sync/protocol/sync.pb.h"
diff --git a/components/sync/engine_impl/sync_manager_impl_unittest.cc b/components/sync/engine_impl/sync_manager_impl_unittest.cc index 8bf15f9..d7f0c79 100644 --- a/components/sync/engine_impl/sync_manager_impl_unittest.cc +++ b/components/sync/engine_impl/sync_manager_impl_unittest.cc
@@ -5,7 +5,6 @@ #include "components/sync/engine_impl/sync_manager_impl.h" #include <cstddef> -#include <memory> #include <utility> #include "base/callback.h"
diff --git a/components/sync/engine_impl/test_entry_factory.cc b/components/sync/engine_impl/test_entry_factory.cc index 1321a87..5d197c81 100644 --- a/components/sync/engine_impl/test_entry_factory.cc +++ b/components/sync/engine_impl/test_entry_factory.cc
@@ -5,7 +5,6 @@ #include "components/sync/engine_impl/test_entry_factory.h" #include "components/sync/base/hash_util.h" -#include "components/sync/base/model_type.h" #include "components/sync/syncable/directory.h" #include "components/sync/syncable/entry.h" #include "components/sync/syncable/model_neutral_mutable_entry.h"
diff --git a/components/sync/model/fake_model_type_sync_bridge.cc b/components/sync/model/fake_model_type_sync_bridge.cc index 1c6e6f9..d7c1c2f1 100644 --- a/components/sync/model/fake_model_type_sync_bridge.cc +++ b/components/sync/model/fake_model_type_sync_bridge.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "components/sync/base/hash_util.h" -#include "components/sync/model/model_error.h" #include "components/sync/model/mutable_data_batch.h" #include "components/sync/model_impl/in_memory_metadata_change_list.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/sync/model/recording_model_type_change_processor.cc b/components/sync/model/recording_model_type_change_processor.cc index 13c1850..0d37974 100644 --- a/components/sync/model/recording_model_type_change_processor.cc +++ b/components/sync/model/recording_model_type_change_processor.cc
@@ -4,7 +4,8 @@ #include "components/sync/model/recording_model_type_change_processor.h" -#include "components/sync/model/fake_model_type_change_processor.h" +#include <utility> + #include "components/sync/model/metadata_batch.h" namespace syncer {
diff --git a/components/sync/model/recording_model_type_change_processor.h b/components/sync/model/recording_model_type_change_processor.h index d0789b4e..6fe9180 100644 --- a/components/sync/model/recording_model_type_change_processor.h +++ b/components/sync/model/recording_model_type_change_processor.h
@@ -5,6 +5,11 @@ #ifndef COMPONENTS_SYNC_MODEL_RECORDING_MODEL_TYPE_CHANGE_PROCESSOR_H_ #define COMPONENTS_SYNC_MODEL_RECORDING_MODEL_TYPE_CHANGE_PROCESSOR_H_ +#include <map> +#include <memory> +#include <set> +#include <string> + #include "components/sync/model/fake_model_type_change_processor.h" namespace syncer { @@ -34,7 +39,7 @@ const std::set<std::string>& delete_set() const { return delete_set_; } - const MetadataBatch* metadata() const { return metadata_.get(); } + MetadataBatch* metadata() const { return metadata_.get(); } private: std::multimap<std::string, std::unique_ptr<EntityData>> put_multimap_;
diff --git a/components/sync/model_impl/attachments/task_queue_unittest.cc b/components/sync/model_impl/attachments/task_queue_unittest.cc index 413433c..634a5de 100644 --- a/components/sync/model_impl/attachments/task_queue_unittest.cc +++ b/components/sync/model_impl/attachments/task_queue_unittest.cc
@@ -6,7 +6,6 @@ #include <vector> -#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/timer/mock_timer.h"
diff --git a/components/sync/model_impl/model_type_store_impl.cc b/components/sync/model_impl/model_type_store_impl.cc index a4d02948..e4d7fcf 100644 --- a/components/sync/model_impl/model_type_store_impl.cc +++ b/components/sync/model_impl/model_type_store_impl.cc
@@ -4,7 +4,6 @@ #include "components/sync/model_impl/model_type_store_impl.h" -#include <string> #include <utility> #include "base/bind.h"
diff --git a/components/sync/model_impl/model_type_store_impl_unittest.cc b/components/sync/model_impl/model_type_store_impl_unittest.cc index 0f5c187..f959251 100644 --- a/components/sync/model_impl/model_type_store_impl_unittest.cc +++ b/components/sync/model_impl/model_type_store_impl_unittest.cc
@@ -4,6 +4,7 @@ #include "components/sync/model_impl/model_type_store_impl.h" +#include <map> #include <utility> #include "base/bind.h"
diff --git a/components/sync/model_impl/shared_model_type_processor.cc b/components/sync/model_impl/shared_model_type_processor.cc index 5081f13..614321d 100644 --- a/components/sync/model_impl/shared_model_type_processor.cc +++ b/components/sync/model_impl/shared_model_type_processor.cc
@@ -82,6 +82,7 @@ weak_ptr_factory_.GetWeakPtr())); } } else { + DCHECK_EQ(0u, batch->TakeAllMetadata().size()); // First time syncing; initialize metadata. model_type_state_.mutable_progress_marker()->set_data_type_id( GetSpecificsFieldNumberFromModelType(type_));
diff --git a/components/sync/protocol/proto_memory_estimations.cc b/components/sync/protocol/proto_memory_estimations.cc index f759f986..af9b102 100644 --- a/components/sync/protocol/proto_memory_estimations.cc +++ b/components/sync/protocol/proto_memory_estimations.cc
@@ -6,6 +6,8 @@ #include "components/sync/protocol/proto_memory_estimations.h" +#include <string> + #include "base/trace_event/memory_usage_estimator.h" #include "components/sync/protocol/proto_visitors.h"
diff --git a/components/sync/protocol/proto_value_conversions.cc b/components/sync/protocol/proto_value_conversions.cc index d2ed4fcb..95897e2 100644 --- a/components/sync/protocol/proto_value_conversions.cc +++ b/components/sync/protocol/proto_value_conversions.cc
@@ -7,6 +7,7 @@ #include <stdint.h> #include <string> +#include <utility> #include "base/base64.h" #include "base/memory/ptr_util.h"
diff --git a/components/sync_bookmarks/PRESUBMIT.py b/components/sync_bookmarks/PRESUBMIT.py index 33378623..db47db9 100644 --- a/components/sync_bookmarks/PRESUBMIT.py +++ b/components/sync_bookmarks/PRESUBMIT.py
@@ -13,11 +13,16 @@ SYNC_BOOKMARKS_SOURCE_FILES = ( r'^components[\\/]sync_bookmarks[\\/].*\.(cc|h)$',) +# The wrapper around lint that is called below disables a set of filters if the +# passed filter evaluates to false. Pass a junk filter to avoid this behavior. +LINT_FILTERS = ['+fake/filter'] + def CheckChangeLintsClean(input_api, output_api): source_filter = lambda x: input_api.FilterSourceFile( x, white_list=SYNC_BOOKMARKS_SOURCE_FILES, black_list=None) return input_api.canned_checks.CheckChangeLintsClean( - input_api, output_api, source_filter, lint_filters=[], verbose_level=1) + input_api, output_api, source_filter, lint_filters=LINT_FILTERS, + verbose_level=1) def CheckChanges(input_api, output_api): results = []
diff --git a/components/sync_sessions/PRESUBMIT.py b/components/sync_sessions/PRESUBMIT.py index 39f2f9ac..ae142e0 100644 --- a/components/sync_sessions/PRESUBMIT.py +++ b/components/sync_sessions/PRESUBMIT.py
@@ -12,11 +12,16 @@ SYNC_SESSIONS_SOURCE_FILES = (r'^components[\\/]sync_sessions[\\/].*\.(cc|h)$',) +# The wrapper around lint that is called below disables a set of filters if the +# passed filter evaluates to false. Pass a junk filter to avoid this behavior. +LINT_FILTERS = ['+fake/filter'] + def CheckChangeLintsClean(input_api, output_api): source_filter = lambda x: input_api.FilterSourceFile( x, white_list=SYNC_SESSIONS_SOURCE_FILES, black_list=None) return input_api.canned_checks.CheckChangeLintsClean( - input_api, output_api, source_filter, lint_filters=[], verbose_level=1) + input_api, output_api, source_filter, lint_filters=LINT_FILTERS, + verbose_level=1) def CheckChanges(input_api, output_api): results = []
diff --git a/components/sync_sessions/revisit/page_revisit_broadcaster.cc b/components/sync_sessions/revisit/page_revisit_broadcaster.cc index 19837833..cfeca0b 100644 --- a/components/sync_sessions/revisit/page_revisit_broadcaster.cc +++ b/components/sync_sessions/revisit/page_revisit_broadcaster.cc
@@ -4,9 +4,7 @@ #include "components/sync_sessions/revisit/page_revisit_broadcaster.h" -#include <memory> #include <string> -#include <vector> #include "base/memory/ptr_util.h" #include "base/metrics/field_trial.h"
diff --git a/components/sync_sessions/revisit/page_revisit_broadcaster.h b/components/sync_sessions/revisit/page_revisit_broadcaster.h index 7bae4f0..150320c 100644 --- a/components/sync_sessions/revisit/page_revisit_broadcaster.h +++ b/components/sync_sessions/revisit/page_revisit_broadcaster.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_SYNC_SESSIONS_REVISIT_PAGE_REVISIT_BROADCASTER_H_ #define COMPONENTS_SYNC_SESSIONS_REVISIT_PAGE_REVISIT_BROADCASTER_H_ +#include <memory> #include <vector> #include "base/macros.h"
diff --git a/components/sync_sessions/synced_tab_delegate.h b/components/sync_sessions/synced_tab_delegate.h index aa81540..9781578 100644 --- a/components/sync_sessions/synced_tab_delegate.h +++ b/components/sync_sessions/synced_tab_delegate.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_SYNC_SESSIONS_SYNCED_TAB_DELEGATE_H__ #define COMPONENTS_SYNC_SESSIONS_SYNCED_TAB_DELEGATE_H__ +#include <memory> #include <string> #include <vector>
diff --git a/components/ukm/ukm_service.cc b/components/ukm/ukm_service.cc index e050b4bb..42bb7ad3 100644 --- a/components/ukm/ukm_service.cc +++ b/components/ukm/ukm_service.cc
@@ -14,7 +14,6 @@ #include "base/metrics/histogram_macros.h" #include "base/rand_util.h" #include "base/strings/string_number_conversions.h" -#include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "components/metrics/metrics_log.h" #include "components/metrics/metrics_log_uploader.h"
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index c61d97f..f0f2743d 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -57,6 +57,7 @@ #include "content/public/common/service_names.mojom.h" #include "gpu/command_buffer/service/gpu_preferences.h" #include "gpu/command_buffer/service/gpu_switches.h" +#include "gpu/config/gpu_driver_bug_list.h" #include "gpu/ipc/host/shader_disk_cache.h" #include "gpu/ipc/service/switches.h" #include "ipc/ipc_channel_handle.h" @@ -1056,6 +1057,11 @@ browser_command_line, switches::kGLSwitchesCopiedFromGpuProcessHost, switches::kGLSwitchesCopiedFromGpuProcessHostNumSwitches); + std::vector<const char*> gpu_workarounds; + gpu::GpuDriverBugList::AppendAllWorkarounds(&gpu_workarounds); + cmd_line->CopySwitchesFrom(browser_command_line, + gpu_workarounds.data(), gpu_workarounds.size()); + GetContentClient()->browser()->AppendExtraCommandLineSwitches( cmd_line.get(), process_->GetData().id);
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc b/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc index 375da42c..eaf04a7 100644 --- a/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc +++ b/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc
@@ -53,11 +53,13 @@ const int kRenderFrameId = 31415; const int kSharedMemoryCount = 11; const char kSecurityOrigin[] = "http://localhost"; +#if BUILDFLAG(ENABLE_WEBRTC) #if defined(OS_WIN) const wchar_t kBaseFileName[] = L"some_file_name"; #else const char kBaseFileName[] = "some_file_name"; -#endif +#endif // defined(OS_WIN) +#endif // BUILDFLAG(ENABLE_WEBRTC) url::Origin SecurityOrigin() { return url::Origin(GURL(kSecurityOrigin));
diff --git a/content/test/gpu/gpu_tests/gpu_process_integration_test.py b/content/test/gpu/gpu_tests/gpu_process_integration_test.py index 89691ed..225c3dd 100644 --- a/content/test/gpu/gpu_tests/gpu_process_integration_test.py +++ b/content/test/gpu/gpu_tests/gpu_process_integration_test.py
@@ -115,7 +115,8 @@ ('GpuProcess_identify_active_gpu2', 'chrome:gpu'), ('GpuProcess_identify_active_gpu3', 'chrome:gpu'), ('GpuProcess_identify_active_gpu4', 'chrome:gpu'), - ('GpuProcess_software_gpu_process', 'about:blank')) + ('GpuProcess_software_gpu_process', 'about:blank'), + ('GpuProcess_disabling_workarounds_works', 'chrome:gpu')) # The earlier has_transparent_visuals_gpu_process and # no_transparent_visuals_gpu_process tests became no-ops in @@ -526,6 +527,17 @@ self._Navigate(test_path) self._VerifyGpuProcessPresent() + def _GpuProcess_disabling_workarounds_works(self, test_path): + self.RestartBrowserIfNecessaryWithArgs([ + '--gpu-testing-vendor-id=0xbad9', + '--gpu-testing-device-id=0xbad9', + '--use_gpu_driver_workaround_for_testing=0']) + self._Navigate(test_path) + workarounds, _ = ( + self._CompareAndCaptureDriverBugWorkarounds()) + if 'use_gpu_driver_workaround_for_testing' in workarounds: + self.fail('use_gpu_driver_workaround_for_testing erroneously present') + def load_tests(loader, tests, pattern): del loader, tests, pattern # Unused. return gpu_integration_test.LoadAllTestsInModule(sys.modules[__name__])
diff --git a/gpu/config/gpu_driver_bug_list.cc b/gpu/config/gpu_driver_bug_list.cc index 7ab68a10..edd9dcf 100644 --- a/gpu/config/gpu_driver_bug_list.cc +++ b/gpu/config/gpu_driver_bug_list.cc
@@ -94,5 +94,17 @@ } } +// static +void GpuDriverBugList::AppendAllWorkarounds( + std::vector<const char*>* workarounds) { + workarounds->resize(workarounds->size() + + NUMBER_OF_GPU_DRIVER_BUG_WORKAROUND_TYPES); + +#define GPU_OP(type, name) workarounds->push_back(#name); + GPU_DRIVER_BUG_WORKAROUNDS(GPU_OP) +#undef GPU_OP +} + + } // namespace gpu
diff --git a/gpu/config/gpu_driver_bug_list.h b/gpu/config/gpu_driver_bug_list.h index 8db219f..0ec839e 100644 --- a/gpu/config/gpu_driver_bug_list.h +++ b/gpu/config/gpu_driver_bug_list.h
@@ -28,6 +28,11 @@ std::set<int>* workarounds, const base::CommandLine& command_line); + // Append |workarounds| with the full list of workarounds. + // This is needed for correctly passing flags down from + // the browser process to the GPU process. + static void AppendAllWorkarounds(std::vector<const char*>* workarounds); + private: GpuDriverBugList();
diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc index dc2c7a8..2ff6190a 100644 --- a/gpu/config/gpu_driver_bug_list_json.cc +++ b/gpu/config/gpu_driver_bug_list_json.cc
@@ -19,7 +19,7 @@ { "name": "gpu driver bug list", // Please update the version number whenever you change this file. - "version": "9.29", + "version": "9.30", "entries": [ { "id": 1, @@ -2324,6 +2324,9 @@ "use_virtualized_gl_contexts" ] }, +) // LONG_STRING_CONST macro +// Avoid C2026 (string too big) error on VisualStudio. +LONG_STRING_CONST( { "id": 214, "description": "Certain versions of Qualcomm driver don't setup scissor state correctly when FBO0 is bound.", @@ -2333,6 +2336,16 @@ "features": [ "force_update_scissor_state_when_binding_fbo0" ] + }, + { + "id": 215, + "description": "Fake no-op GPU driver bug workaround for testing", + "cr_bugs": [682912], + "vendor_id": "0xbad9", + "device_id": ["0xbad9"], + "features": [ + "use_gpu_driver_workaround_for_testing" + ] } ] // Please update the version number at beginning of this file whenever you
diff --git a/ios/chrome/browser/reading_list/BUILD.gn b/ios/chrome/browser/reading_list/BUILD.gn index 4a869ce..40d5ac3 100644 --- a/ios/chrome/browser/reading_list/BUILD.gn +++ b/ios/chrome/browser/reading_list/BUILD.gn
@@ -26,6 +26,7 @@ ] deps = [ "//base", + "//components/browser_sync", "//components/dom_distiller/ios", "//components/favicon/core", "//components/favicon/ios",
diff --git a/ios/chrome/browser/reading_list/reading_list_model_factory.cc b/ios/chrome/browser/reading_list/reading_list_model_factory.cc index b6e2c0c..e396d61 100644 --- a/ios/chrome/browser/reading_list/reading_list_model_factory.cc +++ b/ios/chrome/browser/reading_list/reading_list_model_factory.cc
@@ -9,6 +9,7 @@ #include "base/files/file_path.h" #include "base/memory/ptr_util.h" #include "base/memory/singleton.h" +#include "components/browser_sync/profile_sync_service.h" #include "components/keyed_service/ios/browser_state_dependency_manager.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/reading_list/core/reading_list_switches.h" @@ -19,6 +20,7 @@ #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/experimental_flags.h" +#include "ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.h" #include "ios/chrome/common/channel_info.h" #include "ios/web/public/web_thread.h" @@ -62,23 +64,18 @@ std::unique_ptr<KeyedService> ReadingListModelFactory::BuildServiceInstanceFor( web::BrowserState* context) const { - scoped_refptr<base::SequencedTaskRunner> background_task_runner = - web::WebThread::GetBlockingPool()->GetSequencedTaskRunner( - web::WebThread::GetBlockingPool()->GetSequenceToken()); + ios::ChromeBrowserState* chrome_browser_state = + ios::ChromeBrowserState::FromBrowserState(context); + browser_sync::ProfileSyncService* profile_sync_service = + IOSChromeProfileSyncServiceFactory::GetForBrowserState( + chrome_browser_state); - base::FilePath database_dir( - context->GetStatePath().Append(FILE_PATH_LITERAL("readinglist"))); - - // TODO(crbug.com/664920): use a shared location for the store. std::unique_ptr<ReadingListStore> store = base::MakeUnique<ReadingListStore>( - base::Bind(&syncer::ModelTypeStore::CreateStore, syncer::READING_LIST, - database_dir.AsUTF8Unsafe(), background_task_runner), + profile_sync_service->GetModelTypeStoreFactory(syncer::READING_LIST), base::Bind(&syncer::ModelTypeChangeProcessor::Create, base::BindRepeating(&syncer::ReportUnrecoverableError, GetChannel()))); - ios::ChromeBrowserState* chrome_browser_state = - ios::ChromeBrowserState::FromBrowserState(context); std::unique_ptr<KeyedService> reading_list_model = base::MakeUnique<ReadingListModelImpl>(std::move(store), chrome_browser_state->GetPrefs());
diff --git a/ios/chrome/browser/sync/BUILD.gn b/ios/chrome/browser/sync/BUILD.gn index 3dabba1..14f9eed6 100644 --- a/ios/chrome/browser/sync/BUILD.gn +++ b/ios/chrome/browser/sync/BUILD.gn
@@ -67,6 +67,7 @@ allow_circular_includes_from = [ "//ios/chrome/browser/history", "//ios/chrome/browser/passwords", + "//ios/chrome/browser/reading_list", "//ios/chrome/browser/signin", "//ios/chrome/browser/sync/glue", "//ios/chrome/browser/sync/sessions",
diff --git a/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory_unittest.cc b/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory_unittest.cc index a6514e3b..b82fa5c 100644 --- a/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory_unittest.cc +++ b/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory_unittest.cc
@@ -6,10 +6,9 @@ #include <stddef.h> -#include <memory> +#include <vector> #include "base/command_line.h" -#include "base/macros.h" #include "components/browser_sync/browser_sync_switches.h" #include "components/browser_sync/profile_sync_service.h" #include "components/reading_list/core/reading_list_switches.h"
diff --git a/ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.cc b/ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.cc index f83e9782..e861a942 100644 --- a/ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.cc +++ b/ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.cc
@@ -4,6 +4,8 @@ #include "ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.h" +#include <utility> + #include "base/bind.h" #include "base/memory/ptr_util.h" #include "components/browser_sync/profile_sync_service_mock.h"
diff --git a/ios/chrome/browser/sync/ios_chrome_synced_tab_delegate.h b/ios/chrome/browser/sync/ios_chrome_synced_tab_delegate.h index 341c040..2d59185 100644 --- a/ios/chrome/browser/sync/ios_chrome_synced_tab_delegate.h +++ b/ios/chrome/browser/sync/ios_chrome_synced_tab_delegate.h
@@ -5,6 +5,7 @@ #ifndef IOS_CHROME_BROWSER_SYNC_IOS_CHROME_SYNCED_TAB_DELEGATE_H_ #define IOS_CHROME_BROWSER_SYNC_IOS_CHROME_SYNCED_TAB_DELEGATE_H_ +#include <memory> #include <string> #include <vector>
diff --git a/ios/chrome/browser/sync/sync_setup_service.cc b/ios/chrome/browser/sync/sync_setup_service.cc index d496363..601e1f58 100644 --- a/ios/chrome/browser/sync/sync_setup_service.cc +++ b/ios/chrome/browser/sync/sync_setup_service.cc
@@ -6,7 +6,6 @@ #include <stdio.h> -#include "base/macros.h" #include "base/metrics/histogram_macros.h" #include "components/prefs/pref_service.h" #include "components/sync/base/stop_source.h"
diff --git a/ios/chrome/browser/tabs/tab_model_order_controller_unittest.mm b/ios/chrome/browser/tabs/tab_model_order_controller_unittest.mm index 450d8a3..bde32a3 100644 --- a/ios/chrome/browser/tabs/tab_model_order_controller_unittest.mm +++ b/ios/chrome/browser/tabs/tab_model_order_controller_unittest.mm
@@ -5,11 +5,13 @@ #include "base/mac/scoped_nsautorelease_pool.h" #include "base/memory/ptr_util.h" #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" +#include "ios/chrome/browser/browser_state/test_chrome_browser_state_manager.h" #import "ios/chrome/browser/sessions/session_window.h" #import "ios/chrome/browser/sessions/test_session_service.h" #import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/tabs/tab_model_order_controller.h" +#include "ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_state_manager.h" #include "ios/web/public/referrer.h" #include "ios/web/public/test/test_web_thread_bundle.h" #include "ios/web/public/web_thread.h" @@ -21,7 +23,10 @@ class TabModelOrderControllerTest : public PlatformTest { protected: TabModelOrderControllerTest() - : thread_bundle_(web::TestWebThreadBundle::IO_MAINLOOP) {} + : thread_bundle_(web::TestWebThreadBundle::IO_MAINLOOP), + scoped_browser_state_manager_( + base::MakeUnique<TestChromeBrowserStateManager>(base::FilePath())) { + } void SetUp() override { DCHECK_CURRENTLY_ON(web::WebThread::UI); @@ -78,6 +83,7 @@ GURL url_; web::Referrer referrer_; web::TestWebThreadBundle thread_bundle_; + IOSChromeScopedTestingChromeBrowserStateManager scoped_browser_state_manager_; base::scoped_nsobject<SessionWindowIOS> sessionWindow_; std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; base::scoped_nsobject<Tab> dummy_tab_;
diff --git a/ios/chrome/browser/ui/static_content/static_html_native_content.mm b/ios/chrome/browser/ui/static_content/static_html_native_content.mm index 10b55bb..5c151b9 100644 --- a/ios/chrome/browser/ui/static_content/static_html_native_content.mm +++ b/ios/chrome/browser/ui/static_content/static_html_native_content.mm
@@ -119,6 +119,10 @@ return [_staticHTMLViewController webView]; } +- (void)setDelegate:(id<CRWNativeContentDelegate>)delegate { + [_staticHTMLViewController setDelegate:delegate]; +} + - (NSString*)title { return [_staticHTMLViewController title]; }
diff --git a/mojo/public/tools/bindings/chromium_bindings_configuration.gni b/mojo/public/tools/bindings/chromium_bindings_configuration.gni index 356dd718..2aaff9e 100644 --- a/mojo/public/tools/bindings/chromium_bindings_configuration.gni +++ b/mojo/public/tools/bindings/chromium_bindings_configuration.gni
@@ -26,6 +26,7 @@ "//mojo/common/typemaps.gni", "//mojo/public/cpp/bindings/tests/chromium_typemaps.gni", "//net/interfaces/typemaps.gni", + "//services/memory_instrumentation/public/cpp/typemaps.gni", "//services/service_manager/public/cpp/typemaps.gni", "//services/ui/gpu/interfaces/typemaps.gni", "//services/ui/public/interfaces/ime/typemaps.gni",
diff --git a/net/cert/cert_verify_proc_android.cc b/net/cert/cert_verify_proc_android.cc index 0ce19d63..a59ab28 100644 --- a/net/cert/cert_verify_proc_android.cc +++ b/net/cert/cert_verify_proc_android.cc
@@ -297,13 +297,6 @@ verify_result->verified_cert = verified_cert; } - // Extract the algorithm information from the certs - X509Certificate::OSCertHandles chain; - const X509Certificate::OSCertHandles& intermediates = - verify_result->verified_cert->GetIntermediateCertificates(); - chain.push_back(verify_result->verified_cert->os_cert_handle()); - chain.insert(chain.end(), intermediates.begin(), intermediates.end()); - // Extract the public key hashes. for (size_t i = 0; i < verified_chain.size(); i++) { base::StringPiece spki_bytes;
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc index c8831644..7cff730 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_factory_impl_job.cc
@@ -405,6 +405,9 @@ DCHECK_NE(job_type_, PRECONNECT); DCHECK(!delegate_->for_websockets()); + UMA_HISTOGRAM_TIMES("Net.HttpStreamFactoryJob.StreamReadyCallbackTime", + base::TimeTicks::Now() - job_stream_ready_start_time_); + MaybeCopyConnectionAttemptsFromSocketOrHandle(); delegate_->OnStreamReady(this, server_ssl_config_); @@ -623,6 +626,7 @@ } } else { DCHECK(stream_.get()); + job_stream_ready_start_time_ = base::TimeTicks::Now(); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr()));
diff --git a/net/http/http_stream_factory_impl_job.h b/net/http/http_stream_factory_impl_job.h index 6917b0e..a04e8e3 100644 --- a/net/http/http_stream_factory_impl_job.h +++ b/net/http/http_stream_factory_impl_job.h
@@ -475,6 +475,8 @@ // Only used if |new_spdy_session_| is non-NULL. bool spdy_session_direct_; + base::TimeTicks job_stream_ready_start_time_; + // Type of stream that is requested. HttpStreamRequest::StreamType stream_type_;
diff --git a/pdf/pdfium/pdfium_page.cc b/pdf/pdfium/pdfium_page.cc index 39db69e..e8070f2 100644 --- a/pdf/pdfium/pdfium_page.cc +++ b/pdf/pdfium/pdfium_page.cc
@@ -180,7 +180,8 @@ int text_run_font_size = FPDFText_GetFontSize(text_page, char_index); pp::FloatRect text_run_bounds = GetFloatCharRectInPixels(page, text_page, char_index); - char_index++; + if (char_index < chars_count) + char_index++; while (char_index < chars_count) { unsigned int character = FPDFText_GetUnicode(text_page, char_index);
diff --git a/services/BUILD.gn b/services/BUILD.gn index ddb175f1..39efe0d 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn
@@ -16,6 +16,7 @@ service_test("service_unittests") { deps = [ "//services/image_decoder:tests", + "//services/memory_instrumentation:tests", ] if (is_android) {
diff --git a/services/memory_instrumentation/BUILD.gn b/services/memory_instrumentation/BUILD.gn new file mode 100644 index 0000000..144268ab --- /dev/null +++ b/services/memory_instrumentation/BUILD.gn
@@ -0,0 +1,31 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("lib") { + sources = [ + "coordinator_impl.cc", + "coordinator_impl.h", + ] + + public_deps = [ + "//base", + "//services/memory_instrumentation/public/cpp", + "//services/memory_instrumentation/public/interfaces", + ] +} + +source_set("tests") { + testonly = true + + sources = [ + "coordinator_impl_unittest.cc", + ] + + deps = [ + ":lib", + "//base", + "//mojo/public/cpp/bindings", + "//testing/gtest", + ] +}
diff --git a/services/memory_instrumentation/coordinator_impl.cc b/services/memory_instrumentation/coordinator_impl.cc new file mode 100644 index 0000000..90d3e30c --- /dev/null +++ b/services/memory_instrumentation/coordinator_impl.cc
@@ -0,0 +1,186 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/memory_instrumentation/coordinator_impl.h" + +#include "base/bind_helpers.h" +#include "base/lazy_instance.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/trace_event/memory_dump_manager.h" +#include "base/trace_event/memory_dump_request_args.h" +#include "services/memory_instrumentation/public/interfaces/memory_instrumentation.mojom.h" + +namespace memory_instrumentation { + +namespace { + +base::LazyInstance<CoordinatorImpl>::Leaky g_coordinator = + LAZY_INSTANCE_INITIALIZER; + +} // namespace + +// static +CoordinatorImpl* CoordinatorImpl::GetInstance() { + return g_coordinator.Pointer(); +} + +// TODO(chiniforooshan): Initialize the global MemoryDumpManager instance here. +// This is how the global MemoryDumpManager gets a reference to the delegate on +// the service (read the browser) process for service process memory dumps. This +// can be done when the delegate implementation is landed. +CoordinatorImpl::CoordinatorImpl() + : failed_memory_dump_count_(0) {} + +CoordinatorImpl::~CoordinatorImpl() {} + +void CoordinatorImpl::BindCoordinatorRequest( + mojom::CoordinatorRequest request) { + bindings_.AddBinding(this, std::move(request)); +} + +CoordinatorImpl::QueuedMemoryDumpRequest::QueuedMemoryDumpRequest( + const base::trace_event::MemoryDumpRequestArgs args, + const RequestGlobalMemoryDumpCallback callback) + : args(args), callback(callback) {} + +CoordinatorImpl::QueuedMemoryDumpRequest::~QueuedMemoryDumpRequest() {} + +void CoordinatorImpl::RequestGlobalMemoryDump( + const base::trace_event::MemoryDumpRequestArgs& args, + const RequestGlobalMemoryDumpCallback& callback) { + DCHECK(thread_checker_.CalledOnValidThread()); + + bool another_dump_already_in_progress = !queued_memory_dump_requests_.empty(); + + // If this is a periodic memory dump request and there already is another + // request in the queue with the same level of detail, there's no point in + // enqueuing this request. + if (another_dump_already_in_progress && + args.dump_type == base::trace_event::MemoryDumpType::PERIODIC_INTERVAL) { + for (const auto& request : queued_memory_dump_requests_) { + if (request.args.level_of_detail == args.level_of_detail) { + VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix << " (" + << base::trace_event::MemoryDumpTypeToString(args.dump_type) + << ") skipped because another dump request with the same " + "level of detail (" + << base::trace_event::MemoryDumpLevelOfDetailToString( + args.level_of_detail) + << ") is already in the queue"; + callback.Run(args.dump_guid, false /* success */); + return; + } + } + } + + queued_memory_dump_requests_.emplace_back(args, callback); + + // If another dump is already in progress, this dump will automatically be + // scheduled when the other dump finishes. + if (another_dump_already_in_progress) + return; + + PerformNextQueuedGlobalMemoryDump(); +} + +void CoordinatorImpl::RegisterProcessLocalDumpManager( + mojom::ProcessLocalDumpManagerPtr process_manager) { + DCHECK(thread_checker_.CalledOnValidThread()); + + process_manager.set_connection_error_handler( + base::Bind(&CoordinatorImpl::UnregisterProcessLocalDumpManager, + base::Unretained(this), + process_manager.get())); + auto result = process_managers_.insert( + std::make_pair<mojom::ProcessLocalDumpManager*, + mojom::ProcessLocalDumpManagerPtr>( + process_manager.get(), std::move(process_manager))); + DCHECK(result.second); +} + +void CoordinatorImpl::UnregisterProcessLocalDumpManager( + mojom::ProcessLocalDumpManager* process_manager) { + DCHECK(process_managers_.erase(process_manager) == 1); + + // Check if we are waiting for an ack from this process-local manager. + if (pending_process_managers_.find(process_manager) != + pending_process_managers_.end()) { + DCHECK(!queued_memory_dump_requests_.empty()); + OnProcessMemoryDumpResponse( + process_manager, + queued_memory_dump_requests_.front().args.dump_guid, + false /* success */); + } +} + +void CoordinatorImpl::PerformNextQueuedGlobalMemoryDump() { + DCHECK(!queued_memory_dump_requests_.empty()); + const base::trace_event::MemoryDumpRequestArgs& args = + queued_memory_dump_requests_.front().args; + + // No need to treat the service process different than other processes. The + // service process will register itself as a ProcessLocalDumpManager and will + // be treated like other process-local managers. + pending_process_managers_.clear(); + failed_memory_dump_count_ = 0; + for (const auto& key_value : process_managers_) { + pending_process_managers_.insert(key_value.first); + key_value.second->RequestProcessMemoryDump( + args, + base::Bind(&CoordinatorImpl::OnProcessMemoryDumpResponse, + base::Unretained(this), + key_value.first)); + } + // Run the callback in case there are no process-local managers. + FinalizeGlobalMemoryDumpIfAllManagersReplied(); +} + +void CoordinatorImpl::OnProcessMemoryDumpResponse( + mojom::ProcessLocalDumpManager* process_manager, + uint64_t dump_guid, + bool success) { + auto it = pending_process_managers_.find(process_manager); + + DCHECK(!queued_memory_dump_requests_.empty()); + if (queued_memory_dump_requests_.front().args.dump_guid != dump_guid || + it == pending_process_managers_.end()) { + VLOG(1) << "Received unexpected memory dump response: " << dump_guid; + return; + } + pending_process_managers_.erase(it); + + if (!success) { + ++failed_memory_dump_count_; + VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix + << " failed because of NACK from provider"; + } + FinalizeGlobalMemoryDumpIfAllManagersReplied(); +} + +void CoordinatorImpl::FinalizeGlobalMemoryDumpIfAllManagersReplied() { + if (pending_process_managers_.size() > 0) + return; + + DCHECK(!queued_memory_dump_requests_.empty()); + { + const auto& callback = queued_memory_dump_requests_.front().callback; + const bool global_success = failed_memory_dump_count_ == 0; + callback.Run(queued_memory_dump_requests_.front().args.dump_guid, + global_success); + } + queued_memory_dump_requests_.pop_front(); + + // Schedule the next queued dump (if applicable). + if (!queued_memory_dump_requests_.empty()) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind( + &CoordinatorImpl::PerformNextQueuedGlobalMemoryDump, + base::Unretained(this))); + } +} + +} // namespace memory_instrumentation
diff --git a/services/memory_instrumentation/coordinator_impl.h b/services/memory_instrumentation/coordinator_impl.h new file mode 100644 index 0000000..ab76df1 --- /dev/null +++ b/services/memory_instrumentation/coordinator_impl.h
@@ -0,0 +1,87 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_MEMORY_INSTRUMENTATION_COORDINATOR_IMPL_H_ +#define SERVICES_MEMORY_INSTRUMENTATION_COORDINATOR_IMPL_H_ + +#include <list> +#include <set> +#include <unordered_map> + +#include "base/lazy_instance.h" +#include "base/memory/ref_counted.h" +#include "base/threading/thread_checker.h" +#include "base/trace_event/memory_dump_request_args.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/bindings/binding_set.h" +#include "services/memory_instrumentation/public/cpp/coordinator.h" +#include "services/memory_instrumentation/public/interfaces/memory_instrumentation.mojom.h" + +namespace memory_instrumentation { + +class CoordinatorImpl : public Coordinator, public mojom::Coordinator { + public: + static CoordinatorImpl* GetInstance(); + + // Coordinator + void BindCoordinatorRequest(mojom::CoordinatorRequest) override; + + private: + friend class CoordinatorImplTest; // For testing + friend struct base::DefaultLazyInstanceTraits<CoordinatorImpl>; + + struct QueuedMemoryDumpRequest { + QueuedMemoryDumpRequest( + const base::trace_event::MemoryDumpRequestArgs args, + const RequestGlobalMemoryDumpCallback callback); + ~QueuedMemoryDumpRequest(); + const base::trace_event::MemoryDumpRequestArgs args; + const RequestGlobalMemoryDumpCallback callback; + }; + + CoordinatorImpl(); + ~CoordinatorImpl() override; + + // mojom::Coordinator + void RegisterProcessLocalDumpManager( + mojom::ProcessLocalDumpManagerPtr process_manager) override; + + // Broadcasts a dump request to all the process-local managers registered and + // notifies when all of them have completed, or the global dump attempt + // failed. This is in the mojom::Coordinator interface. + void RequestGlobalMemoryDump( + const base::trace_event::MemoryDumpRequestArgs& args, + const RequestGlobalMemoryDumpCallback& callback) override; + + // Called when a process-local manager gets disconnected. + void UnregisterProcessLocalDumpManager( + mojom::ProcessLocalDumpManager* process_manager); + + // Callback of RequestProcessMemoryDump. + void OnProcessMemoryDumpResponse( + mojom::ProcessLocalDumpManager* process_manager, + uint64_t dump_guid, + bool success); + + void PerformNextQueuedGlobalMemoryDump(); + void FinalizeGlobalMemoryDumpIfAllManagersReplied(); + + mojo::BindingSet<mojom::Coordinator> bindings_; + + // Registered ProcessLocalDumpManagers. + std::unordered_map<mojom::ProcessLocalDumpManager*, + mojom::ProcessLocalDumpManagerPtr> process_managers_; + + // Pending process managers for RequestGlobalMemoryDump. + std::set<mojom::ProcessLocalDumpManager*> pending_process_managers_; + int failed_memory_dump_count_; + std::list<QueuedMemoryDumpRequest> queued_memory_dump_requests_; + + base::ThreadChecker thread_checker_; + + DISALLOW_COPY_AND_ASSIGN(CoordinatorImpl); +}; + +} // namespace memory_instrumentation +#endif // SERVICES_MEMORY_INFSTRUMENTATION_COORDINATOR_IMPL_H_
diff --git a/services/memory_instrumentation/coordinator_impl_unittest.cc b/services/memory_instrumentation/coordinator_impl_unittest.cc new file mode 100644 index 0000000..5b91a2b --- /dev/null +++ b/services/memory_instrumentation/coordinator_impl_unittest.cc
@@ -0,0 +1,146 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/bind_helpers.h" +#include "base/callback_forward.h" +#include "base/memory/ref_counted.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/trace_event/memory_dump_request_args.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "services/memory_instrumentation/coordinator_impl.h" +#include "services/memory_instrumentation/public/interfaces/memory_instrumentation.mojom.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace memory_instrumentation { + +class CoordinatorImplTest : public testing::Test { + public: + CoordinatorImplTest() { } + void SetUp() override { + dump_response_args_ = {static_cast<uint64_t>(-1), false}; + } + + void RegisterProcessLocalDumpManager( + mojom::ProcessLocalDumpManagerPtr process_manager) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind(&CoordinatorImpl::RegisterProcessLocalDumpManager, + base::Unretained(&coordinator_), + base::Passed(&process_manager))); + } + + void RequestGlobalMemoryDump(base::trace_event::MemoryDumpRequestArgs args, + base::Closure closure) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind( + &CoordinatorImpl::RequestGlobalMemoryDump, + base::Unretained(&coordinator_), + args, + base::Bind(&CoordinatorImplTest::OnGlobalMemoryDumpResponse, + base::Unretained(this), closure))); + } + + void OnGlobalMemoryDumpResponse(base::Closure closure, + uint64_t dump_guid, bool success) { + dump_response_args_ = {dump_guid, success}; + closure.Run(); + } + + protected: + struct DumpResponseArgs { + uint64_t dump_guid; + bool success; + }; + + DumpResponseArgs dump_response_args_; + + private: + CoordinatorImpl coordinator_; + base::MessageLoop message_loop_; +}; + +class MockDumpManager : mojom::ProcessLocalDumpManager { + public: + MockDumpManager(CoordinatorImplTest* test_coordinator, int expected_calls) + : binding_(this), expected_calls_(expected_calls) { + // Register to the coordinator. + mojom::ProcessLocalDumpManagerPtr process_manager; + binding_.Bind(mojo::MakeRequest(&process_manager)); + test_coordinator->RegisterProcessLocalDumpManager( + std::move(process_manager)); + } + + ~MockDumpManager() override { + EXPECT_EQ(0, expected_calls_); + } + + void RequestProcessMemoryDump( + const base::trace_event::MemoryDumpRequestArgs& args, + const RequestProcessMemoryDumpCallback& callback) override { + expected_calls_--; + callback.Run(args.dump_guid, true); + } + + private: + mojo::Binding<mojom::ProcessLocalDumpManager> binding_; + int expected_calls_; +}; + +TEST_F(CoordinatorImplTest, NoProcessLocalManagers) { + base::RunLoop run_loop; + base::trace_event::MemoryDumpRequestArgs args = { + 1234, + base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED, + base::trace_event::MemoryDumpLevelOfDetail::DETAILED}; + RequestGlobalMemoryDump(args, run_loop.QuitClosure()); + run_loop.Run(); + EXPECT_EQ(static_cast<uint64_t>(1234), dump_response_args_.dump_guid); + EXPECT_TRUE(dump_response_args_.success); +} + +TEST_F(CoordinatorImplTest, SeveralProcessLocalManagers) { + base::RunLoop run_loop; + + MockDumpManager dump_manager_1(this, 1); + MockDumpManager dump_manager_2(this, 1); + base::trace_event::MemoryDumpRequestArgs args = { + 2345, + base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED, + base::trace_event::MemoryDumpLevelOfDetail::DETAILED}; + RequestGlobalMemoryDump(args, run_loop.QuitClosure()); + + run_loop.Run(); + + EXPECT_EQ(static_cast<uint64_t>(2345), dump_response_args_.dump_guid); + EXPECT_TRUE(dump_response_args_.success); +} + +TEST_F(CoordinatorImplTest, FaultyProcessLocalManager) { + base::RunLoop run_loop; + + MockDumpManager dump_manager_1(this, 1); + std::unique_ptr<MockDumpManager> dump_manager_2(new MockDumpManager(this, 0)); + base::trace_event::MemoryDumpRequestArgs args = { + 3456, + base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED, + base::trace_event::MemoryDumpLevelOfDetail::DETAILED}; + RequestGlobalMemoryDump(args, run_loop.QuitClosure()); + // One of the process-local managers dies after a global dump is requested and + // before it receives the corresponding process dump request. The coordinator + // should detect that one of its clients is disconnected and claim the global + // dump attempt has failed. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind([](std::unique_ptr<MockDumpManager> dm) { }, + base::Passed(&dump_manager_2))); + + run_loop.Run(); + + EXPECT_EQ(static_cast<uint64_t>(3456), dump_response_args_.dump_guid); + EXPECT_FALSE(dump_response_args_.success); +} +} // namespace memory_instrumentation
diff --git a/services/memory_instrumentation/public/cpp/BUILD.gn b/services/memory_instrumentation/public/cpp/BUILD.gn index 403c247..99a22d62 100644 --- a/services/memory_instrumentation/public/cpp/BUILD.gn +++ b/services/memory_instrumentation/public/cpp/BUILD.gn
@@ -2,13 +2,28 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +source_set("cpp") { + sources = [ + "coordinator.h", + ] + + deps = [ + ":struct_traits", + ] + + public_deps = [ + "//services/memory_instrumentation/public/interfaces", + ] +} + source_set("struct_traits") { sources = [ "memory_instrumentation_traits.cc", "memory_instrumentation_traits.h", ] - deps = [ + public_deps = [ + "//base", "//services/memory_instrumentation/public/interfaces", ] }
diff --git a/services/memory_instrumentation/public/cpp/coordinator.h b/services/memory_instrumentation/public/cpp/coordinator.h new file mode 100644 index 0000000..9c75396d --- /dev/null +++ b/services/memory_instrumentation/public/cpp/coordinator.h
@@ -0,0 +1,20 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_MEMORY_INSTRUMENTATION_PUBLIC_CPP_COORDINATOR_H_ +#define SERVICES_MEMORY_INSTRUMENTATION_PUBLIC_CPP_COORDINATOR_H_ + +#include "services/memory_instrumentation/public/interfaces/memory_instrumentation.mojom.h" + +namespace memory_instrumentation { + +class Coordinator { + public: + // Binds a CoordinatorRequest to this Coordinator instance. + virtual void BindCoordinatorRequest(mojom::CoordinatorRequest) = 0; +}; + +} // namespace memory_instrumentation + +#endif // SERVICES_MEMORY_INSTRUMENTATION_PUBLIC_CPP_COORDINATOR_H_
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 74bff0c5..fa58096 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2409,6 +2409,26 @@ ] } ], + "TranslateRankerLogging": [ + { + "platforms": [ + "android", + "chromeos", + "ios", + "linux", + "mac", + "win" + ], + "experiments": [ + { + "name": "TranslateRankerLogging", + "enable_features": [ + "TranslateRankerLogging" + ] + } + ] + } + ], "TranslateUiLangTrial": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/fast/dom/geometry-interface-dom-quad.html b/third_party/WebKit/LayoutTests/fast/dom/geometry-interface-dom-quad.html index 4ab3e500..7cf3781 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/geometry-interface-dom-quad.html +++ b/third_party/WebKit/LayoutTests/fast/dom/geometry-interface-dom-quad.html
@@ -8,7 +8,7 @@ var p2 = new DOMPoint(5, 6, 7, 8); var p3 = new DOMPoint(9, 10, 11, 12); var p4 = new DOMPoint(13, 14, 15, 16); - var quad = new DOMQuad(p1, p2, p3, p4); + var quad = new DOMQuad(p1, p2, p3, p4); assert_dom_point_equals(quad.p1, p1); assert_dom_point_equals(quad.p2, p2); assert_dom_point_equals(quad.p3, p3); @@ -32,11 +32,38 @@ var expect_p2 = new DOMPoint(90, 20, 0, 1); var expect_p3 = new DOMPoint(90, 70, 0, 1); var expect_p4 = new DOMPoint(10, 70, 0, 1); - var quad = DOMQuad.fromRect({x: 10, y: 20, width: 80, height: 50}); + var quad = DOMQuad.fromRect({x: 10, y: 20, width: 80, height: 50}); assert_dom_point_equals(quad.p1, expect_p1, "p1"); assert_dom_point_equals(quad.p2, expect_p2, "p2"); assert_dom_point_equals(quad.p3, expect_p3, "p3"); assert_dom_point_equals(quad.p4, expect_p4, "p4"); }, "DOMQuad() fromRect"); +test(() => { + var expect_p1 = new DOMPoint(0, 1, 2, 3); + var expect_p2 = new DOMPoint(4, 5, 6, 7); + var expect_p3 = new DOMPoint(8, 9, 10, 11); + var expect_p4 = new DOMPoint(12, 13, 14, 15); + var quad = DOMQuad.fromQuad({p1: {x: 0, y: 1, z: 2, w: 3}, + p2: {x: 4, y: 5, z: 6, w: 7}, + p3: {x: 8, y: 9, z: 10, w: 11}, + p4: {x: 12, y: 13, z: 14, w: 15}}); + assert_dom_point_equals(quad.p1, expect_p1, "p1"); + assert_dom_point_equals(quad.p2, expect_p2, "p2"); + assert_dom_point_equals(quad.p3, expect_p3, "p3"); + assert_dom_point_equals(quad.p4, expect_p4, "p4"); +}, "DOMQuad() fromQuad"); + +test(() => { + var expect_p1 = new DOMPoint(0, 0, 0, 1); + var expect_p2 = new DOMPoint(0, 0, 0, 1); + var expect_p3 = new DOMPoint(0, 0, 0, 1); + var expect_p4 = new DOMPoint(0, 0, 0, 1); + var quad = DOMQuad.fromQuad({}); + assert_dom_point_equals(quad.p1, expect_p1, "p1"); + assert_dom_point_equals(quad.p2, expect_p2, "p2"); + assert_dom_point_equals(quad.p3, expect_p3, "p3"); + assert_dom_point_equals(quad.p4, expect_p4, "p4"); +}, "DOMQuad() fromQuad - parameter of fromQuad function does not have any point."); + </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/debugger-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/debugger-test.js index 5765c5d..3b20845 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/debugger-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/debugger-test.js
@@ -720,14 +720,20 @@ } } -InspectorTest.clickJavaScriptSourceFrameBreakpoint = function(sourceFrame, lineNumber, index) +InspectorTest.clickJavaScriptSourceFrameBreakpoint = function(sourceFrame, lineNumber, index, next) { var textEditor = sourceFrame._textEditor; var lineLength = textEditor.line(lineNumber).length; var lineRange = new Common.TextRange(lineNumber, 0, lineNumber, lineLength); var bookmarks = textEditor.bookmarks(lineRange, Sources.JavaScriptSourceFrame.BreakpointDecoration._bookmarkSymbol); bookmarks.sort((bookmark1, bookmark2) => bookmark1.position().startColumn - bookmark2.position().startColumn); - bookmarks[index][Sources.JavaScriptSourceFrame.BreakpointDecoration._elementSymbolForTest].click(); + var bookmark = bookmarks[index]; + if (bookmark) { + bookmark[Sources.JavaScriptSourceFrame.BreakpointDecoration._elementSymbolForTest].click(); + } else { + InspectorTest.addResult(`Could not click on Javascript breakpoint - lineNumber: ${lineNumber}, index: ${index}`); + next(); + } } };
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-skip-step-in.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-skip-step-in.html index 4d9a96c..1977578 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-skip-step-in.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-skip-step-in.html
@@ -37,7 +37,7 @@ function test4() { debugger; - Framework.safeRun(Framework.doSomeWork, callback); // Should NOT step into callback (otherwise too many StepIns) + Framework.safeRun(Framework.doSomeWork, callback); // Should step into callback } function test5()
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger/source-frame-inline-breakpoint-decorations.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger/source-frame-inline-breakpoint-decorations.html index ed16e80..0ec8830 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger/source-frame-inline-breakpoint-decorations.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger/source-frame-inline-breakpoint-decorations.html
@@ -84,21 +84,21 @@ { InspectorTest.addResult("Click by second breakpoint"); waitAndDumpDecorations(javaScriptSourceFrame).then(clickByFirstLocation); - InspectorTest.clickJavaScriptSourceFrameBreakpoint(javaScriptSourceFrame, 3, 1); + InspectorTest.clickJavaScriptSourceFrameBreakpoint(javaScriptSourceFrame, 3, 1, next); } function clickByFirstLocation() { InspectorTest.addResult("Click by first breakpoint"); waitAndDumpDecorations(javaScriptSourceFrame).then(clickBySecondLocationAgain); - InspectorTest.clickJavaScriptSourceFrameBreakpoint(javaScriptSourceFrame, 3, 0); + InspectorTest.clickJavaScriptSourceFrameBreakpoint(javaScriptSourceFrame, 3, 0, next); } function clickBySecondLocationAgain() { InspectorTest.addResult("Click by second breakpoint"); waitAndDumpDecorations(javaScriptSourceFrame).then(() => next()); - InspectorTest.clickJavaScriptSourceFrameBreakpoint(javaScriptSourceFrame, 3, 1); + InspectorTest.clickJavaScriptSourceFrameBreakpoint(javaScriptSourceFrame, 3, 1, next); } }, @@ -126,8 +126,8 @@ { InspectorTest.addResult("Click by first inline breakpoints"); waitAndDumpDecorations(javaScriptSourceFrame).then(() => next()); - InspectorTest.clickJavaScriptSourceFrameBreakpoint(javaScriptSourceFrame, 3, 0); - InspectorTest.clickJavaScriptSourceFrameBreakpoint(javaScriptSourceFrame, 4, 0); + InspectorTest.clickJavaScriptSourceFrameBreakpoint(javaScriptSourceFrame, 3, 0, next); + InspectorTest.clickJavaScriptSourceFrameBreakpoint(javaScriptSourceFrame, 4, 0, next); } } ]);
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-all-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-all-expected.png index 6fbb50ed..54e582a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-expected.png index 6c8fc95..1874913 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-out-of-flow-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-out-of-flow-expected.png index 793575f..63653af 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-out-of-flow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-out-of-flow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-all-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-all-expected.png index 124028a..a0faa0a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-expected.png index f54e0391..c26b284 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-out-of-flow-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-out-of-flow-expected.png index 6cd07771..1239886 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-out-of-flow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-out-of-flow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-all-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-all-expected.png index 2d83a31f..d8d1a31 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-expected.png index 2049a2c..45c4260 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-out-of-flow-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-out-of-flow-expected.png index 81cb2e29..766c669 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-out-of-flow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under-out-of-flow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/webaudio/OfflineAudioContext/offlineaudiocontext-suspend-resume-basic-expected.txt b/third_party/WebKit/LayoutTests/webaudio/OfflineAudioContext/offlineaudiocontext-suspend-resume-basic-expected.txt index 446e589..951d2c4 100644 --- a/third_party/WebKit/LayoutTests/webaudio/OfflineAudioContext/offlineaudiocontext-suspend-resume-basic-expected.txt +++ b/third_party/WebKit/LayoutTests/webaudio/OfflineAudioContext/offlineaudiocontext-suspend-resume-basic-expected.txt
@@ -6,8 +6,9 @@ PASS context.suspend() rejected correctly (with TypeError: Failed to execute 'suspend' on 'OfflineAudioContext': 1 argument required, but only 0 present.). PASS context.suspend(-1.0) rejected correctly (with InvalidStateError: negative suspend time (-1) is not allowed). PASS context.suspend(2.0) rejected correctly (with InvalidStateError: cannot schedule a suspend at frame 88192 (2 seconds) because it is greater than or equal to the total render duration of 44100 frames). -PASS Scheduling a suspend in the past rejected correctly (with InvalidStateError: cannot schedule a suspend at frame 17536 (0.399229 seconds) because it is earlier than the current frame of 22016 (0.499229 seconds)). +PASS Scheduling a suspend in the past rejected correctly (with InvalidStateError: suspend(0.399229) failed to suspend at frame 17536 because it is earlier than the current frame of 22016 (0.499229 seconds)). PASS Scheduling a suspend in the future resolved correctly. +PASS Scheduling a suspend after the render completion rejected correctly (with InvalidStateError: suspend(1) failed to suspend at frame 44032 because it is earlier than the current frame of 44100 (1 seconds)). PASS Scheduling a suspend at frame 128 was successful. PASS Scheduling another suspend at the same rendering quantum rejected correctly (with InvalidStateError: cannot schedule more than one suspend at frame 128 (0.00435374 seconds)). PASS Scheduling a suspend at 4.5 seconds.
diff --git a/third_party/WebKit/LayoutTests/webaudio/OfflineAudioContext/offlineaudiocontext-suspend-resume-basic.html b/third_party/WebKit/LayoutTests/webaudio/OfflineAudioContext/offlineaudiocontext-suspend-resume-basic.html index eb1ab235..ba06bce 100644 --- a/third_party/WebKit/LayoutTests/webaudio/OfflineAudioContext/offlineaudiocontext-suspend-resume-basic.html +++ b/third_party/WebKit/LayoutTests/webaudio/OfflineAudioContext/offlineaudiocontext-suspend-resume-basic.html
@@ -49,6 +49,17 @@ context.startRendering().then(done); }); + // Task: suspending after rendering is finished must be rejected with the + // properly clamped frame/time information. + audit.defineTask('suspend-after-render-completion', function (done) { + var context = new OfflineAudioContext( + 1, sampleRate * renderDuration, sampleRate); + context.startRendering().then(function () { + Should('Scheduling a suspend after the render completion', + context.suspend(renderDuration)).beRejected(); + }).then(done); + }); + // Task: Calling multiple suspends at the same rendering quantum should // reject the promise. audit.defineTask('identical-suspend-time', function (done) { @@ -123,6 +134,7 @@ audit.runTasks( 'suspend-invalid-argument', 'suspend-in-the-past', + 'suspend-after-render-completion', 'identical-suspend-time', 'resume-before-suspend', 'resume-without-suspend',
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 1e3472d..50e669f 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -1149,6 +1149,7 @@ method matrixTransform method toJSON interface DOMQuad + static method fromQuad static method fromRect attribute @@toStringTag getter p1
diff --git a/third_party/WebKit/Source/build/scripts/json5_generator.py b/third_party/WebKit/Source/build/scripts/json5_generator.py index 00f4e9a..4c7a63d 100644 --- a/third_party/WebKit/Source/build/scripts/json5_generator.py +++ b/third_party/WebKit/Source/build/scripts/json5_generator.py
@@ -164,14 +164,23 @@ return entry def _validate_parameter(self, parameter, value): - valid_values = parameter.get("valid_values") - if valid_values and value not in valid_values: - raise Exception("Unknown value: '%s'\nKnown values: %s" % - (value, valid_values)) valid_type = parameter.get("valid_type") if valid_type and type(value).__name__ != valid_type: raise Exception("Incorrect type: '%s'\nExpected type: %s" % (type(value).__name__, valid_type)) + valid_values = parameter.get("valid_values") + if not valid_values: + return + # If valid_values is a list of simple items and not list of list, then + # validate each item in the value list against valid_values. + if valid_type == "list" and type(valid_values[0]) is not list: + for item in value: + if item not in valid_values: + raise Exception("Unknown value: '%s'\nKnown values: %s" % + (item, valid_values)) + elif value not in valid_values: + raise Exception("Unknown value: '%s'\nKnown values: %s" % + (value, valid_values)) class Writer(object):
diff --git a/third_party/WebKit/Source/core/dom/DOMQuad.cpp b/third_party/WebKit/Source/core/dom/DOMQuad.cpp index 1b87a219..853e0740 100644 --- a/third_party/WebKit/Source/core/dom/DOMQuad.cpp +++ b/third_party/WebKit/Source/core/dom/DOMQuad.cpp
@@ -6,6 +6,7 @@ #include "bindings/core/v8/V8ObjectBuilder.h" #include "core/dom/DOMPoint.h" +#include "core/dom/DOMQuadInit.h" #include "core/dom/DOMRectInit.h" namespace blink { @@ -21,6 +22,13 @@ return new DOMQuad(other.x(), other.y(), other.width(), other.height()); } +DOMQuad* DOMQuad::fromQuad(const DOMQuadInit& other) { + return new DOMQuad(other.hasP1() ? other.p1() : DOMPointInit(), + other.hasP2() ? other.p2() : DOMPointInit(), + other.hasP3() ? other.p3() : DOMPointInit(), + other.hasP3() ? other.p4() : DOMPointInit()); +} + DOMQuad::DOMQuad(const DOMPointInit& p1, const DOMPointInit& p2, const DOMPointInit& p3,
diff --git a/third_party/WebKit/Source/core/dom/DOMQuad.h b/third_party/WebKit/Source/core/dom/DOMQuad.h index 19ef067..b2219d10 100644 --- a/third_party/WebKit/Source/core/dom/DOMQuad.h +++ b/third_party/WebKit/Source/core/dom/DOMQuad.h
@@ -13,6 +13,7 @@ class DOMPoint; class DOMPointInit; +class DOMQuadInit; class DOMRectInit; class CORE_EXPORT DOMQuad : public GarbageCollected<DOMQuad>, @@ -25,6 +26,7 @@ const DOMPointInit& p3, const DOMPointInit& p4); static DOMQuad* fromRect(const DOMRectInit&); + static DOMQuad* fromQuad(const DOMQuadInit&); DOMPoint* p1() const { return m_p1; } DOMPoint* p2() const { return m_p2; }
diff --git a/third_party/WebKit/Source/core/dom/DOMQuad.idl b/third_party/WebKit/Source/core/dom/DOMQuad.idl index c0729a9e..7c605263 100644 --- a/third_party/WebKit/Source/core/dom/DOMQuad.idl +++ b/third_party/WebKit/Source/core/dom/DOMQuad.idl
@@ -12,7 +12,7 @@ ] interface DOMQuad { [NewObject] static DOMQuad fromRect(optional DOMRectInit other); - // TODO(hs1217.lee): [NewObject] static DOMQuad fromQuad(optional DOMQuadInit other); + [NewObject] static DOMQuad fromQuad(optional DOMQuadInit other); [SameObject] readonly attribute DOMPoint p1; [SameObject] readonly attribute DOMPoint p2;
diff --git a/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp b/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp index 8c70b95..0f183ce 100644 --- a/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp +++ b/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp
@@ -77,42 +77,47 @@ } } -static int computeUnderlineOffset(const ComputedStyle& style, - const FontMetrics& fontMetrics, - const InlineTextBox* inlineTextBox, - const float textDecorationThickness) { +static int computeUnderlineOffsetForRoman(const FontMetrics& fontMetrics, + const float textDecorationThickness) { // Compute the gap between the font and the underline. Use at least one // pixel gap, if underline is thick then use a bigger gap. int gap = 0; // Underline position of zero means draw underline on Baseline Position, // in Blink we need at least 1-pixel gap to adding following check. - // Positive underline Position means underline should be drawn above baselin e + // Positive underline Position means underline should be drawn above baseline // and negative value means drawing below baseline, negating the value as in - // Blink - // downward Y-increases. + // Blink downward Y-increases. if (fontMetrics.underlinePosition()) gap = -fontMetrics.underlinePosition(); else gap = std::max<int>(1, ceilf(textDecorationThickness / 2.f)); + // Position underline near the alphabetic baseline. + return fontMetrics.ascent() + gap; +} + +static int computeUnderlineOffset(const ComputedStyle& style, + const FontMetrics& fontMetrics, + const InlineTextBox* inlineTextBox, + const float textDecorationThickness) { // FIXME: We support only horizontal text for now. switch (style.getTextUnderlinePosition()) { + default: + NOTREACHED(); + // Fall through. case TextUnderlinePositionAuto: - return fontMetrics.ascent() + - gap; // Position underline near the alphabetic baseline. + return computeUnderlineOffsetForRoman(fontMetrics, + textDecorationThickness); case TextUnderlinePositionUnder: { - // Position underline relative to the under edge of the lowest element's + // Position underline at the under edge of the lowest element's // content box. LayoutUnit offset = computeUnderlineOffsetForUnder(style, inlineTextBox); offset = inlineTextBox->logicalHeight() + std::max(offset, LayoutUnit()); - return offset.toInt() + gap; + return offset.toInt(); } } - - NOTREACHED(); - return fontMetrics.ascent() + gap; } static bool shouldSetDecorationAntialias(
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css b/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css index f4b885c..a692caa 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css +++ b/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css
@@ -340,6 +340,7 @@ overflow: auto; position: relative; background-color: #f3f3f3; + -webkit-user-select: text; } .timeline-details-view-body > div {
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-async/async-callstack-in-console-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-async/async-callstack-in-console-expected.txt new file mode 100644 index 0000000..372acb7 --- /dev/null +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-async/async-callstack-in-console-expected.txt
@@ -0,0 +1,62 @@ +CONSOLE MESSAGE: line 11: console.clear +CONSOLE MESSAGE: line 17: console.trace +CONSOLE ERROR: line 24: Uncaught Error: foo +CONSOLE MESSAGE: line 29: console.trace +CONSOLE ERROR: line 37: Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('http://www.example.com') does not match the recipient window's origin (''). +Tests asynchronous call stacks printed in console. + + +Set timer for test function. +async-callstack-in-console.html:11 Console was cleared +async-callstack-in-console.html:17 console.trace + +timeout1 @ async-callstack-in-console.html:17 + +setTimeout (async) + +testFunction @ async-callstack-in-console.html:12 +async-callstack-in-console.html:24 Uncaught Error: foo + at timeout2 (async-callstack-in-console.html:24) + +timeout2 @ async-callstack-in-console.html:24 + +setTimeout (async) + +timeout1 @ async-callstack-in-console.html:18 + +setTimeout (async) + +testFunction @ async-callstack-in-console.html:12 +async-callstack-in-console.html:29 console.trace + +timeout3 @ async-callstack-in-console.html:29 + +setTimeout (async) + +timeout2 @ async-callstack-in-console.html:23 + +setTimeout (async) + +timeout1 @ async-callstack-in-console.html:18 + +setTimeout (async) + +testFunction @ async-callstack-in-console.html:12 +async-callstack-in-console.html:37 Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('http://www.example.com') does not match the recipient window's origin ('file://'). + +tryPostMessage @ async-callstack-in-console.html:37 + +timeout3 @ async-callstack-in-console.html:31 + +setTimeout (async) + +timeout2 @ async-callstack-in-console.html:23 + +setTimeout (async) + +timeout1 @ async-callstack-in-console.html:18 + +setTimeout (async) + +testFunction @ async-callstack-in-console.html:12 +
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-async/async-callstack-promises-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-async/async-callstack-promises-expected.txt new file mode 100644 index 0000000..cf369f6 --- /dev/null +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-async/async-callstack-promises-expected.txt
@@ -0,0 +1,243 @@ +Tests asynchronous call stacks for Promises. + +Set timer for test function. +Captured call stacks in no particular order: +Call stack: + 0) afterJSONStringifyAndParse (async-callstack-promises.html:97) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) doTestChainedPromises (async-callstack-promises.html:93) + 3) testFunctionTimeout (async-callstack-promises.html:50) + [setTimeout] + 0) testFunction (async-callstack-promises.html:43) + [setTimeout] + 0) scheduleTestFunction (debugger-test.js:3) + <... skipped remaining frames ...> + +Call stack: + 0) catchCallback (async-callstack-promises.html:118) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) chained1 (async-callstack-promises.html:110) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) doTestThrowFromChain (async-callstack-promises.html:109) + 3) testFunctionTimeout (async-callstack-promises.html:50) + [setTimeout] + 0) testFunction (async-callstack-promises.html:43) + [setTimeout] + 0) scheduleTestFunction (debugger-test.js:3) + <... skipped remaining frames ...> + +Call stack: + 0) catchCallback (async-callstack-promises.html:130) + [Promise.reject] + 0) rejectPromise (async-callstack-promises.html:16) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:19) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) chained3 (async-callstack-promises.html:126) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) chained2 (async-callstack-promises.html:124) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) chained1 (async-callstack-promises.html:122) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) doTestThrowFromChain (async-callstack-promises.html:121) + 3) testFunctionTimeout (async-callstack-promises.html:50) + +Call stack: + 0) chained1 (async-callstack-promises.html:80) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) doTestChainedPromises (async-callstack-promises.html:79) + 3) testFunctionTimeout (async-callstack-promises.html:50) + [setTimeout] + 0) testFunction (async-callstack-promises.html:43) + [setTimeout] + 0) scheduleTestFunction (debugger-test.js:3) + <... skipped remaining frames ...> + +Call stack: + 0) chained2 (async-callstack-promises.html:83) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) chained1 (async-callstack-promises.html:81) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) doTestChainedPromises (async-callstack-promises.html:79) + 3) testFunctionTimeout (async-callstack-promises.html:50) + [setTimeout] + 0) testFunction (async-callstack-promises.html:43) + [setTimeout] + 0) scheduleTestFunction (debugger-test.js:3) + <... skipped remaining frames ...> + +Call stack: + 0) chained3 (async-callstack-promises.html:86) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) chained1 (async-callstack-promises.html:81) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) doTestChainedPromises (async-callstack-promises.html:79) + 3) testFunctionTimeout (async-callstack-promises.html:50) + [setTimeout] + 0) testFunction (async-callstack-promises.html:43) + [setTimeout] + 0) scheduleTestFunction (debugger-test.js:3) + <... skipped remaining frames ...> + +Call stack: + 0) chained4 (async-callstack-promises.html:89) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) chained1 (async-callstack-promises.html:81) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) doTestChainedPromises (async-callstack-promises.html:79) + 3) testFunctionTimeout (async-callstack-promises.html:50) + [setTimeout] + 0) testFunction (async-callstack-promises.html:43) + [setTimeout] + 0) scheduleTestFunction (debugger-test.js:3) + <... skipped remaining frames ...> + +Call stack: + 0) errorCallback (async-callstack-promises.html:60) + [Promise.reject] + 0) doTestPromiseResolveAndReject (async-callstack-promises.html:137) + 1) testFunctionTimeout (async-callstack-promises.html:50) + [setTimeout] + 0) testFunction (async-callstack-promises.html:43) + [setTimeout] + 0) scheduleTestFunction (debugger-test.js:3) + <... skipped remaining frames ...> + +Call stack: + 0) errorCallback (async-callstack-promises.html:60) + [Promise.reject] + 0) doTestSettledPromises (async-callstack-promises.html:74) + 1) testFunctionTimeout (async-callstack-promises.html:50) + [setTimeout] + 0) testFunction (async-callstack-promises.html:43) + [setTimeout] + 0) scheduleTestFunction (debugger-test.js:3) + <... skipped remaining frames ...> + +Call stack: + 0) promiseCallback (async-callstack-promises.html:67) + 1) doTestPromiseConstructor (async-callstack-promises.html:65) + 2) testFunctionTimeout (async-callstack-promises.html:50) + [setTimeout] + 0) testFunction (async-callstack-promises.html:43) + [setTimeout] + 0) scheduleTestFunction (debugger-test.js:3) + <... skipped remaining frames ...> + +Call stack: + 0) thenCallback (async-callstack-promises.html:55) + [Promise.resolve] + 0) doTestPromiseResolveAndReject (async-callstack-promises.html:136) + 1) testFunctionTimeout (async-callstack-promises.html:50) + [setTimeout] + 0) testFunction (async-callstack-promises.html:43) + [setTimeout] + 0) scheduleTestFunction (debugger-test.js:3) + <... skipped remaining frames ...> + +Call stack: + 0) thenCallback (async-callstack-promises.html:55) + [Promise.resolve] + 0) doTestSettledPromises (async-callstack-promises.html:73) + 1) testFunctionTimeout (async-callstack-promises.html:50) + [setTimeout] + 0) testFunction (async-callstack-promises.html:43) + [setTimeout] + 0) scheduleTestFunction (debugger-test.js:3) + <... skipped remaining frames ...> + +Call stack: + 0) thenCallback (async-callstack-promises.html:55) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) chained4 (async-callstack-promises.html:90) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) chained1 (async-callstack-promises.html:81) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) doTestChainedPromises (async-callstack-promises.html:79) + 3) testFunctionTimeout (async-callstack-promises.html:50) + [setTimeout] + 0) testFunction (async-callstack-promises.html:43) + [setTimeout] + 0) scheduleTestFunction (debugger-test.js:3) + <... skipped remaining frames ...> + +Call stack: + 0) thenCallback (async-callstack-promises.html:55) + [Promise.resolve] + 0) resolvePromise (async-callstack-promises.html:12) + [setTimeout] + 0) promiseCallback (async-callstack-promises.html:21) + 1) timeoutPromise (async-callstack-promises.html:9) + 2) doTestPromiseAll (async-callstack-promises.html:103) + 3) testFunctionTimeout (async-callstack-promises.html:50) + [setTimeout] + 0) testFunction (async-callstack-promises.html:43) + [setTimeout] + 0) scheduleTestFunction (debugger-test.js:3) + <... skipped remaining frames ...> + +
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-breakpoints/nodejs-set-breakpoint-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-breakpoints/nodejs-set-breakpoint-expected.txt index 973ecd3..1d53b06 100644 --- a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-breakpoints/nodejs-set-breakpoint-expected.txt +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-breakpoints/nodejs-set-breakpoint-expected.txt
@@ -2,8 +2,6 @@ Verify that front-end is able to set breakpoint for node.js scripts. Setting breakpoint: -error: Request Debugger.getPossibleBreakpoints failed. {"code":-32601,"message":"'Debugger.getPossibleBreakpoints' wasn't found"} -error: Request Debugger.getPossibleBreakpoints failed. {"code":-32601,"message":"'Debugger.getPossibleBreakpoints' wasn't found"} Script execution paused. Successfully paused on breakpoint Script execution resumed.
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-breakpoints/possible-breakpoints-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-breakpoints/possible-breakpoints-expected.txt new file mode 100644 index 0000000..2c1c2e7 --- /dev/null +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-breakpoints/possible-breakpoints-expected.txt
@@ -0,0 +1,7 @@ +Checks that BreakpointManager.possibleBreakpoints returns correct locations + +Locations for first line +All locations +Existing location by position +Not existing location by position +
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-breakpoints/use-possible-breakpoints-to-resolve-breakpoint-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-breakpoints/use-possible-breakpoints-to-resolve-breakpoint-expected.txt new file mode 100644 index 0000000..005b4ad --- /dev/null +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-breakpoints/use-possible-breakpoints-to-resolve-breakpoint-expected.txt
@@ -0,0 +1,10 @@ +Checks that locations are correctly resolved for gutter click. + +3: breakpointAdded(3, 0) +4: breakpointAdded(4, 0) +5: breakpointAdded(5, 0) +6: breakpointAdded(6, 0) +11: breakpointAdded(11, 0) +12: breakpointAdded(12, 0) +13: breakpointAdded(13, 0) +
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-frameworks/frameworks-skip-step-in-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-frameworks/frameworks-skip-step-in-expected.txt new file mode 100644 index 0000000..e066ecf --- /dev/null +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-frameworks/frameworks-skip-step-in-expected.txt
@@ -0,0 +1,39 @@ + +Tests the skip stack frames feature when stepping. + +Set timer for test function. +Call stack: + 0) test1 (frameworks-skip-step-in.html:23) + 1) testFunction (frameworks-skip-step-in.html:11) + +Call stack: + 0) test2 (frameworks-skip-step-in.html:29) + 1) testFunction (frameworks-skip-step-in.html:11) + +Call stack: + 0) callback (frameworks-skip-step-in.html:16) + * 1) Framework.safeRun (framework.js:8) + * 2) Framework.safeRun (framework.js:10) + 3) test3 (frameworks-skip-step-in.html:34) + 4) testFunction (frameworks-skip-step-in.html:11) + +Call stack: + 0) test4 (frameworks-skip-step-in.html:41) + 1) testFunction (frameworks-skip-step-in.html:11) + +Call stack: + 0) callback (frameworks-skip-step-in.html:16) + * 1) Framework.safeRun (framework.js:8) + * 2) Framework.safeRun (framework.js:13) + * 3) Framework.safeRun (framework.js:10) + 4) test5 (frameworks-skip-step-in.html:46) + 5) testFunction (frameworks-skip-step-in.html:11) + +Call stack: + 0) callback (frameworks-skip-step-in.html:16) + * 1) Framework.safeRun (framework.js:8) + * 2) Framework.safeRun (framework.js:10) + 3) test6 (frameworks-skip-step-in.html:52) + 4) testFunction (frameworks-skip-step-in.html:11) + +
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-frameworks/frameworks-step-into-skips-setTimeout-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-frameworks/frameworks-step-into-skips-setTimeout-expected.txt new file mode 100644 index 0000000..d01eacb --- /dev/null +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-frameworks/frameworks-step-into-skips-setTimeout-expected.txt
@@ -0,0 +1,25 @@ + +Tests that stepping into blackboxed framework will not pause on setTimeout() inside the framework. + +Set timer for test function. +Call stack: + 0) stop (frameworks-step-into-skips-setTimeout.html:25) + 1) callback (frameworks-step-into-skips-setTimeout.html:19) + * 2) Framework_scheduleUntilDone (framework.js:142) + +Executing StepOut... +Call stack: + 0) callback (frameworks-step-into-skips-setTimeout.html:20) + * 1) Framework_scheduleUntilDone (framework.js:142) + +Executing StepInto... +Call stack: + 0) callback (frameworks-step-into-skips-setTimeout.html:21) + * 1) Framework_scheduleUntilDone (framework.js:142) + +Executing StepInto... +Call stack: + 0) callback (frameworks-step-into-skips-setTimeout.html:17) + * 1) Framework_scheduleUntilDone (framework.js:142) + +
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-frameworks/frameworks-steppings-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-frameworks/frameworks-steppings-expected.txt new file mode 100644 index 0000000..8eb5cfc --- /dev/null +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-frameworks/frameworks-steppings-expected.txt
@@ -0,0 +1,136 @@ + +Tests stepping into/over/out with framework black-boxing. + +Set timer for test function. +Call stack: + 0) testFunction (frameworks-steppings.html:10) + +Executing StepInto... +Executing StepInto... +Call stack: + 0) callback1 (frameworks-steppings.html:12) + * 1) Framework.safeRun (framework.js:8) + 2) testFunction (frameworks-steppings.html:11) + +Executing StepInto... +Call stack: + 0) callback2 (frameworks-steppings.html:18) + * 1) Framework.safeRun (framework.js:8) + * 2) Framework.safeRun (framework.js:10) + 3) callback1 (frameworks-steppings.html:12) + * 4) Framework.safeRun (framework.js:8) + 5) testFunction (frameworks-steppings.html:11) + +Executing StepInto... +Call stack: + 0) callback2 (frameworks-steppings.html:19) + * 1) Framework.safeRun (framework.js:8) + * 2) Framework.safeRun (framework.js:10) + 3) callback1 (frameworks-steppings.html:12) + * 4) Framework.safeRun (framework.js:8) + 5) testFunction (frameworks-steppings.html:11) + +Executing StepInto... +Call stack: + 0) callback3 (frameworks-steppings.html:24) + * 1) Framework.safeRun (framework.js:8) + * 2) Framework.safeRun (framework.js:13) + * 3) Framework.safeRun (framework.js:10) + 4) callback2 (frameworks-steppings.html:19) + * 5) Framework.safeRun (framework.js:8) + * 6) Framework.safeRun (framework.js:10) + 7) callback1 (frameworks-steppings.html:12) + * 8) Framework.safeRun (framework.js:8) + 9) testFunction (frameworks-steppings.html:11) + +Executing StepInto... +Executing StepInto... +Executing StepInto... +Executing StepInto... +Call stack: + 0) callback4 (frameworks-steppings.html:32) + * 1) Framework_bound (framework.js:105) + * 2) Framework_bound (framework.js:105) + * 3) Framework_bound (framework.js:105) + * 4) Framework.safeRun (framework.js:8) + 5) callback3 (frameworks-steppings.html:27) + * 6) Framework.safeRun (framework.js:8) + * 7) Framework.safeRun (framework.js:13) + * 8) Framework.safeRun (framework.js:10) + 9) callback2 (frameworks-steppings.html:19) + * 10) Framework.safeRun (framework.js:8) + * 11) Framework.safeRun (framework.js:10) + 12) callback1 (frameworks-steppings.html:12) + * 13) Framework.safeRun (framework.js:8) + 14) testFunction (frameworks-steppings.html:11) + +Executing StepInto... +Call stack: + 0) callback4 (frameworks-steppings.html:36) + * 1) Framework_bound (framework.js:105) + * 2) Framework_bound (framework.js:105) + * 3) Framework_bound (framework.js:105) + * 4) Framework.safeRun (framework.js:8) + 5) callback3 (frameworks-steppings.html:27) + * 6) Framework.safeRun (framework.js:8) + * 7) Framework.safeRun (framework.js:13) + * 8) Framework.safeRun (framework.js:10) + 9) callback2 (frameworks-steppings.html:19) + * 10) Framework.safeRun (framework.js:8) + * 11) Framework.safeRun (framework.js:10) + 12) callback1 (frameworks-steppings.html:12) + * 13) Framework.safeRun (framework.js:8) + 14) testFunction (frameworks-steppings.html:11) + +Executing StepInto... +Executing StepInto... +Call stack: + 0) callback4 (frameworks-steppings.html:40) + * 1) Framework_bound (framework.js:105) + * 2) Framework_bound (framework.js:105) + * 3) Framework_bound (framework.js:105) + * 4) Framework.safeRun (framework.js:8) + 5) callback3 (frameworks-steppings.html:27) + * 6) Framework.safeRun (framework.js:8) + * 7) Framework.safeRun (framework.js:13) + * 8) Framework.safeRun (framework.js:10) + 9) callback2 (frameworks-steppings.html:19) + * 10) Framework.safeRun (framework.js:8) + * 11) Framework.safeRun (framework.js:10) + 12) callback1 (frameworks-steppings.html:12) + * 13) Framework.safeRun (framework.js:8) + 14) testFunction (frameworks-steppings.html:11) + +Executing StepInto... +Call stack: + 0) callback3 (frameworks-steppings.html:28) + * 1) Framework.safeRun (framework.js:8) + * 2) Framework.safeRun (framework.js:13) + * 3) Framework.safeRun (framework.js:10) + 4) callback2 (frameworks-steppings.html:19) + * 5) Framework.safeRun (framework.js:8) + * 6) Framework.safeRun (framework.js:10) + 7) callback1 (frameworks-steppings.html:12) + * 8) Framework.safeRun (framework.js:8) + 9) testFunction (frameworks-steppings.html:11) + +Executing StepOut... +Call stack: + 0) callback2 (frameworks-steppings.html:20) + * 1) Framework.safeRun (framework.js:8) + * 2) Framework.safeRun (framework.js:10) + 3) callback1 (frameworks-steppings.html:12) + * 4) Framework.safeRun (framework.js:8) + 5) testFunction (frameworks-steppings.html:11) + +Executing StepOver... +Call stack: + 0) callback1 (frameworks-steppings.html:13) + * 1) Framework.safeRun (framework.js:8) + 2) testFunction (frameworks-steppings.html:11) + +Executing StepInto... +Call stack: + 0) testFunction (frameworks-steppings.html:14) + +
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-pause/debugger-eval-while-paused-throws-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-pause/debugger-eval-while-paused-throws-expected.txt new file mode 100644 index 0000000..511c1d8 --- /dev/null +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-pause/debugger-eval-while-paused-throws-expected.txt
@@ -0,0 +1,32 @@ +Tests that evaluation in console that throws works fine when script is paused. + +Set timer for test function. +Dumping console messages: + +injectedFunction() +VM:6 Uncaught Error: injectedObj.func + at Object.func (<anonymous>:6:23) + at injectedFunction (<anonymous>:9:28) + at eval (eval at evaluate, <anonymous>:1:1) + at testFunction (test.js:23:5) +func @ VM:6 +injectedFunction @ VM:9 +(anonymous) @ VM:1 +testFunction @ test.js:18 +localObj.func() +test.js:15 Uncaught Error: localObj.func + at Object.func (test.js:20:19) + at eval (eval at evaluate, <anonymous>:1:10) + at testFunction (test.js:23:5) +func @ test.js:15 +(anonymous) @ VM:1 +testFunction @ test.js:18 +globalObj.func() +test.js:6 Uncaught Error: globalObj.func + at Object.func (test.js:11:15) + at eval (eval at evaluate, <anonymous>:1:11) + at testFunction (test.js:23:5) +func @ test.js:6 +(anonymous) @ VM:1 +testFunction @ test.js:18 +
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-ui/debugger-save-to-temp-var-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-ui/debugger-save-to-temp-var-expected.txt new file mode 100644 index 0000000..b642947 --- /dev/null +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-ui/debugger-save-to-temp-var-expected.txt
@@ -0,0 +1,29 @@ +Tests saving objects to temporary variables while paused. + +Set timer for test function. +Number of expressions: 11 +Names [temp3..temp7] are reserved + +temp1 +42 +temp2 +"foo string" +temp8 +NaN +temp9 +Infinity +temp10 +-Infinity +temp11 +-0 +temp12 +[1, 2, NaN, -0, null, undefined] +temp13 +Object {foo: "bar"} +temp14 +[1, 2, 3, 4] +temp15 +function func() {} +temp16 +Error: errr +
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-ui/function-generator-details-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-ui/function-generator-details-expected.txt new file mode 100644 index 0000000..0ad0a51 --- /dev/null +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-ui/function-generator-details-expected.txt
@@ -0,0 +1,72 @@ +Tests that Debugger.getGeneratorObjectDetails command returns correct result. + + +Running: testIterNotStarted +iterNotStarted: type = object, subtype = generator +[[GeneratorStatus]] = suspended +[[GeneratorFunction]] = function* gen() +{ + yield 1; + yield 2; + yield 3; +} +[[GeneratorReceiver]] = Window +lineNumber = 13 +columnNumber = 13 +script is valid: yes + +Running: testIterSuspended +iterSuspended: type = object, subtype = generator +[[GeneratorStatus]] = suspended +[[GeneratorFunction]] = function* gen() +{ + yield 1; + yield 2; + yield 3; +} +[[GeneratorReceiver]] = Window +lineNumber = 15 +columnNumber = 4 +script is valid: yes + +Running: testIterClosed +iterClosed: type = object, subtype = generator +[[GeneratorStatus]] = closed +[[GeneratorFunction]] = function* gen() +{ + yield 1; + yield 2; + yield 3; +} +[[GeneratorReceiver]] = Window +lineNumber = 13 +columnNumber = 13 +script is valid: yes + +Running: testIterObjGenerator +iterObjGenerator: type = object, subtype = generator +[[GeneratorStatus]] = suspended +[[GeneratorFunction]] = function* () + { + yield 11; + yield 12; + yield 13; + } +[[GeneratorReceiver]] = Object +lineNumber = 24 +columnNumber = 8 +script is valid: yes + +Running: testAnonymousGenIter +anonymousGenIter: type = object, subtype = generator +[[GeneratorStatus]] = suspended +[[GeneratorFunction]] = function* () { + yield 21; + yield 22; + yield 23; +} +[[GeneratorReceiver]] = Window +lineNumber = 38 +columnNumber = 4 +script is valid: yes +
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-ui/watch-expressions-preserve-expansion-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-ui/watch-expressions-preserve-expansion-expected.txt new file mode 100644 index 0000000..0794d3d --- /dev/null +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger-ui/watch-expressions-preserve-expansion-expected.txt
@@ -0,0 +1,265 @@ +Test that watch expressions expansion state is restored after update. + +Bug 99304 +Watch expressions added. +expanded foo [object Object] +expanded bar [object Object] +expanded [[Scopes]] [object Object] +expanded 0 [object Object] +expanded a [object Object] +expanded [200 .. 299] +expanded 299 [object Object] +Watch expressions expanded. +globalObject: Object + foo: Object + bar: Object + __proto__: Object + __proto__: Object +windowAlias: Window +array: Array[300] + [0 .. 99] + [100 .. 199] + [200 .. 299] + 200: 200 + 201: 201 + 202: 202 + 203: 203 + 204: 204 + 205: 205 + 206: 206 + 207: 207 + 208: 208 + 209: 209 + 210: 210 + 211: 211 + 212: 212 + 213: 213 + 214: 214 + 215: 215 + 216: 216 + 217: 217 + 218: 218 + 219: 219 + 220: 220 + 221: 221 + 222: 222 + 223: 223 + 224: 224 + 225: 225 + 226: 226 + 227: 227 + 228: 228 + 229: 229 + 230: 230 + 231: 231 + 232: 232 + 233: 233 + 234: 234 + 235: 235 + 236: 236 + 237: 237 + 238: 238 + 239: 239 + 240: 240 + 241: 241 + 242: 242 + 243: 243 + 244: 244 + 245: 245 + 246: 246 + 247: 247 + 248: 248 + 249: 249 + 250: 250 + 251: 251 + 252: 252 + 253: 253 + 254: 254 + 255: 255 + 256: 256 + 257: 257 + 258: 258 + 259: 259 + 260: 260 + 261: 261 + 262: 262 + 263: 263 + 264: 264 + 265: 265 + 266: 266 + 267: 267 + 268: 268 + 269: 269 + 270: 270 + 271: 271 + 272: 272 + 273: 273 + 274: 274 + 275: 275 + 276: 276 + 277: 277 + 278: 278 + 279: 279 + 280: 280 + 281: 281 + 282: 282 + 283: 283 + 284: 284 + 285: 285 + 286: 286 + 287: 287 + 288: 288 + 289: 289 + 290: 290 + 291: 291 + 292: 292 + 293: 293 + 294: 294 + 295: 295 + 296: 296 + 297: 297 + 298: 298 + 299: 299 + length: 300 + __proto__: Array[0] +func: function () {return a + b;} + arguments: null + caller: null + length: 0 + name: + prototype: Object + __proto__: function () {} + [[FunctionLocation]]: Object + [[Scopes]]: Scopes[2] + 0: Closure + a: 10 + b: 100 + 1: Global +Page reloaded. +Watch expressions after page reload: +globalObject: Object + foo: Object + bar: Object + __proto__: Object + __proto__: Object +windowAlias: Window +array: Array[300] + [0 .. 99] + [100 .. 199] + [200 .. 299] + 200: 200 + 201: 201 + 202: 202 + 203: 203 + 204: 204 + 205: 205 + 206: 206 + 207: 207 + 208: 208 + 209: 209 + 210: 210 + 211: 211 + 212: 212 + 213: 213 + 214: 214 + 215: 215 + 216: 216 + 217: 217 + 218: 218 + 219: 219 + 220: 220 + 221: 221 + 222: 222 + 223: 223 + 224: 224 + 225: 225 + 226: 226 + 227: 227 + 228: 228 + 229: 229 + 230: 230 + 231: 231 + 232: 232 + 233: 233 + 234: 234 + 235: 235 + 236: 236 + 237: 237 + 238: 238 + 239: 239 + 240: 240 + 241: 241 + 242: 242 + 243: 243 + 244: 244 + 245: 245 + 246: 246 + 247: 247 + 248: 248 + 249: 249 + 250: 250 + 251: 251 + 252: 252 + 253: 253 + 254: 254 + 255: 255 + 256: 256 + 257: 257 + 258: 258 + 259: 259 + 260: 260 + 261: 261 + 262: 262 + 263: 263 + 264: 264 + 265: 265 + 266: 266 + 267: 267 + 268: 268 + 269: 269 + 270: 270 + 271: 271 + 272: 272 + 273: 273 + 274: 274 + 275: 275 + 276: 276 + 277: 277 + 278: 278 + 279: 279 + 280: 280 + 281: 281 + 282: 282 + 283: 283 + 284: 284 + 285: 285 + 286: 286 + 287: 287 + 288: 288 + 289: 289 + 290: 290 + 291: 291 + 292: 292 + 293: 293 + 294: 294 + 295: 295 + 296: 296 + 297: 297 + 298: 298 + 299: 299 + length: 300 + __proto__: Array[0] +func: function () {return a + b;} + arguments: null + caller: null + length: 0 + name: + prototype: Object + __proto__: function () {} + [[FunctionLocation]]: Object + [[Scopes]]: Scopes[2] + 0: Closure + a: 10 + b: 100 + 1: Global +
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger/debugger-scope-minified-variables-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger/debugger-scope-minified-variables-expected.txt new file mode 100644 index 0000000..9b2573e --- /dev/null +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger/debugger-scope-minified-variables-expected.txt
@@ -0,0 +1,18 @@ +Tests resolving variable names via source maps. + +Set timer for test function. +Script execution paused. + +Scope variables sidebar pane: +Catch + error: "boom!" +Local + longMap: Map + longObject: Object + parameter1: 100 + parameter2: "hello" + this: Window +WindowGlobal + <section collapsed> +Script execution resumed. +
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger/properties-special-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger/properties-special-expected.txt new file mode 100644 index 0000000..ccb6bc58 --- /dev/null +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger/properties-special-expected.txt
@@ -0,0 +1,38 @@ +CONSOLE MESSAGE: line 10: true +CONSOLE MESSAGE: line 11: function (a,b) { return a + b; } +CONSOLE MESSAGE: line 12: function () { [native code] } +CONSOLE MESSAGE: line 13: function* () { yeild [1,2,3] } +Tests how debugger presents special properties of closures, bound functions and object wrappers. + +properties-special.html:10 Boolean + __proto__: Boolean + [[PrimitiveValue]]: true +properties-special.html:11 function anonymous(a,b) + arguments: null + caller: null + length: 2 + name: "" + prototype: Object + __proto__: function () + [[FunctionLocation]]: properties-special.html:11 + [[Scopes]]: Scopes[1] +properties-special.html:12 function bound () + arguments: (...) + caller: (...) + length: 1 + name: "bound " + __proto__: function () + [[TargetFunction]]: function (a,b) + [[BoundThis]]: Object + [[BoundArgs]]: Array[1] +properties-special.html:13 function* anonymous() + arguments: (...) + caller: (...) + length: 0 + name: "" + prototype: Generator + __proto__: GeneratorFunction + [[FunctionLocation]]: properties-special.html:13 + [[IsGenerator]]: true + [[Scopes]]: Scopes[1] +
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger/rethrow-error-from-bindings-crash-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger/rethrow-error-from-bindings-crash-expected.txt new file mode 100644 index 0000000..9e8fd33 --- /dev/null +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger/rethrow-error-from-bindings-crash-expected.txt
@@ -0,0 +1,40 @@ +CONSOLE MESSAGE: line 11: console.clear +CONSOLE ERROR: line 25: Uncaught TypeError: Failed to execute 'compareBoundaryPoints' on 'Range': parameter 2 is not of type 'Range'. +CONSOLE ERROR: line 20: Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. +CONSOLE ERROR: line 25: Uncaught TypeError: Failed to execute 'compareBoundaryPoints' on 'Range': parameter 2 is not of type 'Range'. +CONSOLE ERROR: line 20: Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. +CONSOLE ERROR: line 25: Uncaught TypeError: Failed to execute 'compareBoundaryPoints' on 'Range': parameter 2 is not of type 'Range'. +CONSOLE ERROR: line 20: Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. +CONSOLE ERROR: line 25: Uncaught TypeError: Failed to execute 'compareBoundaryPoints' on 'Range': parameter 2 is not of type 'Range'. +CONSOLE ERROR: line 20: Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. +Tests that pausing on uncaught exceptions thrown from C++ bindings will not crash. + +Set timer for test function. +rethrow-error-from-bindings-crash.html:11 Console was cleared +rethrow-error-from-bindings-crash.html:25 Uncaught TypeError: Failed to execute 'compareBoundaryPoints' on 'Range': parameter 2 is not of type 'Range'. + at f2 (rethrow-error-from-bindings-crash.html:25) + at testFunction (rethrow-error-from-bindings-crash.html:15) +f2 @ rethrow-error-from-bindings-crash.html:25 +testFunction @ rethrow-error-from-bindings-crash.html:15 +rethrow-error-from-bindings-crash.html:20 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. + at f1 (rethrow-error-from-bindings-crash.html:20) +f1 @ rethrow-error-from-bindings-crash.html:20 +rethrow-error-from-bindings-crash.html:25 Uncaught TypeError: Failed to execute 'compareBoundaryPoints' on 'Range': parameter 2 is not of type 'Range'. + at f2 (rethrow-error-from-bindings-crash.html:25) +f2 @ rethrow-error-from-bindings-crash.html:25 +rethrow-error-from-bindings-crash.html:20 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. + at f1 (rethrow-error-from-bindings-crash.html:20) +f1 @ rethrow-error-from-bindings-crash.html:20 +rethrow-error-from-bindings-crash.html:25 Uncaught TypeError: Failed to execute 'compareBoundaryPoints' on 'Range': parameter 2 is not of type 'Range'. + at f2 (rethrow-error-from-bindings-crash.html:25) +f2 @ rethrow-error-from-bindings-crash.html:25 +rethrow-error-from-bindings-crash.html:20 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. + at f1 (rethrow-error-from-bindings-crash.html:20) +f1 @ rethrow-error-from-bindings-crash.html:20 +rethrow-error-from-bindings-crash.html:25 Uncaught TypeError: Failed to execute 'compareBoundaryPoints' on 'Range': parameter 2 is not of type 'Range'. + at f2 (rethrow-error-from-bindings-crash.html:25) +f2 @ rethrow-error-from-bindings-crash.html:25 +rethrow-error-from-bindings-crash.html:20 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. + at f1 (rethrow-error-from-bindings-crash.html:20) +f1 @ rethrow-error-from-bindings-crash.html:20 +
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger/source-frame-breakpoint-decorations-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger/source-frame-breakpoint-decorations-expected.txt new file mode 100644 index 0000000..42bc8e4 --- /dev/null +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger/source-frame-breakpoint-decorations-expected.txt
@@ -0,0 +1,38 @@ +Checks that JavaScriptSourceFrame show breakpoints correctly + + +Running: testAddRemoveBreakpoint +Setting breakpoint +breakpoint at 2 +Toggle breakpoint + +Running: testTwoBreakpointsResolvedInOneLine +Setting breakpoint +breakpoint at 2 +Toggle breakpoint + +Running: testDecorationInGutter +Adding regular disabled breakpoint +breakpoint at 2 disabled +Adding conditional disabled breakpoint +breakpoint at 0 disabled conditional +breakpoint at 2 disabled +Adding regular enabled breakpoint +breakpoint at 2 + inline breakpoint at (2, 0) disabled + inline breakpoint at (2, 4) +Adding conditional enabled breakpoint +breakpoint at 2 + inline breakpoint at (2, 0) disabled + inline breakpoint at (2, 4) +Disable breakpoints +breakpoint at 0 disabled +breakpoint at 2 disabled + inline breakpoint at (2, 0) disabled + inline breakpoint at (2, 4) disabled +Enable breakpoints +breakpoint at 0 disabled +breakpoint at 2 +Remove breakpoints +breakpoint at 0 disabled +
diff --git a/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger/source-frame-inline-breakpoint-decorations-expected.txt b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger/source-frame-inline-breakpoint-decorations-expected.txt new file mode 100644 index 0000000..87b24e6 --- /dev/null +++ b/third_party/WebKit/Source/devtools/tests/baseline/protocol-1.2/inspector/sources/debugger/source-frame-inline-breakpoint-decorations-expected.txt
@@ -0,0 +1,27 @@ +Checks that JavaScriptSourceFrame show inline breakpoints correctly + + +Running: testAddRemoveBreakpoint +Setting breakpoint +breakpoint at 4 +Toggle breakpoint +breakpoint at 4 + +Running: testAddRemoveBreakpointInLineWithOneLocation +Setting breakpoint +breakpoint at 4 +breakpoint at 5 +Toggle breakpoint +breakpoint at 4 + +Running: clickByInlineBreakpoint +Setting breakpoint +breakpoint at 4 +Click by second breakpoint +Could not click on Javascript breakpoint - lineNumber: 3, index: 1 + +Running: toggleBreakpointInAnotherLineWontRemoveExisting +Setting breakpoint in line 4 +Click by first breakpoint +Could not click on Javascript breakpoint - lineNumber: 3, index: 0 +
diff --git a/third_party/WebKit/Source/modules/webaudio/OfflineAudioContext.cpp b/third_party/WebKit/Source/modules/webaudio/OfflineAudioContext.cpp index b841030..39e70ed 100644 --- a/third_party/WebKit/Source/modules/webaudio/OfflineAudioContext.cpp +++ b/third_party/WebKit/Source/modules/webaudio/OfflineAudioContext.cpp
@@ -257,13 +257,15 @@ // The specified suspend time is in the past; reject the promise. if (frame < currentSampleFrame()) { + size_t currentFrameClamped = std::min(currentSampleFrame(), length()); + double currentTimeClamped = + std::min(currentTime(), length() / static_cast<double>(sampleRate())); resolver->reject(DOMException::create( InvalidStateError, - "cannot schedule a suspend at frame " + String::number(frame) + " (" + - String::number(when) + - " seconds) because it is earlier than the current frame of " + - String::number(currentSampleFrame()) + " (" + - String::number(currentTime()) + " seconds)")); + "suspend(" + String::number(when) + ") failed to suspend at frame " + + String::number(frame) + " because it is earlier than the current " + + "frame of " + String::number(currentFrameClamped) + " (" + + String::number(currentTimeClamped) + " seconds)")); return promise; }
diff --git a/third_party/WebKit/Source/modules/webaudio/OfflineAudioContext.h b/third_party/WebKit/Source/modules/webaudio/OfflineAudioContext.h index aaf705a..3499829 100644 --- a/third_party/WebKit/Source/modules/webaudio/OfflineAudioContext.h +++ b/third_party/WebKit/Source/modules/webaudio/OfflineAudioContext.h
@@ -49,7 +49,7 @@ DECLARE_VIRTUAL_TRACE(); - unsigned length() const { return m_totalRenderFrames; } + size_t length() const { return m_totalRenderFrames; } ScriptPromise startOfflineRendering(ScriptState*);
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ScrollPaintPropertyNode.cpp b/third_party/WebKit/Source/platform/graphics/paint/ScrollPaintPropertyNode.cpp index 24afc52f..fe601869 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/ScrollPaintPropertyNode.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/ScrollPaintPropertyNode.cpp
@@ -27,7 +27,7 @@ text.append(" userScrollable="); if (m_userScrollableHorizontal && m_userScrollableVertical) text.append("both"); - else if (!m_userScrollableHorizontal && !m_userScrollableHorizontal) + else if (!m_userScrollableHorizontal && !m_userScrollableVertical) text.append("none"); else text.append(m_userScrollableHorizontal ? "horizontal" : "vertical");
diff --git a/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp b/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp index 85f01cb..43055af 100644 --- a/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp +++ b/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp
@@ -38,6 +38,7 @@ #include "platform/geometry/IntPoint.h" #include "platform/geometry/IntRect.h" #include "platform/graphics/GraphicsLayer.h" +#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" #include "platform/testing/URLTestHelpers.h" #include "public/platform/Platform.h" #include "public/platform/WebLayer.h" @@ -54,9 +55,13 @@ namespace blink { -class ScrollingCoordinatorTest : public testing::Test { +class ScrollingCoordinatorTest : public testing::Test, + public testing::WithParamInterface<bool>, + private ScopedRootLayerScrollingForTest { public: - ScrollingCoordinatorTest() : m_baseURL("http://www.test.com/") { + ScrollingCoordinatorTest() + : ScopedRootLayerScrollingForTest(GetParam()), + m_baseURL("http://www.test.com/") { m_helper.initialize(true, nullptr, &m_mockWebViewClient, nullptr, &configureSettings); webViewImpl()->resize(IntSize(320, 240)); @@ -84,6 +89,11 @@ FrameTestHelpers::loadFrame(webViewImpl()->mainFrame(), url); } + void loadHTML(const std::string& html) { + FrameTestHelpers::loadHTMLString(webViewImpl()->mainFrame(), html, + URLTestHelpers::toKURL("about:blank")); + } + void forceFullCompositingUpdate() { webViewImpl()->updateAllLifecyclePhases(); } @@ -95,13 +105,9 @@ } WebLayer* getRootScrollLayer() { - PaintLayerCompositor* compositor = - frame()->contentLayoutItem().compositor(); - DCHECK(compositor); - DCHECK(compositor->scrollLayer()); - - WebLayer* webScrollLayer = compositor->scrollLayer()->platformLayer(); - return webScrollLayer; + GraphicsLayer* layer = + frame()->view()->layoutViewportScrollableArea()->layerForScrolling(); + return layer ? layer->platformLayer() : nullptr; } WebViewImpl* webViewImpl() const { return m_helper.webView(); } @@ -113,9 +119,6 @@ return webViewImpl()->layerTreeView(); } - void styleRelatedMainThreadScrollingReasonTest(const std::string&, - const uint32_t); - protected: std::string m_baseURL; FrameTestHelpers::TestWebViewClient m_mockWebViewClient; @@ -130,8 +133,11 @@ FrameTestHelpers::WebViewHelper m_helper; }; -TEST_F(ScrollingCoordinatorTest, fastScrollingByDefault) { - navigateTo("about:blank"); +INSTANTIATE_TEST_CASE_P(All, ScrollingCoordinatorTest, ::testing::Bool()); + +TEST_P(ScrollingCoordinatorTest, fastScrollingByDefault) { + webViewImpl()->resize(WebSize(800, 600)); + loadHTML("<div id='spacer' style='height: 1000px'></div>"); forceFullCompositingUpdate(); // Make sure the scrolling coordinator is active. @@ -143,6 +149,7 @@ // Fast scrolling should be enabled by default. WebLayer* rootScrollLayer = getRootScrollLayer(); + ASSERT_TRUE(rootScrollLayer); ASSERT_TRUE(rootScrollLayer->scrollable()); ASSERT_FALSE(rootScrollLayer->shouldScrollOnMainThread()); ASSERT_EQ(WebEventListenerProperties::Nothing, @@ -158,8 +165,9 @@ ASSERT_FALSE(innerViewportScrollLayer->shouldScrollOnMainThread()); } -TEST_F(ScrollingCoordinatorTest, fastScrollingCanBeDisabledWithSetting) { - navigateTo("about:blank"); +TEST_P(ScrollingCoordinatorTest, fastScrollingCanBeDisabledWithSetting) { + webViewImpl()->resize(WebSize(800, 600)); + loadHTML("<div id='spacer' style='height: 1000px'></div>"); webViewImpl()->settings()->setThreadedScrollingEnabled(false); forceFullCompositingUpdate(); @@ -172,6 +180,7 @@ // Main scrolling should be enabled with the setting override. WebLayer* rootScrollLayer = getRootScrollLayer(); + ASSERT_TRUE(rootScrollLayer); ASSERT_TRUE(rootScrollLayer->scrollable()); ASSERT_TRUE(rootScrollLayer->shouldScrollOnMainThread()); @@ -182,7 +191,7 @@ ASSERT_TRUE(innerViewportScrollLayer->shouldScrollOnMainThread()); } -TEST_F(ScrollingCoordinatorTest, fastFractionalScrollingDiv) { +TEST_P(ScrollingCoordinatorTest, fastFractionalScrollingDiv) { bool origFractionalOffsetsEnabled = RuntimeEnabledFeatures::fractionalScrollOffsetsEnabled(); RuntimeEnabledFeatures::setFractionalScrollOffsetsEnabled(true); @@ -242,13 +251,14 @@ return graphicsLayer->platformLayer(); } -TEST_F(ScrollingCoordinatorTest, fastScrollingForFixedPosition) { +TEST_P(ScrollingCoordinatorTest, fastScrollingForFixedPosition) { registerMockedHttpURLLoad("fixed-position.html"); navigateTo(m_baseURL + "fixed-position.html"); forceFullCompositingUpdate(); // Fixed position should not fall back to main thread scrolling. WebLayer* rootScrollLayer = getRootScrollLayer(); + ASSERT_TRUE(rootScrollLayer); ASSERT_FALSE(rootScrollLayer->shouldScrollOnMainThread()); Document* document = frame()->document(); @@ -334,13 +344,14 @@ } } -TEST_F(ScrollingCoordinatorTest, fastScrollingForStickyPosition) { +TEST_P(ScrollingCoordinatorTest, fastScrollingForStickyPosition) { registerMockedHttpURLLoad("sticky-position.html"); navigateTo(m_baseURL + "sticky-position.html"); forceFullCompositingUpdate(); // Sticky position should not fall back to main thread scrolling. WebLayer* rootScrollLayer = getRootScrollLayer(); + ASSERT_TRUE(rootScrollLayer); EXPECT_FALSE(rootScrollLayer->shouldScrollOnMainThread()); Document* document = frame()->document(); @@ -440,7 +451,7 @@ } } -TEST_F(ScrollingCoordinatorTest, touchEventHandler) { +TEST_P(ScrollingCoordinatorTest, touchEventHandler) { registerMockedHttpURLLoad("touch-event-handler.html"); navigateTo(m_baseURL + "touch-event-handler.html"); forceFullCompositingUpdate(); @@ -450,7 +461,7 @@ WebEventListenerClass::TouchStartOrMove)); } -TEST_F(ScrollingCoordinatorTest, touchEventHandlerPassive) { +TEST_P(ScrollingCoordinatorTest, touchEventHandlerPassive) { registerMockedHttpURLLoad("touch-event-handler-passive.html"); navigateTo(m_baseURL + "touch-event-handler-passive.html"); forceFullCompositingUpdate(); @@ -460,7 +471,7 @@ WebEventListenerClass::TouchStartOrMove)); } -TEST_F(ScrollingCoordinatorTest, touchEventHandlerBoth) { +TEST_P(ScrollingCoordinatorTest, touchEventHandlerBoth) { registerMockedHttpURLLoad("touch-event-handler-both.html"); navigateTo(m_baseURL + "touch-event-handler-both.html"); forceFullCompositingUpdate(); @@ -470,7 +481,7 @@ WebEventListenerClass::TouchStartOrMove)); } -TEST_F(ScrollingCoordinatorTest, wheelEventHandler) { +TEST_P(ScrollingCoordinatorTest, wheelEventHandler) { registerMockedHttpURLLoad("wheel-event-handler.html"); navigateTo(m_baseURL + "wheel-event-handler.html"); forceFullCompositingUpdate(); @@ -480,7 +491,7 @@ WebEventListenerClass::MouseWheel)); } -TEST_F(ScrollingCoordinatorTest, wheelEventHandlerPassive) { +TEST_P(ScrollingCoordinatorTest, wheelEventHandlerPassive) { registerMockedHttpURLLoad("wheel-event-handler-passive.html"); navigateTo(m_baseURL + "wheel-event-handler-passive.html"); forceFullCompositingUpdate(); @@ -490,7 +501,7 @@ WebEventListenerClass::MouseWheel)); } -TEST_F(ScrollingCoordinatorTest, wheelEventHandlerBoth) { +TEST_P(ScrollingCoordinatorTest, wheelEventHandlerBoth) { registerMockedHttpURLLoad("wheel-event-handler-both.html"); navigateTo(m_baseURL + "wheel-event-handler-both.html"); forceFullCompositingUpdate(); @@ -500,7 +511,7 @@ WebEventListenerClass::MouseWheel)); } -TEST_F(ScrollingCoordinatorTest, scrollEventHandler) { +TEST_P(ScrollingCoordinatorTest, scrollEventHandler) { registerMockedHttpURLLoad("scroll-event-handler.html"); navigateTo(m_baseURL + "scroll-event-handler.html"); forceFullCompositingUpdate(); @@ -508,7 +519,7 @@ ASSERT_TRUE(webLayerTreeView()->haveScrollEventHandlers()); } -TEST_F(ScrollingCoordinatorTest, updateEventHandlersDuringTeardown) { +TEST_P(ScrollingCoordinatorTest, updateEventHandlersDuringTeardown) { registerMockedHttpURLLoad("scroll-event-handler-window.html"); navigateTo(m_baseURL + "scroll-event-handler-window.html"); forceFullCompositingUpdate(); @@ -518,16 +529,17 @@ frame()->document()->shutdown(); } -TEST_F(ScrollingCoordinatorTest, clippedBodyTest) { +TEST_P(ScrollingCoordinatorTest, clippedBodyTest) { registerMockedHttpURLLoad("clipped-body.html"); navigateTo(m_baseURL + "clipped-body.html"); forceFullCompositingUpdate(); WebLayer* rootScrollLayer = getRootScrollLayer(); + ASSERT_TRUE(rootScrollLayer); ASSERT_EQ(0u, rootScrollLayer->nonFastScrollableRegion().size()); } -TEST_F(ScrollingCoordinatorTest, overflowScrolling) { +TEST_P(ScrollingCoordinatorTest, overflowScrolling) { registerMockedHttpURLLoad("overflow-scrolling.html"); navigateTo(m_baseURL + "overflow-scrolling.html"); forceFullCompositingUpdate(); @@ -573,7 +585,7 @@ #endif } -TEST_F(ScrollingCoordinatorTest, overflowHidden) { +TEST_P(ScrollingCoordinatorTest, overflowHidden) { registerMockedHttpURLLoad("overflow-hidden.html"); navigateTo(m_baseURL + "overflow-hidden.html"); forceFullCompositingUpdate(); @@ -634,7 +646,7 @@ ASSERT_TRUE(webScrollLayer->userScrollableVertical()); } -TEST_F(ScrollingCoordinatorTest, iframeScrolling) { +TEST_P(ScrollingCoordinatorTest, iframeScrolling) { registerMockedHttpURLLoad("iframe-scrolling.html"); registerMockedHttpURLLoad("iframe-scrolling-inner.html"); navigateTo(m_baseURL + "iframe-scrolling.html"); @@ -660,10 +672,12 @@ PaintLayerCompositor* innerCompositor = innerLayoutViewItem.compositor(); ASSERT_TRUE(innerCompositor->inCompositingMode()); - ASSERT_TRUE(innerCompositor->scrollLayer()); - GraphicsLayer* scrollLayer = innerCompositor->scrollLayer(); - ASSERT_EQ(innerFrameView, scrollLayer->getScrollableArea()); + GraphicsLayer* scrollLayer = + innerFrameView->layoutViewportScrollableArea()->layerForScrolling(); + ASSERT_TRUE(scrollLayer); + ASSERT_EQ(innerFrameView->layoutViewportScrollableArea(), + scrollLayer->getScrollableArea()); WebLayer* webScrollLayer = scrollLayer->platformLayer(); ASSERT_TRUE(webScrollLayer->scrollable()); @@ -678,7 +692,7 @@ #endif } -TEST_F(ScrollingCoordinatorTest, rtlIframe) { +TEST_P(ScrollingCoordinatorTest, rtlIframe) { registerMockedHttpURLLoad("rtl-iframe.html"); registerMockedHttpURLLoad("rtl-iframe-inner.html"); navigateTo(m_baseURL + "rtl-iframe.html"); @@ -704,21 +718,26 @@ PaintLayerCompositor* innerCompositor = innerLayoutViewItem.compositor(); ASSERT_TRUE(innerCompositor->inCompositingMode()); - ASSERT_TRUE(innerCompositor->scrollLayer()); - GraphicsLayer* scrollLayer = innerCompositor->scrollLayer(); - ASSERT_EQ(innerFrameView, scrollLayer->getScrollableArea()); + GraphicsLayer* scrollLayer = + innerFrameView->layoutViewportScrollableArea()->layerForScrolling(); + ASSERT_TRUE(scrollLayer); + ASSERT_EQ(innerFrameView->layoutViewportScrollableArea(), + scrollLayer->getScrollableArea()); WebLayer* webScrollLayer = scrollLayer->platformLayer(); ASSERT_TRUE(webScrollLayer->scrollable()); int expectedScrollPosition = - 958 + - (innerFrameView->verticalScrollbar()->isOverlayScrollbar() ? 0 : 15); + 958 + (innerFrameView->layoutViewportScrollableArea() + ->verticalScrollbar() + ->isOverlayScrollbar() + ? 0 + : 15); ASSERT_EQ(expectedScrollPosition, webScrollLayer->scrollPositionDouble().x); } -TEST_F(ScrollingCoordinatorTest, setupScrollbarLayerShouldNotCrash) { +TEST_P(ScrollingCoordinatorTest, setupScrollbarLayerShouldNotCrash) { registerMockedHttpURLLoad("setup_scrollbar_layer_crash.html"); navigateTo(m_baseURL + "setup_scrollbar_layer_crash.html"); forceFullCompositingUpdate(); @@ -726,7 +745,7 @@ // an empty document by javascript. } -TEST_F(ScrollingCoordinatorTest, +TEST_P(ScrollingCoordinatorTest, scrollbarsForceMainThreadOrHaveWebScrollbarLayer) { registerMockedHttpURLLoad("trivial-scroller.html"); navigateTo(m_baseURL + "trivial-scroller.html"); @@ -753,10 +772,10 @@ } #if OS(MACOSX) || OS(ANDROID) -TEST_F(ScrollingCoordinatorTest, +TEST_P(ScrollingCoordinatorTest, DISABLED_setupScrollbarLayerShouldSetScrollLayerOpaque) #else -TEST_F(ScrollingCoordinatorTest, setupScrollbarLayerShouldSetScrollLayerOpaque) +TEST_P(ScrollingCoordinatorTest, setupScrollbarLayerShouldSetScrollLayerOpaque) #endif { registerMockedHttpURLLoad("wide_document.html"); @@ -767,7 +786,7 @@ ASSERT_TRUE(frameView); GraphicsLayer* scrollbarGraphicsLayer = - frameView->layerForHorizontalScrollbar(); + frameView->layoutViewportScrollableArea()->layerForHorizontalScrollbar(); ASSERT_TRUE(scrollbarGraphicsLayer); WebLayer* platformLayer = scrollbarGraphicsLayer->platformLayer(); @@ -782,19 +801,16 @@ ASSERT_EQ(platformLayer->opaque(), contentsLayer->opaque()); } -TEST_F(ScrollingCoordinatorTest, +TEST_P(ScrollingCoordinatorTest, FixedPositionLosingBackingShouldTriggerMainThreadScroll) { webViewImpl()->settings()->setPreferCompositingToLCDTextEnabled(false); registerMockedHttpURLLoad("fixed-position-losing-backing.html"); navigateTo(m_baseURL + "fixed-position-losing-backing.html"); forceFullCompositingUpdate(); - WebLayer* scrollLayer = frame() - ->page() - ->deprecatedLocalMainFrame() - ->view() - ->layerForScrolling() - ->platformLayer(); + WebLayer* scrollLayer = getRootScrollLayer(); + ASSERT_TRUE(scrollLayer); + Document* document = frame()->document(); Element* fixedPos = document->getElementById("fixed"); @@ -812,7 +828,7 @@ EXPECT_TRUE(scrollLayer->shouldScrollOnMainThread()); } -TEST_F(ScrollingCoordinatorTest, CustomScrollbarShouldTriggerMainThreadScroll) { +TEST_P(ScrollingCoordinatorTest, CustomScrollbarShouldTriggerMainThreadScroll) { webViewImpl()->settings()->setPreferCompositingToLCDTextEnabled(true); webViewImpl()->setDeviceScaleFactor(2.f); registerMockedHttpURLLoad("custom_scrollbar.html"); @@ -853,7 +869,7 @@ MainThreadScrollingReason::kCustomScrollbarScrolling); } -TEST_F(ScrollingCoordinatorTest, +TEST_P(ScrollingCoordinatorTest, BackgroundAttachmentFixedShouldTriggerMainThreadScroll) { registerMockedHttpURLLoad("iframe-background-attachment-fixed.html"); registerMockedHttpURLLoad("iframe-background-attachment-fixed-inner.html"); @@ -879,10 +895,12 @@ PaintLayerCompositor* innerCompositor = innerLayoutViewItem.compositor(); ASSERT_TRUE(innerCompositor->inCompositingMode()); - ASSERT_TRUE(innerCompositor->scrollLayer()); - GraphicsLayer* scrollLayer = innerCompositor->scrollLayer(); - ASSERT_EQ(innerFrameView, scrollLayer->getScrollableArea()); + GraphicsLayer* scrollLayer = + innerFrameView->layoutViewportScrollableArea()->layerForScrolling(); + ASSERT_TRUE(scrollLayer); + ASSERT_EQ(innerFrameView->layoutViewportScrollableArea(), + scrollLayer->getScrollableArea()); WebLayer* webScrollLayer = scrollLayer->platformLayer(); ASSERT_TRUE(webScrollLayer->scrollable()); @@ -901,7 +919,9 @@ layoutObject = iframe->layoutObject(); ASSERT_TRUE(layoutObject); - scrollLayer = layoutObject->frameView()->layerForScrolling(); + scrollLayer = layoutObject->frameView() + ->layoutViewportScrollableArea() + ->layerForScrolling(); ASSERT_TRUE(scrollLayer); webScrollLayer = scrollLayer->platformLayer(); @@ -922,7 +942,9 @@ layoutObject = iframe->layoutObject(); ASSERT_TRUE(layoutObject); - scrollLayer = layoutObject->frameView()->layerForScrolling(); + scrollLayer = layoutObject->frameView() + ->layoutViewportScrollableArea() + ->layerForScrolling(); ASSERT_TRUE(scrollLayer); webScrollLayer = scrollLayer->platformLayer(); @@ -933,7 +955,7 @@ // Upon resizing the content size, the main thread scrolling reason // kHasNonLayerViewportConstrainedObject should be updated on all frames -TEST_F(ScrollingCoordinatorTest, +TEST_P(ScrollingCoordinatorTest, RecalculateMainThreadScrollingReasonsUponResize) { webViewImpl()->settings()->setPreferCompositingToLCDTextEnabled(false); registerMockedHttpURLLoad("has-non-layer-viewport-constrained-objects.html"); @@ -947,29 +969,23 @@ LayoutObject* layoutObject = element->layoutObject(); ASSERT_TRUE(layoutObject); - GraphicsLayer* scrollLayer = layoutObject->frameView()->layerForScrolling(); - ASSERT_TRUE(scrollLayer); + GraphicsLayer* scrollLayer = layoutObject->frameView() + ->layoutViewportScrollableArea() + ->layerForScrolling(); + WebLayer* webScrollLayer; - WebLayer* webScrollLayer = scrollLayer->platformLayer(); - ASSERT_TRUE(webScrollLayer->scrollable()); - ASSERT_FALSE( - webScrollLayer->mainThreadScrollingReasons() & - MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); - - Element* iframe = frame()->document()->getElementById("iframe"); - ASSERT_TRUE(iframe); - - layoutObject = iframe->layoutObject(); - ASSERT_TRUE(layoutObject); - - scrollLayer = layoutObject->frameView()->layerForScrolling(); - ASSERT_TRUE(scrollLayer); - - webScrollLayer = scrollLayer->platformLayer(); - ASSERT_TRUE(webScrollLayer->scrollable()); - ASSERT_FALSE( - webScrollLayer->mainThreadScrollingReasons() & - MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); + if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { + // When RLS is enabled, the LayoutView won't have a scrolling contents + // because it does not overflow. + ASSERT_FALSE(scrollLayer); + } else { + ASSERT_TRUE(scrollLayer); + webScrollLayer = scrollLayer->platformLayer(); + ASSERT_TRUE(webScrollLayer->scrollable()); + ASSERT_FALSE( + webScrollLayer->mainThreadScrollingReasons() & + MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); + } // When the div becomes to scrollable it should scroll on main thread element->setAttribute("style", @@ -980,19 +996,9 @@ layoutObject = element->layoutObject(); ASSERT_TRUE(layoutObject); - scrollLayer = layoutObject->frameView()->layerForScrolling(); - ASSERT_TRUE(scrollLayer); - - webScrollLayer = scrollLayer->platformLayer(); - ASSERT_TRUE(webScrollLayer->scrollable()); - ASSERT_TRUE( - webScrollLayer->mainThreadScrollingReasons() & - MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); - - layoutObject = iframe->layoutObject(); - ASSERT_TRUE(layoutObject); - - scrollLayer = layoutObject->frameView()->layerForScrolling(); + scrollLayer = layoutObject->frameView() + ->layoutViewportScrollableArea() + ->layerForScrolling(); ASSERT_TRUE(scrollLayer); webScrollLayer = scrollLayer->platformLayer(); @@ -1010,26 +1016,21 @@ layoutObject = element->layoutObject(); ASSERT_TRUE(layoutObject); - scrollLayer = layoutObject->frameView()->layerForScrolling(); - ASSERT_TRUE(scrollLayer); - - webScrollLayer = scrollLayer->platformLayer(); - ASSERT_TRUE(webScrollLayer->scrollable()); - ASSERT_FALSE( - webScrollLayer->mainThreadScrollingReasons() & - MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); - - layoutObject = iframe->layoutObject(); - ASSERT_TRUE(layoutObject); - - scrollLayer = layoutObject->frameView()->layerForScrolling(); - ASSERT_TRUE(scrollLayer); - - webScrollLayer = scrollLayer->platformLayer(); - ASSERT_TRUE(webScrollLayer->scrollable()); - ASSERT_FALSE( - webScrollLayer->mainThreadScrollingReasons() & - MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); + scrollLayer = layoutObject->frameView() + ->layoutViewportScrollableArea() + ->layerForScrolling(); + if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { + // When RLS is enabled, the LayoutView won't have a scrolling contents + // because it does not overflow. + ASSERT_FALSE(scrollLayer); + } else { + ASSERT_TRUE(scrollLayer); + webScrollLayer = scrollLayer->platformLayer(); + ASSERT_TRUE(webScrollLayer->scrollable()); + ASSERT_FALSE( + webScrollLayer->mainThreadScrollingReasons() & + MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects); + } } class StyleRelatedMainThreadScrollingReasonTest @@ -1092,28 +1093,32 @@ } }; -TEST_F(StyleRelatedMainThreadScrollingReasonTest, TransparentTest) { +INSTANTIATE_TEST_CASE_P(All, + StyleRelatedMainThreadScrollingReasonTest, + ::testing::Bool()); + +TEST_P(StyleRelatedMainThreadScrollingReasonTest, TransparentTest) { testStyle("transparent", MainThreadScrollingReason::kHasOpacityAndLCDText); } -TEST_F(StyleRelatedMainThreadScrollingReasonTest, TransformTest) { +TEST_P(StyleRelatedMainThreadScrollingReasonTest, TransformTest) { testStyle("transform", MainThreadScrollingReason::kHasTransformAndLCDText); } -TEST_F(StyleRelatedMainThreadScrollingReasonTest, BackgroundNotOpaqueTest) { +TEST_P(StyleRelatedMainThreadScrollingReasonTest, BackgroundNotOpaqueTest) { testStyle("background-not-opaque", MainThreadScrollingReason::kBackgroundNotOpaqueInRectAndLCDText); } -TEST_F(StyleRelatedMainThreadScrollingReasonTest, BorderRadiusTest) { +TEST_P(StyleRelatedMainThreadScrollingReasonTest, BorderRadiusTest) { testStyle("border-radius", MainThreadScrollingReason::kHasBorderRadius); } -TEST_F(StyleRelatedMainThreadScrollingReasonTest, ClipTest) { +TEST_P(StyleRelatedMainThreadScrollingReasonTest, ClipTest) { testStyle("clip", MainThreadScrollingReason::kHasClipRelatedProperty); } -TEST_F(StyleRelatedMainThreadScrollingReasonTest, ClipPathTest) { +TEST_P(StyleRelatedMainThreadScrollingReasonTest, ClipPathTest) { uint32_t reason = MainThreadScrollingReason::kHasClipRelatedProperty; webViewImpl()->settings()->setPreferCompositingToLCDTextEnabled(false); Document* document = frame()->document(); @@ -1148,13 +1153,13 @@ ASSERT_FALSE(frameView->mainThreadScrollingReasons() & reason); } -TEST_F(StyleRelatedMainThreadScrollingReasonTest, LCDTextEnabledTest) { +TEST_P(StyleRelatedMainThreadScrollingReasonTest, LCDTextEnabledTest) { testStyle("transparent border-radius", MainThreadScrollingReason::kHasOpacityAndLCDText | MainThreadScrollingReason::kHasBorderRadius); } -TEST_F(StyleRelatedMainThreadScrollingReasonTest, BoxShadowTest) { +TEST_P(StyleRelatedMainThreadScrollingReasonTest, BoxShadowTest) { testStyle("box-shadow", MainThreadScrollingReason::kHasBoxShadowFromNonRootLayer); }
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp index d123a03..bc04711ad 100644 --- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -7761,6 +7761,16 @@ webViewHelper.resize(WebSize(viewportWidth, viewportHeight)); webViewImpl->updateAllLifecyclePhases(); + WebLayer* webScrollLayer = webViewImpl->mainFrameImpl() + ->frame() + ->view() + ->layoutViewportScrollableArea() + ->layerForScrolling() + ->platformLayer(); + ASSERT_TRUE(webScrollLayer->scrollable()); + ASSERT_TRUE(webScrollLayer->userScrollableHorizontal()); + ASSERT_TRUE(webScrollLayer->userScrollableVertical()); + Document* document = webViewImpl->mainFrameImpl()->frame()->document(); UserGestureIndicator gesture(DocumentUserGestureToken::create(document)); Fullscreen::requestFullscreen(*document->documentElement()); @@ -7780,8 +7790,12 @@ Fullscreen::fullscreenElementFrom(*document)); // Verify that the main frame is still scrollable. - WebLayer* webScrollLayer = - webViewImpl->compositor()->scrollLayer()->platformLayer(); + webScrollLayer = webViewImpl->mainFrameImpl() + ->frame() + ->view() + ->layoutViewportScrollableArea() + ->layerForScrolling() + ->platformLayer(); ASSERT_TRUE(webScrollLayer->scrollable()); ASSERT_TRUE(webScrollLayer->userScrollableHorizontal()); ASSERT_TRUE(webScrollLayer->userScrollableVertical());
diff --git a/third_party/WebKit/Source/web/tests/data/has-non-layer-viewport-constrained-objects.html b/third_party/WebKit/Source/web/tests/data/has-non-layer-viewport-constrained-objects.html index 50796f6..f2919be 100644 --- a/third_party/WebKit/Source/web/tests/data/has-non-layer-viewport-constrained-objects.html +++ b/third_party/WebKit/Source/web/tests/data/has-non-layer-viewport-constrained-objects.html
@@ -1,4 +1,2 @@ <div style="position:fixed;">Fixed obj</div> -<div id="scrollable" style="overflow: scroll; height:200px; will-change:transform;"> - <iframe id="iframe"></iframe> -</div> +<div id="scrollable" style="overflow: scroll; height:200px; will-change:transform;"></div>
diff --git a/third_party/WebKit/Source/web/tests/data/iframe-background-attachment-fixed-inner.html b/third_party/WebKit/Source/web/tests/data/iframe-background-attachment-fixed-inner.html index 38843967..5dc4b2d 100644 --- a/third_party/WebKit/Source/web/tests/data/iframe-background-attachment-fixed-inner.html +++ b/third_party/WebKit/Source/web/tests/data/iframe-background-attachment-fixed-inner.html
@@ -3,8 +3,7 @@ .background-attachment-fixed { background-image: url("white-1x1.png"); background-attachment: fixed; - height: 2000px; } </style> -<div id="scrollable" style="will-change:transform;" class="background-attachment-fixed" /> +<div id="scrollable" style="will-change:transform; height: 2000px;" class="background-attachment-fixed" />
diff --git a/tools/chrome_proxy/webdriver/bypass.py b/tools/chrome_proxy/webdriver/bypass.py new file mode 100644 index 0000000..d7d1b0c --- /dev/null +++ b/tools/chrome_proxy/webdriver/bypass.py
@@ -0,0 +1,27 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import common +from common import TestDriver +from common import IntegrationTest + + +class Bypass(IntegrationTest): + + # Ensure Chrome does not use Data Saver for block=0, which uses the default + # proxy retry delay. + def testBypass(self): + with TestDriver() as t: + t.AddChromeArg('--enable-spdy-proxy-auth') + t.LoadURL('http://check.googlezip.net/block/') + for response in t.GetHTTPResponses(): + self.assertNotHasChromeProxyViaHeader(response) + + # Load another page and check that Data Saver is not used. + t.LoadURL('http://check.googlezip.net/test.html') + for response in t.GetHTTPResponses(): + self.assertNotHasChromeProxyViaHeader(response) + +if __name__ == '__main__': + IntegrationTest.RunAllTests()
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 7f458b6..2ea45cf 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -32524,10 +32524,7 @@ </histogram> <histogram name="Net.HttpStreamFactoryJob.StreamReadyCallbackTime" units="ms"> - <obsolete> - Deprecated 08/2016. No longer tracked. - </obsolete> - <owner>rtenneti@chromium.org</owner> + <owner>zhongyi@chromium.org</owner> <summary>Time it takes for OnStreamReadyCallback to be called.</summary> </histogram> @@ -55201,6 +55198,23 @@ </summary> </histogram> +<histogram name="SafeBrowsing.NavigationObserver.IPAddressCleanUpCount"> + <owner>jialiul@chromium.org</owner> + <summary> + Count of how many ResolvedIPAddresses get removed in each periodic clean up. + This is a rough estimation of the number of IPs associated with main frame + and sub-frame navigations every two minutes. + </summary> +</histogram> + +<histogram name="SafeBrowsing.NavigationObserver.NavigationEventCleanUpCount"> + <owner>jialiul@chromium.org</owner> + <summary> + Count of how many NavigationEvents get removed in each periodic clean up. + This is a rough estimation of the number of navigations every two minutes. + </summary> +</histogram> + <histogram name="SafeBrowsing.NotificationImageReporter.NetError" enum="NetErrorCodes"> <owner>nparker@chromium.org</owner> @@ -95739,6 +95753,7 @@ <int value="-1497338981" label="disable-accelerated-overflow-scroll"/> <int value="-1491417046" label="enable-fullscreen-toolbar-reveal"/> <int value="-1490298774" label="enable-captive-portal-bypass-proxy-option"/> + <int value="-1488744539" label="QuickUnlockFingerprint:enabled"/> <int value="-1482685863" label="enable-request-tablet-site"/> <int value="-1480926949" label="MaterialDesignBookmarks:enabled"/> <int value="-1478876902" label="disable-permission-action-reporting"/> @@ -96135,6 +96150,7 @@ <int value="365467768" label="prefetch-search-results"/> <int value="368854020" label="ash-screen-rotation-animation"/> <int value="370486304" label="enable-origin-chip-on-srp"/> + <int value="372460068" label="QuickUnlockFingerprint:disabled"/> <int value="377093001" label="WebRtcHWH264Encoding:disabled"/> <int value="379326303" label="enable-add-to-shelf"/> <int value="379428799" label="security-chip-animation"/>
diff --git a/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm b/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm index 45e9692a..aa7b063 100644 --- a/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm +++ b/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm
@@ -9,8 +9,9 @@ #include <CoreVideo/CoreVideo.h> #include <GLES2/gl2extchromium.h> +#include <utility> + #include "base/command_line.h" -#include "base/lazy_instance.h" #include "base/mac/sdk_forward_declarations.h" #include "base/trace_event/trace_event.h" #include "third_party/skia/include/core/SkColor.h" @@ -142,21 +143,20 @@ SolidColorContents(SkColor color, IOSurfaceRef io_surface); ~SolidColorContents(); + static std::map<SkColor, SolidColorContents*>* GetMap(); + SkColor color_ = 0; base::ScopedCFTypeRef<IOSurfaceRef> io_surface_; - static base::LazyInstance<std::map<SkColor, SolidColorContents*>> map_; }; -base::LazyInstance<std::map<SkColor, CARendererLayerTree::SolidColorContents*>> - CARendererLayerTree::SolidColorContents::map_; - // static scoped_refptr<CARendererLayerTree::SolidColorContents> CARendererLayerTree::SolidColorContents::Get(SkColor color) { const int kSolidColorContentsSize = 16; - auto found = map_.Get().find(color); - if (found != map_.Get().end()) + auto map = GetMap(); + auto found = map->find(color); + if (found != map->end()) return found->second; IOSurfaceRef io_surface = CreateIOSurface( @@ -188,15 +188,24 @@ SkColor color, IOSurfaceRef io_surface) : color_(color), io_surface_(io_surface) { - DCHECK(map_.Get().find(color_) == map_.Get().end()); - map_.Get()[color_] = this; + auto map = GetMap(); + DCHECK(map->find(color_) == map->end()); + map->insert(std::make_pair(color_, this)); } CARendererLayerTree::SolidColorContents::~SolidColorContents() { - auto found = map_.Get().find(color_); - DCHECK(found != map_.Get().end()); + auto map = GetMap(); + auto found = map->find(color_); + DCHECK(found != map->end()); DCHECK(found->second == this); - map_.Get().erase(color_); + map->erase(color_); +} + +// static +std::map<SkColor, CARendererLayerTree::SolidColorContents*>* +CARendererLayerTree::SolidColorContents::GetMap() { + static auto map = new std::map<SkColor, SolidColorContents*>(); + return map; } CARendererLayerTree::CARendererLayerTree(
diff --git a/ui/accelerated_widget_mac/io_surface_context.h b/ui/accelerated_widget_mac/io_surface_context.h index c673560..cf7770d 100644 --- a/ui/accelerated_widget_mac/io_surface_context.h +++ b/ui/accelerated_widget_mac/io_surface_context.h
@@ -10,7 +10,6 @@ #include <map> #include <memory> -#include "base/lazy_instance.h" #include "base/mac/scoped_nsobject.h" #include "base/memory/ref_counted.h" #include "ui/accelerated_widget_mac/accelerated_widget_mac_export.h" @@ -61,12 +60,6 @@ base::ScopedTypeRef<CGLContextObj> cgl_context_; bool poisoned_; - - // The global map from window number and window ordering to - // context data. - typedef std::map<Type, IOSurfaceContext*> TypeMap; - static base::LazyInstance<TypeMap> type_map_; - static TypeMap* type_map(); }; } // namespace ui
diff --git a/ui/accelerated_widget_mac/io_surface_context.mm b/ui/accelerated_widget_mac/io_surface_context.mm index 21d854c..382403e 100644 --- a/ui/accelerated_widget_mac/io_surface_context.mm +++ b/ui/accelerated_widget_mac/io_surface_context.mm
@@ -16,14 +16,27 @@ namespace ui { +namespace { + +// The global map from window number and window ordering to context data. +using TypeMap = std::map<IOSurfaceContext::Type, IOSurfaceContext*>; + +TypeMap* GetTypeMap() { + static auto type_map = new TypeMap(); + return type_map; +} + +} // namespace + // static scoped_refptr<IOSurfaceContext> IOSurfaceContext::Get(Type type) { TRACE_EVENT0("browser", "IOSurfaceContext::Get"); // Return the context for this type, if it exists. - TypeMap::iterator found = type_map()->find(type); - if (found != type_map()->end()) { + auto type_map = GetTypeMap(); + TypeMap::iterator found = type_map->find(type); + if (found != type_map->end()) { DCHECK(!found->second->poisoned_); return found->second; } @@ -51,8 +64,8 @@ // Create all contexts in the same share group so that the textures don't // need to be recreated when transitioning contexts. CGLContextObj share_context = NULL; - if (!type_map()->empty()) - share_context = type_map()->begin()->second->cgl_context(); + if (!type_map->empty()) + share_context = type_map->begin()->second->cgl_context(); error = CGLCreateContext( pixel_format, share_context, cgl_context.InitializeInto()); if (error != kCGLNoError) { @@ -67,19 +80,19 @@ if (poisoned_) return; - for (TypeMap::iterator it = type_map()->begin(); - it != type_map()->end(); - ++it) { + auto type_map = GetTypeMap(); + for (TypeMap::iterator it = type_map->begin(); it != type_map->end(); ++it) { it->second->poisoned_ = true; } - type_map()->clear(); + type_map->clear(); } IOSurfaceContext::IOSurfaceContext( Type type, base::ScopedTypeRef<CGLContextObj> cgl_context) : type_(type), cgl_context_(cgl_context), poisoned_(false) { - DCHECK(type_map()->find(type_) == type_map()->end()); - type_map()->insert(std::make_pair(type_, this)); + auto type_map = GetTypeMap(); + DCHECK(type_map->find(type_) == type_map->end()); + type_map->insert(std::make_pair(type_, this)); ui::GpuSwitchingManager::GetInstance()->AddObserver(this); } @@ -87,13 +100,14 @@ IOSurfaceContext::~IOSurfaceContext() { ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this); + auto type_map = GetTypeMap(); if (!poisoned_) { - DCHECK(type_map()->find(type_) != type_map()->end()); - DCHECK(type_map()->find(type_)->second == this); - type_map()->erase(type_); + DCHECK(type_map->find(type_) != type_map->end()); + DCHECK(type_map->find(type_)->second == this); + type_map->erase(type_); } else { - TypeMap::const_iterator found = type_map()->find(type_); - if (found != type_map()->end()) + TypeMap::const_iterator found = type_map->find(type_); + if (found != type_map->end()) DCHECK(found->second != this); } } @@ -105,14 +119,4 @@ PoisonContextAndSharegroup(); } -// static -IOSurfaceContext::TypeMap* - IOSurfaceContext::type_map() { - return type_map_.Pointer(); -} - -// static -base::LazyInstance<IOSurfaceContext::TypeMap> - IOSurfaceContext::type_map_; - } // namespace ui
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index b9f0a4a3a..e443d4f 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -166,8 +166,6 @@ "selection_model.h", "sequential_id_generator.cc", "sequential_id_generator.h", - "shadow_util.cc", - "shadow_util.h", "shadow_value.cc", "shadow_value.h", "skbitmap_operations.cc", @@ -233,6 +231,10 @@ "paint_throbber.h", "scoped_canvas.cc", "scoped_canvas.h", + "shadow_util.cc", + "shadow_util.h", + "skia_paint_util.cc", + "skia_paint_util.h", ] } @@ -402,13 +404,11 @@ ] } - if (!use_aura) { - if (!toolkit_views) { - sources -= [ - "nine_image_painter.cc", - "nine_image_painter.h", - ] - } + if ((!use_aura && !toolkit_views) || is_ios) { + sources -= [ + "nine_image_painter.cc", + "nine_image_painter.h", + ] } if (use_x11) {
diff --git a/ui/gfx/canvas.cc b/ui/gfx/canvas.cc index 58a3b57..64bec26 100644 --- a/ui/gfx/canvas.cc +++ b/ui/gfx/canvas.cc
@@ -22,6 +22,7 @@ #include "ui/gfx/geometry/safe_integer_conversions.h" #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/scoped_canvas.h" +#include "ui/gfx/skia_paint_util.h" #include "ui/gfx/skia_util.h" #include "ui/gfx/transform.h"
diff --git a/ui/gfx/image/image_skia_operations.cc b/ui/gfx/image/image_skia_operations.cc index 700a458..a9ce580 100644 --- a/ui/gfx/image/image_skia_operations.cc +++ b/ui/gfx/image/image_skia_operations.cc
@@ -25,6 +25,7 @@ #include "ui/gfx/image/image_skia_rep.h" #include "ui/gfx/image/image_skia_source.h" #include "ui/gfx/skbitmap_operations.h" +#include "ui/gfx/skia_paint_util.h" #include "ui/gfx/skia_util.h" namespace gfx {
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc index 3b36ea0..d081c168 100644 --- a/ui/gfx/render_text.cc +++ b/ui/gfx/render_text.cc
@@ -30,6 +30,7 @@ #include "ui/gfx/platform_font.h" #include "ui/gfx/render_text_harfbuzz.h" #include "ui/gfx/scoped_canvas.h" +#include "ui/gfx/skia_paint_util.h" #include "ui/gfx/skia_util.h" #include "ui/gfx/switches.h" #include "ui/gfx/text_elider.h"
diff --git a/ui/gfx/shadow_util.cc b/ui/gfx/shadow_util.cc index 238181a..88b19fae0 100644 --- a/ui/gfx/shadow_util.cc +++ b/ui/gfx/shadow_util.cc
@@ -14,6 +14,7 @@ #include "ui/gfx/geometry/insets.h" #include "ui/gfx/image/canvas_image_source.h" #include "ui/gfx/shadow_value.h" +#include "ui/gfx/skia_paint_util.h" #include "ui/gfx/skia_util.h" namespace gfx {
diff --git a/ui/gfx/skia_paint_util.cc b/ui/gfx/skia_paint_util.cc new file mode 100644 index 0000000..fbac6636 --- /dev/null +++ b/ui/gfx/skia_paint_util.cc
@@ -0,0 +1,136 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/skia_paint_util.h" + +#include "third_party/skia/include/core/SkColorFilter.h" +#include "third_party/skia/include/effects/SkBlurMaskFilter.h" +#include "third_party/skia/include/effects/SkGradientShader.h" +#include "third_party/skia/include/effects/SkLayerDrawLooper.h" +#include "ui/gfx/image/image_skia_rep.h" + +namespace gfx { + +sk_sp<SkShader> CreateImageRepShader(const gfx::ImageSkiaRep& image_rep, + SkShader::TileMode tile_mode, + const SkMatrix& local_matrix) { + return CreateImageRepShaderForScale(image_rep, tile_mode, local_matrix, + image_rep.scale()); +} + +sk_sp<SkShader> CreateImageRepShaderForScale(const gfx::ImageSkiaRep& image_rep, + SkShader::TileMode tile_mode, + const SkMatrix& local_matrix, + SkScalar scale) { + // Unscale matrix by |scale| such that the bitmap is drawn at the + // correct density. + // Convert skew and translation to pixel coordinates. + // Thus, for |bitmap_scale| = 2: + // x scale = 2, x translation = 1 DIP, + // should be converted to + // x scale = 1, x translation = 2 pixels. + SkMatrix shader_scale = local_matrix; + shader_scale.preScale(scale, scale); + shader_scale.setScaleX(local_matrix.getScaleX() / scale); + shader_scale.setScaleY(local_matrix.getScaleY() / scale); + + return SkShader::MakeBitmapShader(image_rep.sk_bitmap(), tile_mode, tile_mode, + &shader_scale); +} + +sk_sp<SkShader> CreateGradientShader(int start_point, + int end_point, + SkColor start_color, + SkColor end_color) { + SkColor grad_colors[2] = {start_color, end_color}; + SkPoint grad_points[2]; + grad_points[0].iset(0, start_point); + grad_points[1].iset(0, end_point); + + return SkGradientShader::MakeLinear(grad_points, grad_colors, NULL, 2, + SkShader::kClamp_TileMode); +} + +// TODO(estade): remove. Only exists to support legacy CreateShadowDrawLooper. +static SkScalar DeprecatedRadiusToSigma(double radius) { + // This captures historically what skia did under the hood. Now skia accepts + // sigma, not radius, so we perform the conversion. + return radius > 0 ? SkDoubleToScalar(0.57735f * radius + 0.5) : 0; +} + +// This is copied from +// third_party/WebKit/Source/platform/graphics/skia/SkiaUtils.h +static SkScalar RadiusToSigma(double radius) { + return radius > 0 ? SkDoubleToScalar(0.288675f * radius + 0.5f) : 0; +} + +sk_sp<SkDrawLooper> CreateShadowDrawLooper( + const std::vector<ShadowValue>& shadows) { + if (shadows.empty()) + return nullptr; + + SkLayerDrawLooper::Builder looper_builder; + + looper_builder.addLayer(); // top layer of the original. + + SkLayerDrawLooper::LayerInfo layer_info; + layer_info.fPaintBits |= SkLayerDrawLooper::kMaskFilter_Bit; + layer_info.fPaintBits |= SkLayerDrawLooper::kColorFilter_Bit; + layer_info.fColorMode = SkBlendMode::kSrc; + + for (size_t i = 0; i < shadows.size(); ++i) { + const ShadowValue& shadow = shadows[i]; + + layer_info.fOffset.set(SkIntToScalar(shadow.x()), + SkIntToScalar(shadow.y())); + + SkPaint* paint = looper_builder.addLayer(layer_info); + // SkBlurMaskFilter's blur radius defines the range to extend the blur from + // original mask, which is half of blur amount as defined in ShadowValue. + // Note that because this function uses DeprecatedRadiusToSigma, it actually + // creates a draw looper with roughly twice the desired blur. + paint->setMaskFilter(SkBlurMaskFilter::Make( + kNormal_SkBlurStyle, DeprecatedRadiusToSigma(shadow.blur() / 2), + SkBlurMaskFilter::kHighQuality_BlurFlag)); + paint->setColorFilter( + SkColorFilter::MakeModeFilter(shadow.color(), SkBlendMode::kSrcIn)); + } + + return looper_builder.detach(); +} + +sk_sp<SkDrawLooper> CreateShadowDrawLooperCorrectBlur( + const std::vector<ShadowValue>& shadows) { + if (shadows.empty()) + return nullptr; + + SkLayerDrawLooper::Builder looper_builder; + + looper_builder.addLayer(); // top layer of the original. + + SkLayerDrawLooper::LayerInfo layer_info; + layer_info.fPaintBits |= SkLayerDrawLooper::kMaskFilter_Bit; + layer_info.fPaintBits |= SkLayerDrawLooper::kColorFilter_Bit; + layer_info.fColorMode = SkBlendMode::kSrc; + + for (size_t i = 0; i < shadows.size(); ++i) { + const ShadowValue& shadow = shadows[i]; + + layer_info.fOffset.set(SkIntToScalar(shadow.x()), + SkIntToScalar(shadow.y())); + + SkPaint* paint = looper_builder.addLayer(layer_info); + // SkBlurMaskFilter's blur radius defines the range to extend the blur from + // original mask, which is half of blur amount as defined in ShadowValue. + paint->setMaskFilter(SkBlurMaskFilter::Make( + kNormal_SkBlurStyle, RadiusToSigma(shadow.blur() / 2), + SkBlurMaskFilter::kHighQuality_BlurFlag)); + paint->setColorFilter( + SkColorFilter::MakeModeFilter(shadow.color(), SkBlendMode::kSrcIn)); + } + + return looper_builder.detach(); +} + +} // namespace gfx
diff --git a/ui/gfx/skia_paint_util.h b/ui/gfx/skia_paint_util.h new file mode 100644 index 0000000..2ec10ff --- /dev/null +++ b/ui/gfx/skia_paint_util.h
@@ -0,0 +1,63 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_SKIA_PAINT_UTIL_H_ +#define UI_GFX_SKIA_PAINT_UTIL_H_ + +#include <vector> + +#include "third_party/skia/include/core/SkShader.h" +#include "ui/gfx/gfx_export.h" +#include "ui/gfx/shadow_value.h" + +class SkDrawLooper; +class SkMatrix; + +namespace gfx { + +class ImageSkiaRep; + +// Creates a bitmap shader for the image rep with the image rep's scale factor. +// Sets the created shader's local matrix such that it displays the image rep at +// the correct scale factor. +// The shader's local matrix should not be changed after the shader is created. +// TODO(pkotwicz): Allow shader's local matrix to be changed after the shader +// is created. +// +GFX_EXPORT sk_sp<SkShader> CreateImageRepShader( + const gfx::ImageSkiaRep& image_rep, + SkShader::TileMode tile_mode, + const SkMatrix& local_matrix); + +// Creates a bitmap shader for the image rep with the passed in scale factor. +GFX_EXPORT sk_sp<SkShader> CreateImageRepShaderForScale( + const gfx::ImageSkiaRep& image_rep, + SkShader::TileMode tile_mode, + const SkMatrix& local_matrix, + SkScalar scale); + +// Creates a vertical gradient shader. The caller owns the shader. +// Example usage to avoid leaks: +GFX_EXPORT sk_sp<SkShader> CreateGradientShader(int start_point, + int end_point, + SkColor start_color, + SkColor end_color); + +// Creates a draw looper to generate |shadows|. The caller owns the draw looper. +// NULL is returned if |shadows| is empty since no draw looper is needed in +// this case. +// DEPRECATED: See below. TODO(estade): remove this: crbug.com/624175 +GFX_EXPORT sk_sp<SkDrawLooper> CreateShadowDrawLooper( + const std::vector<ShadowValue>& shadows); + +// Creates a draw looper to generate |shadows|. This creates a looper with the +// correct amount of blur. Callers of the existing CreateShadowDrawLooper may +// rely on the wrong amount of blur being applied but new code should use this +// function. +GFX_EXPORT sk_sp<SkDrawLooper> CreateShadowDrawLooperCorrectBlur( + const std::vector<ShadowValue>& shadows); + +} // namespace gfx + +#endif // UI_GFX_SKIA_UTIL_H_
diff --git a/ui/gfx/skia_util.cc b/ui/gfx/skia_util.cc index 963e081..6f7818d9 100644 --- a/ui/gfx/skia_util.cc +++ b/ui/gfx/skia_util.cc
@@ -10,7 +10,6 @@ #include "base/numerics/safe_conversions.h" #include "base/numerics/safe_math.h" #include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkColorFilter.h" #include "third_party/skia/include/core/SkColorPriv.h" #include "third_party/skia/include/core/SkUnPreMultiply.h" #include "third_party/skia/include/effects/SkBlurMaskFilter.h" @@ -104,128 +103,6 @@ flattened->set(8, SkMScalarToScalar(transform.matrix().get(3, 3))); } -sk_sp<SkShader> CreateImageRepShader(const gfx::ImageSkiaRep& image_rep, - SkShader::TileMode tile_mode, - const SkMatrix& local_matrix) { - return CreateImageRepShaderForScale(image_rep, tile_mode, local_matrix, - image_rep.scale()); -} - -sk_sp<SkShader> CreateImageRepShaderForScale( - const gfx::ImageSkiaRep& image_rep, - SkShader::TileMode tile_mode, - const SkMatrix& local_matrix, - SkScalar scale) { - // Unscale matrix by |scale| such that the bitmap is drawn at the - // correct density. - // Convert skew and translation to pixel coordinates. - // Thus, for |bitmap_scale| = 2: - // x scale = 2, x translation = 1 DIP, - // should be converted to - // x scale = 1, x translation = 2 pixels. - SkMatrix shader_scale = local_matrix; - shader_scale.preScale(scale, scale); - shader_scale.setScaleX(local_matrix.getScaleX() / scale); - shader_scale.setScaleY(local_matrix.getScaleY() / scale); - - return SkShader::MakeBitmapShader( - image_rep.sk_bitmap(), tile_mode, tile_mode, &shader_scale); -} - -sk_sp<SkShader> CreateGradientShader(int start_point, - int end_point, - SkColor start_color, - SkColor end_color) { - SkColor grad_colors[2] = { start_color, end_color}; - SkPoint grad_points[2]; - grad_points[0].iset(0, start_point); - grad_points[1].iset(0, end_point); - - return SkGradientShader::MakeLinear( - grad_points, grad_colors, NULL, 2, SkShader::kClamp_TileMode); -} - -// TODO(estade): remove. Only exists to support legacy CreateShadowDrawLooper. -static SkScalar DeprecatedRadiusToSigma(double radius) { - // This captures historically what skia did under the hood. Now skia accepts - // sigma, not radius, so we perform the conversion. - return radius > 0 ? SkDoubleToScalar(0.57735f * radius + 0.5) : 0; -} - -// This is copied from -// third_party/WebKit/Source/platform/graphics/skia/SkiaUtils.h -static SkScalar RadiusToSigma(double radius) { - return radius > 0 ? SkDoubleToScalar(0.288675f * radius + 0.5f) : 0; -} - -sk_sp<SkDrawLooper> CreateShadowDrawLooper( - const std::vector<ShadowValue>& shadows) { - if (shadows.empty()) - return nullptr; - - SkLayerDrawLooper::Builder looper_builder; - - looper_builder.addLayer(); // top layer of the original. - - SkLayerDrawLooper::LayerInfo layer_info; - layer_info.fPaintBits |= SkLayerDrawLooper::kMaskFilter_Bit; - layer_info.fPaintBits |= SkLayerDrawLooper::kColorFilter_Bit; - layer_info.fColorMode = SkBlendMode::kSrc; - - for (size_t i = 0; i < shadows.size(); ++i) { - const ShadowValue& shadow = shadows[i]; - - layer_info.fOffset.set(SkIntToScalar(shadow.x()), - SkIntToScalar(shadow.y())); - - SkPaint* paint = looper_builder.addLayer(layer_info); - // SkBlurMaskFilter's blur radius defines the range to extend the blur from - // original mask, which is half of blur amount as defined in ShadowValue. - // Note that because this function uses DeprecatedRadiusToSigma, it actually - // creates a draw looper with roughly twice the desired blur. - paint->setMaskFilter(SkBlurMaskFilter::Make( - kNormal_SkBlurStyle, DeprecatedRadiusToSigma(shadow.blur() / 2), - SkBlurMaskFilter::kHighQuality_BlurFlag)); - paint->setColorFilter( - SkColorFilter::MakeModeFilter(shadow.color(), SkBlendMode::kSrcIn)); - } - - return looper_builder.detach(); -} - -sk_sp<SkDrawLooper> CreateShadowDrawLooperCorrectBlur( - const std::vector<ShadowValue>& shadows) { - if (shadows.empty()) - return nullptr; - - SkLayerDrawLooper::Builder looper_builder; - - looper_builder.addLayer(); // top layer of the original. - - SkLayerDrawLooper::LayerInfo layer_info; - layer_info.fPaintBits |= SkLayerDrawLooper::kMaskFilter_Bit; - layer_info.fPaintBits |= SkLayerDrawLooper::kColorFilter_Bit; - layer_info.fColorMode = SkBlendMode::kSrc; - - for (size_t i = 0; i < shadows.size(); ++i) { - const ShadowValue& shadow = shadows[i]; - - layer_info.fOffset.set(SkIntToScalar(shadow.x()), - SkIntToScalar(shadow.y())); - - SkPaint* paint = looper_builder.addLayer(layer_info); - // SkBlurMaskFilter's blur radius defines the range to extend the blur from - // original mask, which is half of blur amount as defined in ShadowValue. - paint->setMaskFilter(SkBlurMaskFilter::Make( - kNormal_SkBlurStyle, RadiusToSigma(shadow.blur() / 2), - SkBlurMaskFilter::kHighQuality_BlurFlag)); - paint->setColorFilter( - SkColorFilter::MakeModeFilter(shadow.color(), SkBlendMode::kSrcIn)); - } - - return looper_builder.detach(); -} - bool BitmapsAreEqual(const SkBitmap& bitmap1, const SkBitmap& bitmap2) { void* addr1 = NULL; void* addr2 = NULL;
diff --git a/ui/gfx/skia_util.h b/ui/gfx/skia_util.h index fbd1909..76a999f 100644 --- a/ui/gfx/skia_util.h +++ b/ui/gfx/skia_util.h
@@ -16,16 +16,14 @@ #include "ui/gfx/gfx_export.h" class SkBitmap; -class SkDrawLooper; +class SkMatrix; namespace gfx { -class ImageSkiaRep; class Point; class PointF; class Rect; class RectF; -class ShadowValue; class Transform; // Convert between Skia and gfx types. @@ -46,46 +44,6 @@ GFX_EXPORT void TransformToFlattenedSkMatrix(const gfx::Transform& transform, SkMatrix* flattened); -// Creates a bitmap shader for the image rep with the image rep's scale factor. -// Sets the created shader's local matrix such that it displays the image rep at -// the correct scale factor. -// The shader's local matrix should not be changed after the shader is created. -// TODO(pkotwicz): Allow shader's local matrix to be changed after the shader -// is created. -// -GFX_EXPORT sk_sp<SkShader> CreateImageRepShader( - const gfx::ImageSkiaRep& image_rep, - SkShader::TileMode tile_mode, - const SkMatrix& local_matrix); - -// Creates a bitmap shader for the image rep with the passed in scale factor. -GFX_EXPORT sk_sp<SkShader> CreateImageRepShaderForScale( - const gfx::ImageSkiaRep& image_rep, - SkShader::TileMode tile_mode, - const SkMatrix& local_matrix, - SkScalar scale); - -// Creates a vertical gradient shader. The caller owns the shader. -// Example usage to avoid leaks: -GFX_EXPORT sk_sp<SkShader> CreateGradientShader(int start_point, - int end_point, - SkColor start_color, - SkColor end_color); - -// Creates a draw looper to generate |shadows|. The caller owns the draw looper. -// NULL is returned if |shadows| is empty since no draw looper is needed in -// this case. -// DEPRECATED: See below. TODO(estade): remove this: crbug.com/624175 -GFX_EXPORT sk_sp<SkDrawLooper> CreateShadowDrawLooper( - const std::vector<ShadowValue>& shadows); - -// Creates a draw looper to generate |shadows|. This creates a looper with the -// correct amount of blur. Callers of the existing CreateShadowDrawLooper may -// rely on the wrong amount of blur being applied but new code should use this -// function. -GFX_EXPORT sk_sp<SkDrawLooper> CreateShadowDrawLooperCorrectBlur( - const std::vector<ShadowValue>& shadows); - // Returns true if the two bitmaps contain the same pixels. GFX_EXPORT bool BitmapsAreEqual(const SkBitmap& bitmap1, const SkBitmap& bitmap2);
diff --git a/ui/gl/gl_gl_api_implementation.cc b/ui/gl/gl_gl_api_implementation.cc index cc4453e..ecd5881 100644 --- a/ui/gl/gl_gl_api_implementation.cc +++ b/ui/gl/gl_gl_api_implementation.cc
@@ -437,20 +437,29 @@ } void RealGLApi::glClearDepthFn(GLclampd depth) { - if (driver_->fn.glClearDepthFn) { - GLApiBase::glClearDepthFn(depth); - } else { + // OpenGL ES only has glClearDepthf, forward the parameters from glClearDepth. + // Many mock tests expect only glClearDepth is called so don't make the + // interception when testing with mocks. + if (version_->is_es && GetGLImplementation() != kGLImplementationMockGL) { DCHECK(driver_->fn.glClearDepthfFn); GLApiBase::glClearDepthfFn(static_cast<GLclampf>(depth)); + } else { + DCHECK(driver_->fn.glClearDepthFn); + GLApiBase::glClearDepthFn(depth); } } void RealGLApi::glDepthRangeFn(GLclampd z_near, GLclampd z_far) { - if (driver_->fn.glDepthRangeFn) { - GLApiBase::glDepthRangeFn(z_near, z_far); - } else { + // OpenGL ES only has glDepthRangef, forward the parameters from glDepthRange. + // Many mock tests expect only glDepthRange is called so don't make the + // interception when testing with mocks. + if (version_->is_es && GetGLImplementation() != kGLImplementationMockGL) { + DCHECK(driver_->fn.glDepthRangefFn); GLApiBase::glDepthRangefFn(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far)); + } else { + DCHECK(driver_->fn.glDepthRangeFn); + GLApiBase::glDepthRangeFn(z_near, z_far); } }
diff --git a/ui/native_theme/native_theme_mac.mm b/ui/native_theme/native_theme_mac.mm index 36a58dc..bcb69cc 100644 --- a/ui/native_theme/native_theme_mac.mm +++ b/ui/native_theme/native_theme_mac.mm
@@ -19,6 +19,7 @@ #include "ui/gfx/color_palette.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/shadow_value.h" +#include "ui/gfx/skia_paint_util.h" #include "ui/gfx/skia_util.h" #include "ui/native_theme/common_theme.h"
diff --git a/ui/views/animation/ink_drop_painted_layer_delegates.cc b/ui/views/animation/ink_drop_painted_layer_delegates.cc index c098c83..135e249 100644 --- a/ui/views/animation/ink_drop_painted_layer_delegates.cc +++ b/ui/views/animation/ink_drop_painted_layer_delegates.cc
@@ -15,6 +15,7 @@ #include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_f.h" +#include "ui/gfx/skia_paint_util.h" #include "ui/gfx/skia_util.h" namespace views {
diff --git a/ui/views/bubble/bubble_border.cc b/ui/views/bubble/bubble_border.cc index 0aed6ef..67b2acf 100644 --- a/ui/views/bubble/bubble_border.cc +++ b/ui/views/bubble/bubble_border.cc
@@ -18,7 +18,7 @@ #include "ui/gfx/path.h" #include "ui/gfx/scoped_canvas.h" #include "ui/gfx/shadow_value.h" -#include "ui/gfx/skia_util.h" +#include "ui/gfx/skia_paint_util.h" #include "ui/resources/grit/ui_resources.h" #include "ui/views/painter.h" #include "ui/views/resources/grit/views_resources.h"
diff --git a/ui/views/bubble/bubble_frame_view.cc b/ui/views/bubble/bubble_frame_view.cc index d27aa9d..80c41c0 100644 --- a/ui/views/bubble/bubble_frame_view.cc +++ b/ui/views/bubble/bubble_frame_view.cc
@@ -51,7 +51,7 @@ // The MD spec states that the center of the "x" should be 16x16 from the top // right of the dialog. constexpr int kClosePaddingRightMd = 4; -constexpr int kClosePaddingTopMd = 5; +constexpr int kClosePaddingTopMd = 4; // Get the |vertical| or horizontal amount that |available_bounds| overflows // |window_bounds|.
diff --git a/ui/views/controls/button/toggle_button.cc b/ui/views/controls/button/toggle_button.cc index 37c2ce1..349acde 100644 --- a/ui/views/controls/button/toggle_button.cc +++ b/ui/views/controls/button/toggle_button.cc
@@ -12,6 +12,7 @@ #include "ui/gfx/color_utils.h" #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/shadow_value.h" +#include "ui/gfx/skia_paint_util.h" #include "ui/views/animation/ink_drop_impl.h" #include "ui/views/animation/ink_drop_ripple.h" #include "ui/views/border.h"
diff --git a/ui/views/controls/button/vector_icon_button.cc b/ui/views/controls/button/vector_icon_button.cc index 848700a..c3e1ba2 100644 --- a/ui/views/controls/button/vector_icon_button.cc +++ b/ui/views/controls/button/vector_icon_button.cc
@@ -22,13 +22,12 @@ } // namespace VectorIconButton::VectorIconButton(VectorIconButtonDelegate* delegate) - : views::ImageButton(delegate), + : ImageButton(delegate), delegate_(delegate), id_(gfx::VectorIconId::VECTOR_ICON_NONE) { SetInkDropMode(InkDropMode::ON); set_has_ink_drop_action_on_click(true); - SetImageAlignment(views::ImageButton::ALIGN_CENTER, - views::ImageButton::ALIGN_MIDDLE); + SetImageAlignment(ImageButton::ALIGN_CENTER, ImageButton::ALIGN_MIDDLE); SetFocusPainter(nullptr); } @@ -36,39 +35,49 @@ void VectorIconButton::SetIcon(gfx::VectorIconId id) { id_ = id; + icon_ = nullptr; - if (!border()) { - SetBorder( - views::CreateEmptyBorder(kButtonExtraTouchSize, kButtonExtraTouchSize, - kButtonExtraTouchSize, kButtonExtraTouchSize)); - } + OnSetIcon(); } void VectorIconButton::SetIcon(const gfx::VectorIcon& icon) { + id_ = gfx::VectorIconId::VECTOR_ICON_NONE; icon_ = &icon; - SetIcon(gfx::VectorIconId::VECTOR_ICON_NONE); + + OnSetIcon(); } void VectorIconButton::OnThemeChanged() { + UpdateImagesAndColors(); +} + +void VectorIconButton::OnNativeThemeChanged(const ui::NativeTheme* theme) { + UpdateImagesAndColors(); +} + +void VectorIconButton::OnSetIcon() { + if (!border()) + SetBorder(CreateEmptyBorder(gfx::Insets(kButtonExtraTouchSize))); + + UpdateImagesAndColors(); +} + +void VectorIconButton::UpdateImagesAndColors() { SkColor icon_color = color_utils::DeriveDefaultIconColor(delegate_->GetVectorIconBaseColor()); SkColor disabled_color = SkColorSetA(icon_color, 0xff / 2); if (icon_) { - SetImage(views::CustomButton::STATE_NORMAL, + SetImage(CustomButton::STATE_NORMAL, gfx::CreateVectorIcon(*icon_, icon_color)); - SetImage(views::CustomButton::STATE_DISABLED, + SetImage(CustomButton::STATE_DISABLED, gfx::CreateVectorIcon(*icon_, disabled_color)); } else { - SetImage(views::CustomButton::STATE_NORMAL, + SetImage(CustomButton::STATE_NORMAL, gfx::CreateVectorIcon(id_, icon_color)); - SetImage(views::CustomButton::STATE_DISABLED, + SetImage(CustomButton::STATE_DISABLED, gfx::CreateVectorIcon(id_, disabled_color)); } set_ink_drop_base_color(icon_color); } -void VectorIconButton::OnNativeThemeChanged(const ui::NativeTheme* theme) { - OnThemeChanged(); -} - } // namespace views
diff --git a/ui/views/controls/button/vector_icon_button.h b/ui/views/controls/button/vector_icon_button.h index 8a99ae0e..b0aa025 100644 --- a/ui/views/controls/button/vector_icon_button.h +++ b/ui/views/controls/button/vector_icon_button.h
@@ -36,6 +36,12 @@ void OnNativeThemeChanged(const ui::NativeTheme* theme) override; private: + // Performs the work common to both SetIcon() variants. + void OnSetIcon(); + + // Called when something may have affected the button's images or colors. + void UpdateImagesAndColors(); + VectorIconButtonDelegate* delegate_; // TODO(estade): remove |id_| in favor of |icon_| once all callers have been // updated.
diff --git a/ui/views/shadow_border.cc b/ui/views/shadow_border.cc index 1f19c01..3bc065b 100644 --- a/ui/views/shadow_border.cc +++ b/ui/views/shadow_border.cc
@@ -8,7 +8,7 @@ #include "ui/gfx/canvas.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/rect.h" -#include "ui/gfx/skia_util.h" +#include "ui/gfx/skia_paint_util.h" #include "ui/views/view.h" namespace views {
diff --git a/url/url_canon.h b/url/url_canon.h index ff66c6e3..d093f359 100644 --- a/url/url_canon.h +++ b/url/url_canon.h
@@ -118,8 +118,9 @@ } void ReserveSizeIfNeeded(int estimated_size) { + // Reserve a bit extra to account for escaped chars. if (estimated_size > buffer_len_) - Resize(estimated_size); + Resize(estimated_size + 8); } protected:
diff --git a/url/url_canon_relative.cc b/url/url_canon_relative.cc index 8259056..851368d 100644 --- a/url/url_canon_relative.cc +++ b/url/url_canon_relative.cc
@@ -288,7 +288,7 @@ // possible escaped characters. output->ReserveSizeIfNeeded( base_parsed.path.begin + - std::max(path.end(), std::max(query.end(), ref.end())) + 8); + std::max(path.end(), std::max(query.end(), ref.end()))); output->Append(base_url, base_parsed.path.begin); if (path.len > 0) { @@ -406,7 +406,7 @@ // base URL. output->ReserveSizeIfNeeded( replacements.components().Length() + - base_parsed.CountCharactersBefore(Parsed::USERNAME, false) + 8); + base_parsed.CountCharactersBefore(Parsed::USERNAME, false)); return ReplaceStandardURL(base_url, base_parsed, replacements, query_converter, output, out_parsed); }
diff --git a/url/url_canon_stdstring.cc b/url/url_canon_stdstring.cc index 366a2e0..c81a0a98 100644 --- a/url/url_canon_stdstring.cc +++ b/url/url_canon_stdstring.cc
@@ -9,7 +9,6 @@ StdStringCanonOutput::StdStringCanonOutput(std::string* str) : CanonOutput(), str_(str) { cur_len_ = static_cast<int>(str_->size()); // Append to existing data. - str_->resize(str_->capacity()); buffer_ = str_->empty() ? NULL : &(*str_)[0]; buffer_len_ = static_cast<int>(str_->size()); }
diff --git a/url/url_canon_stdstring.h b/url/url_canon_stdstring.h index 662cac7..f36f3a9b 100644 --- a/url/url_canon_stdstring.h +++ b/url/url_canon_stdstring.h
@@ -23,8 +23,7 @@ // throughout the lifetime of this object. // // The given string will be appended to; any existing data in the string will -// be preserved. The caller should reserve() the amount of data in the string -// they expect to be written. We will resize if necessary, but that's slow. +// be preserved. // // Note that when canonicalization is complete, the string will likely have // unused space at the end because we make the string very big to start out
diff --git a/url/url_util.cc b/url/url_util.cc index 9a2cce4..d5c27d1 100644 --- a/url/url_util.cc +++ b/url/url_util.cc
@@ -193,9 +193,7 @@ CharsetConverter* charset_converter, CanonOutput* output, Parsed* output_parsed) { - // Reserve enough room in the output for the input, plus some extra so that - // we have room if we have to escape a few things without reallocating. - output->ReserveSizeIfNeeded(spec_len + 8); + output->ReserveSizeIfNeeded(spec_len); // Remove any whitespace from the middle of the relative URL if necessary. // Possibly this will result in copying to the new buffer. @@ -423,7 +421,7 @@ // in callers below, and the code checks to see which components are being // replaced, and with what length. If this ends up being a hot spot it should // be changed. - output->ReserveSizeIfNeeded(spec_len + 8); + output->ReserveSizeIfNeeded(spec_len); // If we get here, then we know the scheme doesn't need to be replaced, so can // just key off the scheme in the spec to know how to do the replacements.