diff --git a/DEPS b/DEPS index 9691f1b..0f89d6bb 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '9f85d68887a61f93656dbfacdd3f978d510c02ee', + 'skia_revision': 'e980174d0f3af8e497d9c38851114cc6a3c02e9a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '213c71950c7eb00f8ad53cf6c184cbecc1499d36', + 'v8_revision': '4eb9e4f0e51b914cbe911f3f5a48672c43314040', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -1175,6 +1175,4 @@ 'src/third_party/android_tools', # ANGLE manages DEPS that it also owns the build files for, such as dEQP. ("src/third_party/angle", "DEPS.chromium"), - # SwiftShader manages DEPS that it also owns the build files for, such as Subzero. - ("src/third_party/swiftshader", "DEPS"), ]
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index ac2cb98..7645203 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -2269,8 +2269,17 @@ if (callback != null) { jsCallback = new JavaScriptCallback() { @Override - public void handleJavaScriptResult(String jsonResult) { - callback.onReceiveValue(jsonResult); + public void handleJavaScriptResult(final String jsonResult) { + // Post the application callback back to the current thread to ensure the + // application callback is executed without any native code on the stack. This + // so that any exception thrown by the application callback won't have to be + // propagated through a native call stack. + mHandler.post(new Runnable() { + @Override + public void run() { + callback.onReceiveValue(jsonResult); + } + }); } }; }
diff --git a/base/task_scheduler/task_scheduler_impl.cc b/base/task_scheduler/task_scheduler_impl.cc index b1b2d36..3bcda338 100644 --- a/base/task_scheduler/task_scheduler_impl.cc +++ b/base/task_scheduler/task_scheduler_impl.cc
@@ -6,7 +6,6 @@ #include <utility> -#include "base/memory/ptr_util.h" #include "base/task_scheduler/delayed_task_manager.h" #include "base/task_scheduler/scheduler_worker_pool_params.h" #include "base/task_scheduler/sequence.h" @@ -53,10 +52,13 @@ } // namespace -TaskSchedulerImpl::TaskSchedulerImpl(StringPiece name) +TaskSchedulerImpl::TaskSchedulerImpl( + StringPiece name, + std::unique_ptr<TaskTrackerType> task_tracker) : name_(name), service_thread_("TaskSchedulerServiceThread"), - single_thread_task_runner_manager_(&task_tracker_, + task_tracker_(std::move(task_tracker)), + single_thread_task_runner_manager_(task_tracker_.get(), &delayed_task_manager_) { static_assert(arraysize(worker_pools_) == ENVIRONMENT_COUNT, "The size of |worker_pools_| must match ENVIRONMENT_COUNT."); @@ -68,7 +70,7 @@ ++environment_type) { worker_pools_[environment_type] = MakeUnique<SchedulerWorkerPoolImpl>( name_ + kEnvironmentParams[environment_type].name_suffix, - kEnvironmentParams[environment_type].priority_hint, &task_tracker_, + kEnvironmentParams[environment_type].priority_hint, task_tracker_.get(), &delayed_task_manager_); } } @@ -96,11 +98,11 @@ #if defined(OS_POSIX) && !defined(OS_NACL_SFI) // Needs to happen after starting the service thread to get its // message_loop(). - task_tracker_.set_watch_file_descriptor_message_loop( + task_tracker_->set_watch_file_descriptor_message_loop( static_cast<MessageLoopForIO*>(service_thread_.message_loop())); #if DCHECK_IS_ON() - task_tracker_.set_service_thread_handle(service_thread_.GetThreadHandle()); + task_tracker_->set_service_thread_handle(service_thread_.GetThreadHandle()); #endif // DCHECK_IS_ON() #endif // defined(OS_POSIX) && !defined(OS_NACL_SFI) @@ -179,11 +181,11 @@ void TaskSchedulerImpl::Shutdown() { // TODO(fdoray): Increase the priority of BACKGROUND tasks blocking shutdown. - task_tracker_.Shutdown(); + task_tracker_->Shutdown(); } void TaskSchedulerImpl::FlushForTesting() { - task_tracker_.Flush(); + task_tracker_->Flush(); } void TaskSchedulerImpl::JoinForTesting() {
diff --git a/base/task_scheduler/task_scheduler_impl.h b/base/task_scheduler/task_scheduler_impl.h index 4907ce2..1b05baf9 100644 --- a/base/task_scheduler/task_scheduler_impl.h +++ b/base/task_scheduler/task_scheduler_impl.h
@@ -12,6 +12,7 @@ #include "base/callback.h" #include "base/logging.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "base/strings/string_piece.h" #include "base/synchronization/atomic_flag.h" @@ -38,8 +39,19 @@ // Default TaskScheduler implementation. This class is thread-safe. class BASE_EXPORT TaskSchedulerImpl : public TaskScheduler { public: - // |name| is used to label threads and histograms. - explicit TaskSchedulerImpl(StringPiece name); + using TaskTrackerType = +#if defined(OS_POSIX) && !defined(OS_NACL_SFI) + TaskTrackerPosix; +#else + TaskTracker; +#endif + + // |name| is used to label threads and histograms. |task_tracker| can be used + // for tests that need more execution control. By default, you get the + // production TaskTracker. + explicit TaskSchedulerImpl(StringPiece name, + std::unique_ptr<TaskTrackerType> task_tracker = + MakeUnique<TaskTrackerType>()); ~TaskSchedulerImpl() override; // TaskScheduler: @@ -74,11 +86,7 @@ const std::string name_; Thread service_thread_; -#if defined(OS_POSIX) && !defined(OS_NACL_SFI) - TaskTrackerPosix task_tracker_; -#else - TaskTracker task_tracker_; -#endif + const std::unique_ptr<TaskTrackerType> task_tracker_; DelayedTaskManager delayed_task_manager_; SchedulerSingleThreadTaskRunnerManager single_thread_task_runner_manager_;
diff --git a/base/task_scheduler/task_tracker.cc b/base/task_scheduler/task_tracker.cc index 55230aa9..5509e32 100644 --- a/base/task_scheduler/task_tracker.cc +++ b/base/task_scheduler/task_tracker.cc
@@ -388,6 +388,10 @@ } #endif +int TaskTracker::GetNumPendingUndelayedTasksForTesting() const { + return subtle::Acquire_Load(&num_pending_undelayed_tasks_); +} + bool TaskTracker::BeforePostTask(TaskShutdownBehavior shutdown_behavior) { if (shutdown_behavior == TaskShutdownBehavior::BLOCK_SHUTDOWN) { // BLOCK_SHUTDOWN tasks block shutdown between the moment they are posted
diff --git a/base/task_scheduler/task_tracker.h b/base/task_scheduler/task_tracker.h index 1a1977d..b80e661c 100644 --- a/base/task_scheduler/task_tracker.h +++ b/base/task_scheduler/task_tracker.h
@@ -90,6 +90,10 @@ virtual bool IsPostingBlockShutdownTaskAfterShutdownAllowed(); #endif + // Returns the number of undelayed tasks that haven't completed their + // execution. + int GetNumPendingUndelayedTasksForTesting() const; + private: class State;
diff --git a/base/task_scheduler/task_tracker_posix.h b/base/task_scheduler/task_tracker_posix.h index a98b464c..7a17f75 100644 --- a/base/task_scheduler/task_tracker_posix.h +++ b/base/task_scheduler/task_tracker_posix.h
@@ -50,11 +50,12 @@ } #endif - private: + protected: // TaskTracker: void PerformRunTask(std::unique_ptr<Task> task, const SequenceToken& sequence_token) override; + private: #if DCHECK_IS_ON() bool IsPostingBlockShutdownTaskAfterShutdownAllowed() override; #endif
diff --git a/base/test/scoped_task_environment.cc b/base/test/scoped_task_environment.cc index 672ffb05..7ca8af07 100644 --- a/base/test/scoped_task_environment.cc +++ b/base/test/scoped_task_environment.cc
@@ -5,8 +5,12 @@ #include "base/test/scoped_task_environment.h" #include "base/run_loop.h" -#include "base/task_scheduler/scheduler_worker_pool_params.h" +#include "base/synchronization/condition_variable.h" +#include "base/synchronization/lock.h" +#include "base/task_scheduler/post_task.h" #include "base/task_scheduler/task_scheduler.h" +#include "base/task_scheduler/task_scheduler_impl.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" namespace base { @@ -21,25 +25,70 @@ // MessageLoop::TaskObserver: void WillProcessTask(const PendingTask& pending_task) override {} void DidProcessTask(const PendingTask& pending_task) override { - ran_task_ = true; + ++task_count_; } - bool ran_task() const { return ran_task_; } + int task_count() const { return task_count_; } private: - bool ran_task_ = false; + int task_count_ = 0; + DISALLOW_COPY_AND_ASSIGN(TaskObserver); }; } // namespace -ScopedTaskEnvironment::ScopedTaskEnvironment(MainThreadType main_thread_type) - : message_loop_(main_thread_type == MainThreadType::DEFAULT +class ScopedTaskEnvironment::TestTaskTracker + : public internal::TaskSchedulerImpl::TaskTrackerType { + public: + TestTaskTracker(ScopedTaskEnvironment* outer); + + void SetTaskQueueEmptyClosure(OnceClosure task_queue_empty_closure); + + // Allow running tasks. + void AllowRunRask(); + + // Disallow running tasks. No-ops and returns false if a task is running. + bool DisallowRunTasks(); + + private: + friend class ScopedTaskEnvironment; + + // internal::TaskSchedulerImpl::TaskTrackerType: + void PerformRunTask(std::unique_ptr<internal::Task> task, + const SequenceToken& sequence_token) override; + + ScopedTaskEnvironment* const outer_; + + // Synchronizes accesses to members below. + Lock lock_; + + // Closure posted to the main thread when the task queue becomes empty. + OnceClosure task_queue_empty_closure_; + + // True if running tasks is allowed. + bool can_run_tasks_ = true; + + // Signaled when |can_run_tasks_| becomes true. + ConditionVariable can_run_tasks_cv_; + + // Number of tasks that are currently running. + int num_tasks_running_ = 0; + + DISALLOW_COPY_AND_ASSIGN(TestTaskTracker); +}; + +ScopedTaskEnvironment::ScopedTaskEnvironment( + MainThreadType main_thread_type, + ExecutionControlMode execution_control_mode) + : execution_control_mode_(execution_control_mode), + message_loop_(main_thread_type == MainThreadType::DEFAULT ? MessageLoop::TYPE_DEFAULT : (main_thread_type == MainThreadType::UI ? MessageLoop::TYPE_UI - : MessageLoop::TYPE_IO)) { - DCHECK(!TaskScheduler::GetInstance()); + : MessageLoop::TYPE_IO)), + task_tracker_(new TestTaskTracker(this)) { + CHECK(!TaskScheduler::GetInstance()); // Instantiate a TaskScheduler with 1 thread in each of its 4 pools. Threads // stay alive even when they don't have work. @@ -48,10 +97,14 @@ const SchedulerWorkerPoolParams worker_pool_params( SchedulerWorkerPoolParams::StandbyThreadPolicy::ONE, kMaxThreads, kSuggestedReclaimTime); - TaskScheduler::Create("ScopedTaskEnvironment"); + TaskScheduler::SetInstance(MakeUnique<internal::TaskSchedulerImpl>( + "ScopedTaskEnvironment", WrapUnique(task_tracker_))); task_scheduler_ = TaskScheduler::GetInstance(); TaskScheduler::GetInstance()->Start({worker_pool_params, worker_pool_params, worker_pool_params, worker_pool_params}); + + if (execution_control_mode_ == ExecutionControlMode::QUEUED) + CHECK(task_tracker_->DisallowRunTasks()); } ScopedTaskEnvironment::~ScopedTaskEnvironment() { @@ -59,10 +112,10 @@ // infinite post loop in the remaining work but this isn't possible right now // because base::~MessageLoop() didn't use to do this and adding it here would // make the migration away from MessageLoop that much harder. - - DCHECK_EQ(TaskScheduler::GetInstance(), task_scheduler_); + CHECK_EQ(TaskScheduler::GetInstance(), task_scheduler_); // Without FlushForTesting(), DeleteSoon() and ReleaseSoon() tasks could be // skipped, resulting in memory leaks. + task_tracker_->AllowRunRask(); TaskScheduler::GetInstance()->FlushForTesting(); TaskScheduler::GetInstance()->Shutdown(); TaskScheduler::GetInstance()->JoinForTesting(); @@ -76,15 +129,104 @@ void ScopedTaskEnvironment::RunUntilIdle() { for (;;) { - TaskScheduler::GetInstance()->FlushForTesting(); + RunLoop run_loop; + // Register a closure to stop running tasks on the main thread when the + // TaskScheduler queue becomes empty. + task_tracker_->SetTaskQueueEmptyClosure(run_loop.QuitWhenIdleClosure()); + + // The closure registered above may never run if the TaskScheduler queue + // starts empty. Post a TaskScheduler tasks to make sure that the queue + // doesn't start empty. + PostTask(FROM_HERE, BindOnce(&DoNothing)); + + // Run main thread and TaskScheduler tasks. + task_tracker_->AllowRunRask(); TaskObserver task_observer; MessageLoop::current()->AddTaskObserver(&task_observer); - RunLoop().RunUntilIdle(); + run_loop.Run(); MessageLoop::current()->RemoveTaskObserver(&task_observer); - if (!task_observer.ran_task()) + // If the ExecutionControlMode is QUEUED and DisallowRunTasks() fails, + // another iteration is required to make sure that RunUntilIdle() doesn't + // return while TaskScheduler tasks are still allowed to run. + // + // If tasks other than the QuitWhenIdle closure ran on the main thread, they + // may have posted TaskScheduler tasks that didn't run yet. Another + // iteration is required to run them. + // + // Note: DisallowRunTasks() fails when a TaskScheduler task is running. A + // TaskScheduler task may be running after the TaskScheduler queue became + // empty even if no tasks ran on the main thread in these cases: + // - An undelayed task became ripe for execution. + // - A task was posted from an external thread. + if ((execution_control_mode_ == ExecutionControlMode::QUEUED && + task_tracker_->DisallowRunTasks()) || + task_observer.task_count() == 1) { return; + } + } +} + +ScopedTaskEnvironment::TestTaskTracker::TestTaskTracker( + ScopedTaskEnvironment* outer) + : outer_(outer), can_run_tasks_cv_(&lock_) {} + +void ScopedTaskEnvironment::TestTaskTracker::SetTaskQueueEmptyClosure( + OnceClosure task_queue_empty_closure) { + AutoLock auto_lock(lock_); + CHECK(!task_queue_empty_closure_); + task_queue_empty_closure_ = std::move(task_queue_empty_closure); +} + +void ScopedTaskEnvironment::TestTaskTracker::AllowRunRask() { + AutoLock auto_lock(lock_); + can_run_tasks_ = true; + can_run_tasks_cv_.Broadcast(); +} + +bool ScopedTaskEnvironment::TestTaskTracker::DisallowRunTasks() { + AutoLock auto_lock(lock_); + + // Can't disallow run task if there are tasks running. + if (num_tasks_running_ > 0) + return false; + + can_run_tasks_ = false; + return true; +} + +void ScopedTaskEnvironment::TestTaskTracker::PerformRunTask( + std::unique_ptr<internal::Task> task, + const SequenceToken& sequence_token) { + { + AutoLock auto_lock(lock_); + + while (!can_run_tasks_) + can_run_tasks_cv_.Wait(); + + ++num_tasks_running_; + } + + internal::TaskSchedulerImpl::TaskTrackerType::PerformRunTask(std::move(task), + sequence_token); + + { + AutoLock auto_lock(lock_); + + CHECK_GT(num_tasks_running_, 0); + CHECK(can_run_tasks_); + + --num_tasks_running_; + + // Notify the main thread when no undelayed tasks are queued and no task + // other than the current one is running. + if (num_tasks_running_ == 0 && + GetNumPendingUndelayedTasksForTesting() == 1 && + task_queue_empty_closure_) { + outer_->GetMainThreadTaskRunner()->PostTask( + FROM_HERE, std::move(task_queue_empty_closure_)); + } } }
diff --git a/base/test/scoped_task_environment.h b/base/test/scoped_task_environment.h index f46b516..6156c215 100644 --- a/base/test/scoped_task_environment.h +++ b/base/test/scoped_task_environment.h
@@ -26,7 +26,9 @@ // RunLoop::Run(UntilIdle) or ScopedTaskEnvironment::RunUntilIdle is called on // the thread where the ScopedTaskEnvironment lives. // -// Tasks posted through base/task_scheduler/post_task.h run on dedicated threads +// Tasks posted through base/task_scheduler/post_task.h run on dedicated +// threads. If ExecutionControlMode is QUEUED, they run when RunUntilIdle() or +// ~ScopedTaskEnvironment is called. If ExecutionControlMode is ASYNC, they run // as they are posted. // // All methods of ScopedTaskEnvironment must be called from the same thread. @@ -61,8 +63,17 @@ IO, }; + enum class ExecutionControlMode { + // Tasks are queued and executed when RunUntilIdle() is called. + QUEUED, + // Tasks run as they are posted. + ASYNC, + }; + ScopedTaskEnvironment( - MainThreadType main_thread_type = MainThreadType::DEFAULT); + MainThreadType main_thread_type = MainThreadType::DEFAULT, + ExecutionControlMode execution_control_mode = + ExecutionControlMode::ASYNC); // Waits until no undelayed TaskScheduler tasks remain. Then, unregisters the // TaskScheduler and the (Thread|Sequenced)TaskRunnerHandle. @@ -71,11 +82,15 @@ // Returns a TaskRunner that schedules tasks on the main thread. scoped_refptr<base::SingleThreadTaskRunner> GetMainThreadTaskRunner(); - // Synchronously runs (Thread|Sequenced)TaskRunnerHandle tasks until no - // undelayed (Thread|Sequenced)TaskRunnerHandle or TaskScheduler tasks remain. + // Runs tasks until both the (Thread|Sequenced)TaskRunnerHandle and the + // TaskScheduler queues are empty. void RunUntilIdle(); private: + class TestTaskTracker; + + const ExecutionControlMode execution_control_mode_; + // Note: |message_loop_| is an implementation detail and will be replaced in // the future, do NOT rely on the presence of a MessageLoop beyond // (Thread|Sequenced)TaskRunnerHandle and RunLoop. @@ -83,6 +98,9 @@ const TaskScheduler* task_scheduler_ = nullptr; + // Owned by |task_scheduler_|. + TestTaskTracker* const task_tracker_; + DISALLOW_COPY_AND_ASSIGN(ScopedTaskEnvironment); };
diff --git a/base/test/scoped_task_environment_unittest.cc b/base/test/scoped_task_environment_unittest.cc index 245cda28..fcc366dc 100644 --- a/base/test/scoped_task_environment_unittest.cc +++ b/base/test/scoped_task_environment_unittest.cc
@@ -6,7 +6,10 @@ #include "base/bind.h" #include "base/synchronization/atomic_flag.h" +#include "base/synchronization/waitable_event.h" #include "base/task_scheduler/post_task.h" +#include "base/test/test_timeouts.h" +#include "base/threading/platform_thread.h" #include "base/threading/thread_task_runner_handle.h" #include "testing/gtest/include/gtest/gtest.h" @@ -22,11 +25,11 @@ task_ran->Set(); } -} // namespace - -TEST(ScopedTaskEnvironmentTest, RunUntilIdle) { +void RunUntilIdleTest( + ScopedTaskEnvironment::ExecutionControlMode execution_control_mode) { AtomicFlag run_until_idle_returned; - ScopedTaskEnvironment scoped_task_environment; + ScopedTaskEnvironment scoped_task_environment( + ScopedTaskEnvironment::MainThreadType::DEFAULT, execution_control_mode); AtomicFlag first_main_thread_task_ran; ThreadTaskRunnerHandle::Get()->PostTask( @@ -58,5 +61,76 @@ EXPECT_TRUE(second_main_thread_task_ran.IsSet()); } +} // namespace + +TEST(ScopedTaskEnvironmentTest, QueuedRunUntilIdle) { + RunUntilIdleTest(ScopedTaskEnvironment::ExecutionControlMode::QUEUED); +} + +TEST(ScopedTaskEnvironmentTest, AsyncRunUntilIdle) { + RunUntilIdleTest(ScopedTaskEnvironment::ExecutionControlMode::ASYNC); +} + +// Verify that tasks posted to an ExecutionControlMode::QUEUED +// ScopedTaskEnvironment do not run outside of RunUntilIdle(). +TEST(ScopedTaskEnvironmentTest, QueuedTasksDoNotRunOutsideOfRunUntilIdle) { + ScopedTaskEnvironment scoped_task_environment( + ScopedTaskEnvironment::MainThreadType::DEFAULT, + ScopedTaskEnvironment::ExecutionControlMode::QUEUED); + + AtomicFlag run_until_idle_called; + PostTask(FROM_HERE, BindOnce( + [](AtomicFlag* run_until_idle_called) { + EXPECT_TRUE(run_until_idle_called->IsSet()); + }, + Unretained(&run_until_idle_called))); + PlatformThread::Sleep(TestTimeouts::tiny_timeout()); + run_until_idle_called.Set(); + scoped_task_environment.RunUntilIdle(); + + AtomicFlag other_run_until_idle_called; + PostTask(FROM_HERE, BindOnce( + [](AtomicFlag* other_run_until_idle_called) { + EXPECT_TRUE(other_run_until_idle_called->IsSet()); + }, + Unretained(&other_run_until_idle_called))); + PlatformThread::Sleep(TestTimeouts::tiny_timeout()); + other_run_until_idle_called.Set(); + scoped_task_environment.RunUntilIdle(); +} + +// Verify that a task posted to an ExecutionControlMode::QUEUED +// ScopedTaskEnvironment can run without a call to RunUntilIdle(). +TEST(ScopedTaskEnvironmentTest, AsyncTasksRunAsTheyArePosted) { + ScopedTaskEnvironment scoped_task_environment( + ScopedTaskEnvironment::MainThreadType::DEFAULT, + ScopedTaskEnvironment::ExecutionControlMode::ASYNC); + + WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, + WaitableEvent::InitialState::NOT_SIGNALED); + PostTask(FROM_HERE, + BindOnce([](WaitableEvent* task_ran) { task_ran->Signal(); }, + Unretained(&task_ran))); + task_ran.Wait(); +} + +// Verify that a task posted to an ExecutionControlMode::QUEUED +// ScopedTaskEnvironment after a call to RunUntilIdle() can run without another +// call to RunUntilIdle(). +TEST(ScopedTaskEnvironmentTest, AsyncTasksRunAsTheyArePostedAfterRunUntilIdle) { + ScopedTaskEnvironment scoped_task_environment( + ScopedTaskEnvironment::MainThreadType::DEFAULT, + ScopedTaskEnvironment::ExecutionControlMode::ASYNC); + + scoped_task_environment.RunUntilIdle(); + + WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, + WaitableEvent::InitialState::NOT_SIGNALED); + PostTask(FROM_HERE, + BindOnce([](WaitableEvent* task_ran) { task_ran->Signal(); }, + Unretained(&task_ran))); + task_ran.Wait(); +} + } // namespace test } // namespace base
diff --git a/cc/surfaces/compositor_frame_sink_support_unittest.cc b/cc/surfaces/compositor_frame_sink_support_unittest.cc index fe1156e..d39b9e2 100644 --- a/cc/surfaces/compositor_frame_sink_support_unittest.cc +++ b/cc/surfaces/compositor_frame_sink_support_unittest.cc
@@ -123,6 +123,7 @@ void OnSurfaceDamaged(const SurfaceId& id, bool* changed) override { *changed = true; } + void OnSurfaceDiscarded(const SurfaceId& surface_id) override {} void SubmitCompositorFrameWithResources(ResourceId* resource_ids, size_t num_resource_ids) {
diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc index e3693207..846897b 100644 --- a/cc/surfaces/display.cc +++ b/cc/surfaces/display.cc
@@ -412,6 +412,11 @@ void Display::OnSurfaceCreated(const SurfaceInfo& surface_info) {} +void Display::OnSurfaceDiscarded(const SurfaceId& surface_id) { + if (aggregator_) + aggregator_->ReleaseResources(surface_id); +} + const SurfaceId& Display::CurrentSurfaceId() { return current_surface_id_; }
diff --git a/cc/surfaces/display.h b/cc/surfaces/display.h index 314cb405..df0f717 100644 --- a/cc/surfaces/display.h +++ b/cc/surfaces/display.h
@@ -88,6 +88,7 @@ // SurfaceObserver implementation. void OnSurfaceDamaged(const SurfaceId& surface, bool* changed) override; void OnSurfaceCreated(const SurfaceInfo& surface_info) override; + void OnSurfaceDiscarded(const SurfaceId& surface_id) override; bool has_scheduler() const { return !!scheduler_; } DirectRenderer* renderer_for_testing() const { return renderer_.get(); }
diff --git a/cc/surfaces/surface_manager.cc b/cc/surfaces/surface_manager.cc index cbdb78c..0eb2b21 100644 --- a/cc/surfaces/surface_manager.cc +++ b/cc/surfaces/surface_manager.cc
@@ -494,6 +494,8 @@ } void SurfaceManager::SurfaceDiscarded(Surface* surface) { + for (auto& observer : observer_list_) + observer.OnSurfaceDiscarded(surface->surface_id()); if (dependency_tracker_) dependency_tracker_->OnSurfaceDiscarded(surface); }
diff --git a/cc/surfaces/surface_observer.h b/cc/surfaces/surface_observer.h index e1c182a..9b2fc1c5 100644 --- a/cc/surfaces/surface_observer.h +++ b/cc/surfaces/surface_observer.h
@@ -18,6 +18,9 @@ // Runs when a Surface is damaged. *changed should be set to true if this // causes a Display to be damaged. virtual void OnSurfaceDamaged(const SurfaceId& surface_id, bool* changed) = 0; + + // Called when a surface is garbage-collected. + virtual void OnSurfaceDiscarded(const SurfaceId& surface_id) = 0; }; } // namespace cc
diff --git a/cc/surfaces/surface_synchronization_unittest.cc b/cc/surfaces/surface_synchronization_unittest.cc index ae7d7487..445ffc0b 100644 --- a/cc/surfaces/surface_synchronization_unittest.cc +++ b/cc/surfaces/surface_synchronization_unittest.cc
@@ -155,6 +155,7 @@ void OnSurfaceDamaged(const SurfaceId& surface_id, bool* changed) override { damaged_surfaces_.insert(surface_id); } + void OnSurfaceDiscarded(const SurfaceId& surface_id) override {} protected: testing::NiceMock<MockCompositorFrameSinkSupportClient> support_client_;
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index e3cec7c..71ead755 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -347,6 +347,7 @@ ":app_hooks_java", ":chrome_java", ":chrome_java_resources", + ":partner_location_descriptor_proto_java", "//base:base_java", "//base:base_java_test_support", "//chrome/android/webapk/libs/client:client_java", @@ -376,6 +377,7 @@ "//third_party/WebKit/public:android_mojo_bindings_java", "//third_party/WebKit/public:blink_headers_java", "//third_party/WebKit/public:mojo_bindings_java", + "//third_party/android_protobuf:protobuf_nano_javalib", "//third_party/android_tools:android_support_annotations_java", "//third_party/android_tools:android_support_v7_appcompat_java", "//third_party/android_tools:android_support_v7_mediarouter_java",
diff --git a/chrome/android/java/res/drawable-hdpi/diners_card.png b/chrome/android/java/res/drawable-hdpi/diners_card.png new file mode 100644 index 0000000..d276c42b --- /dev/null +++ b/chrome/android/java/res/drawable-hdpi/diners_card.png Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/jcb_card.png b/chrome/android/java/res/drawable-hdpi/jcb_card.png new file mode 100644 index 0000000..03b2f5a --- /dev/null +++ b/chrome/android/java/res/drawable-hdpi/jcb_card.png Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/mir_card.png b/chrome/android/java/res/drawable-hdpi/mir_card.png deleted file mode 100644 index c686f15..0000000 --- a/chrome/android/java/res/drawable-hdpi/mir_card.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/pr_amex.png b/chrome/android/java/res/drawable-hdpi/pr_amex.png deleted file mode 100644 index 8584b7a8..0000000 --- a/chrome/android/java/res/drawable-hdpi/pr_amex.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/pr_dinersclub.png b/chrome/android/java/res/drawable-hdpi/pr_dinersclub.png deleted file mode 100644 index 8875789..0000000 --- a/chrome/android/java/res/drawable-hdpi/pr_dinersclub.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/pr_discover.png b/chrome/android/java/res/drawable-hdpi/pr_discover.png deleted file mode 100644 index a34d9bd..0000000 --- a/chrome/android/java/res/drawable-hdpi/pr_discover.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/pr_generic.png b/chrome/android/java/res/drawable-hdpi/pr_generic.png deleted file mode 100644 index fdec48b..0000000 --- a/chrome/android/java/res/drawable-hdpi/pr_generic.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/pr_jcb.png b/chrome/android/java/res/drawable-hdpi/pr_jcb.png deleted file mode 100644 index 1547fe1..0000000 --- a/chrome/android/java/res/drawable-hdpi/pr_jcb.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/pr_mc.png b/chrome/android/java/res/drawable-hdpi/pr_mc.png deleted file mode 100644 index 5731888..0000000 --- a/chrome/android/java/res/drawable-hdpi/pr_mc.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/pr_mir.png b/chrome/android/java/res/drawable-hdpi/pr_mir.png deleted file mode 100644 index 2a51a41a..0000000 --- a/chrome/android/java/res/drawable-hdpi/pr_mir.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/pr_unionpay.png b/chrome/android/java/res/drawable-hdpi/pr_unionpay.png deleted file mode 100644 index 9c61af1..0000000 --- a/chrome/android/java/res/drawable-hdpi/pr_unionpay.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/pr_visa.png b/chrome/android/java/res/drawable-hdpi/pr_visa.png deleted file mode 100644 index 1f8dc61..0000000 --- a/chrome/android/java/res/drawable-hdpi/pr_visa.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/diners_card.png b/chrome/android/java/res/drawable-mdpi/diners_card.png new file mode 100644 index 0000000..c8caf67 --- /dev/null +++ b/chrome/android/java/res/drawable-mdpi/diners_card.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/jcb_card.png b/chrome/android/java/res/drawable-mdpi/jcb_card.png new file mode 100644 index 0000000..8c603de --- /dev/null +++ b/chrome/android/java/res/drawable-mdpi/jcb_card.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/mir_card.png b/chrome/android/java/res/drawable-mdpi/mir_card.png deleted file mode 100644 index a17a51b..0000000 --- a/chrome/android/java/res/drawable-mdpi/mir_card.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/pr_amex.png b/chrome/android/java/res/drawable-mdpi/pr_amex.png deleted file mode 100644 index 67dfb96..0000000 --- a/chrome/android/java/res/drawable-mdpi/pr_amex.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/pr_dinersclub.png b/chrome/android/java/res/drawable-mdpi/pr_dinersclub.png deleted file mode 100644 index a3446c40..0000000 --- a/chrome/android/java/res/drawable-mdpi/pr_dinersclub.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/pr_discover.png b/chrome/android/java/res/drawable-mdpi/pr_discover.png deleted file mode 100644 index c6e04e9..0000000 --- a/chrome/android/java/res/drawable-mdpi/pr_discover.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/pr_generic.png b/chrome/android/java/res/drawable-mdpi/pr_generic.png deleted file mode 100644 index a93ff32d..0000000 --- a/chrome/android/java/res/drawable-mdpi/pr_generic.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/pr_jcb.png b/chrome/android/java/res/drawable-mdpi/pr_jcb.png deleted file mode 100644 index 66495ce5..0000000 --- a/chrome/android/java/res/drawable-mdpi/pr_jcb.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/pr_mc.png b/chrome/android/java/res/drawable-mdpi/pr_mc.png deleted file mode 100644 index bcdf48f..0000000 --- a/chrome/android/java/res/drawable-mdpi/pr_mc.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/pr_mir.png b/chrome/android/java/res/drawable-mdpi/pr_mir.png deleted file mode 100644 index fc97556..0000000 --- a/chrome/android/java/res/drawable-mdpi/pr_mir.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/pr_unionpay.png b/chrome/android/java/res/drawable-mdpi/pr_unionpay.png deleted file mode 100644 index 0e11c0f..0000000 --- a/chrome/android/java/res/drawable-mdpi/pr_unionpay.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/pr_visa.png b/chrome/android/java/res/drawable-mdpi/pr_visa.png deleted file mode 100644 index c0c8c08..0000000 --- a/chrome/android/java/res/drawable-mdpi/pr_visa.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/diners_card.png b/chrome/android/java/res/drawable-xhdpi/diners_card.png new file mode 100644 index 0000000..f3cc7bfd --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/diners_card.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/jcb_card.png b/chrome/android/java/res/drawable-xhdpi/jcb_card.png new file mode 100644 index 0000000..d96b48a --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/jcb_card.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/mir_card.png b/chrome/android/java/res/drawable-xhdpi/mir_card.png deleted file mode 100644 index 8fdae43..0000000 --- a/chrome/android/java/res/drawable-xhdpi/mir_card.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/pr_amex.png b/chrome/android/java/res/drawable-xhdpi/pr_amex.png deleted file mode 100644 index f29dcdf57..0000000 --- a/chrome/android/java/res/drawable-xhdpi/pr_amex.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/pr_dinersclub.png b/chrome/android/java/res/drawable-xhdpi/pr_dinersclub.png deleted file mode 100644 index c61096b..0000000 --- a/chrome/android/java/res/drawable-xhdpi/pr_dinersclub.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/pr_discover.png b/chrome/android/java/res/drawable-xhdpi/pr_discover.png deleted file mode 100644 index 6d8f2ff2..0000000 --- a/chrome/android/java/res/drawable-xhdpi/pr_discover.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/pr_generic.png b/chrome/android/java/res/drawable-xhdpi/pr_generic.png deleted file mode 100644 index 8dd4609..0000000 --- a/chrome/android/java/res/drawable-xhdpi/pr_generic.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/pr_jcb.png b/chrome/android/java/res/drawable-xhdpi/pr_jcb.png deleted file mode 100644 index 2a18c032..0000000 --- a/chrome/android/java/res/drawable-xhdpi/pr_jcb.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/pr_mc.png b/chrome/android/java/res/drawable-xhdpi/pr_mc.png deleted file mode 100644 index ade774b8..0000000 --- a/chrome/android/java/res/drawable-xhdpi/pr_mc.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/pr_mir.png b/chrome/android/java/res/drawable-xhdpi/pr_mir.png deleted file mode 100644 index 1b9e5330..0000000 --- a/chrome/android/java/res/drawable-xhdpi/pr_mir.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/pr_unionpay.png b/chrome/android/java/res/drawable-xhdpi/pr_unionpay.png deleted file mode 100644 index 33f62de..0000000 --- a/chrome/android/java/res/drawable-xhdpi/pr_unionpay.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/pr_visa.png b/chrome/android/java/res/drawable-xhdpi/pr_visa.png deleted file mode 100644 index 493c2ab..0000000 --- a/chrome/android/java/res/drawable-xhdpi/pr_visa.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/diners_card.png b/chrome/android/java/res/drawable-xxhdpi/diners_card.png new file mode 100644 index 0000000..ed5aae44 --- /dev/null +++ b/chrome/android/java/res/drawable-xxhdpi/diners_card.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/jcb_card.png b/chrome/android/java/res/drawable-xxhdpi/jcb_card.png new file mode 100644 index 0000000..aed168f9 --- /dev/null +++ b/chrome/android/java/res/drawable-xxhdpi/jcb_card.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/mir_card.png b/chrome/android/java/res/drawable-xxhdpi/mir_card.png deleted file mode 100644 index 743fcff2..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/mir_card.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/pr_amex.png b/chrome/android/java/res/drawable-xxhdpi/pr_amex.png deleted file mode 100644 index 9cb774c7..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/pr_amex.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/pr_dinersclub.png b/chrome/android/java/res/drawable-xxhdpi/pr_dinersclub.png deleted file mode 100644 index 99c5aa2..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/pr_dinersclub.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/pr_discover.png b/chrome/android/java/res/drawable-xxhdpi/pr_discover.png deleted file mode 100644 index 8c84098..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/pr_discover.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/pr_generic.png b/chrome/android/java/res/drawable-xxhdpi/pr_generic.png deleted file mode 100644 index da56787c..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/pr_generic.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/pr_jcb.png b/chrome/android/java/res/drawable-xxhdpi/pr_jcb.png deleted file mode 100644 index 6a8adc5..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/pr_jcb.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/pr_mc.png b/chrome/android/java/res/drawable-xxhdpi/pr_mc.png deleted file mode 100644 index 450a1b6c..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/pr_mc.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/pr_mir.png b/chrome/android/java/res/drawable-xxhdpi/pr_mir.png deleted file mode 100644 index 5d25999..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/pr_mir.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/pr_unionpay.png b/chrome/android/java/res/drawable-xxhdpi/pr_unionpay.png deleted file mode 100644 index e6b8b12a..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/pr_unionpay.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/pr_visa.png b/chrome/android/java/res/drawable-xxhdpi/pr_visa.png deleted file mode 100644 index 53b39f8..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/pr_visa.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/diners_card.png b/chrome/android/java/res/drawable-xxxhdpi/diners_card.png new file mode 100644 index 0000000..fc1784d --- /dev/null +++ b/chrome/android/java/res/drawable-xxxhdpi/diners_card.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/jcb_card.png b/chrome/android/java/res/drawable-xxxhdpi/jcb_card.png new file mode 100644 index 0000000..bcaa6b8 --- /dev/null +++ b/chrome/android/java/res/drawable-xxxhdpi/jcb_card.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/mir_card.png b/chrome/android/java/res/drawable-xxxhdpi/mir_card.png deleted file mode 100644 index a2324c0..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/mir_card.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/pr_amex.png b/chrome/android/java/res/drawable-xxxhdpi/pr_amex.png deleted file mode 100644 index 318ec6584..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/pr_amex.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/pr_dinersclub.png b/chrome/android/java/res/drawable-xxxhdpi/pr_dinersclub.png deleted file mode 100644 index 87fa3c4..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/pr_dinersclub.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/pr_discover.png b/chrome/android/java/res/drawable-xxxhdpi/pr_discover.png deleted file mode 100644 index b8109ff..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/pr_discover.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/pr_generic.png b/chrome/android/java/res/drawable-xxxhdpi/pr_generic.png deleted file mode 100644 index bda5b34..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/pr_generic.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/pr_jcb.png b/chrome/android/java/res/drawable-xxxhdpi/pr_jcb.png deleted file mode 100644 index d9919ef..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/pr_jcb.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/pr_mc.png b/chrome/android/java/res/drawable-xxxhdpi/pr_mc.png deleted file mode 100644 index 4cdd3a52..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/pr_mc.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/pr_mir.png b/chrome/android/java/res/drawable-xxxhdpi/pr_mir.png deleted file mode 100644 index 56934a4..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/pr_mir.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/pr_unionpay.png b/chrome/android/java/res/drawable-xxxhdpi/pr_unionpay.png deleted file mode 100644 index fa1bd84..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/pr_unionpay.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/pr_visa.png b/chrome/android/java/res/drawable-xxxhdpi/pr_visa.png deleted file mode 100644 index ef6aa856..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/pr_visa.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable/discover_card.xml b/chrome/android/java/res/drawable/discover_card.xml index 7609429..d7d075c73 100644 --- a/chrome/android/java/res/drawable/discover_card.xml +++ b/chrome/android/java/res/drawable/discover_card.xml
@@ -12,122 +12,64 @@ android:viewportHeight="80"> <path + android:pathData="M0,8C0,3.58 3.59,0 8.01,0L119.99,0C124.42,0 128,3.58 128,8L128,72C128,76.42 124.41,80 119.99,80L8.01,80C3.58,80 0,76.42 0,72L0,8Z" + android:strokeColor="#00000000" android:fillColor="#E0E0E0" - android:fillType="evenOdd" - android:strokeWidth="1" - android:pathData="M0,8.00005106 C0,3.58174486 3.59075293,0 8.00697327,0 L119.993027,0 -C124.415156,0 128,3.5797863 128,8.00005106 L128,71.9999489 C128,76.4182551 -124.409247,80 119.993027,80 L8.00697327,80 C3.58484404,80 0,76.4202137 -0,71.9999489 L0,8.00005106 Z" /> + android:strokeWidth="1"/> <path + android:pathData="M4,8L4,72C4,74.21 5.79,76 8.01,76L119.99,76C122.2,76 124,74.21 124,72L124,8C124,5.79 122.21,4 119.99,4L8.01,4C5.8,4 4,5.79 4,8Z" + android:strokeColor="#00000000" android:fillColor="#FFFFFF" - android:fillType="evenOdd" - android:strokeWidth="1" - android:pathData="M4,8.00005106 L4,71.9999489 C4,74.2094718 5.79238055,76 8.00697327,76 -L119.993027,76 C122.203379,76 124,74.2058465 124,71.9999489 L124,8.00005106 -C124,5.79052815 122.207619,4 119.993027,4 L8.00697327,4 C5.79662132,4 -4,5.79415354 4,8.00005106 Z" /> - <group - android:translateX="4.000000" - android:translateY="4.000000"> - <path - android:fillColor="#FFFFFF" - android:fillType="evenOdd" - android:strokeWidth="1" - android:pathData="M0,4.00005106 L0,67.9999489 C0,70.2094718 1.79238055,72 4.00697327,72 -L115.993027,72 C118.203379,72 120,70.2058465 120,67.9999489 L120,4.00005106 -C120,1.79052815 118.207619,0 115.993027,0 L4.00697327,0 C1.79662132,0 -0,1.79415354 0,4.00005106 Z" /> - <path - android:fillColor="#F68221" - android:fillType="evenOdd" - android:strokeWidth="1" - android:pathData="M32,72 L115.990154,71.9999999 C118.204731,71.9999999 120,70.2132052 -120,68.0007251 L119.999999,42 C119.999999,42 86.8891933,63.0977749 32,72 Z" /> - </group> - <group - android:translateX="12.000000" - android:translateY="27.000000"> - <path - android:fillColor="#231F20" - android:fillType="evenOdd" - android:strokeWidth="1" - android:pathData="M4.80389506,0.997038492 L0.0556034122,0.997038492 L0.0556034122,16.9970385 -L4.77945083,16.9970385 C7.29109545,16.9970385 9.10607951,16.4251888 -10.69801,15.1488439 C12.5893823,13.6396324 13.7077058,11.3610768 -13.7077058,9.00882921 C13.7077058,4.28664792 10.0502379,0.997038492 -4.80389506,0.997038492 L4.80389506,0.997038492 Z M8.5835841,13.0176722 -C7.56609303,13.9019759 6.24610462,14.2881218 4.15612297,14.2881218 -L3.28835281,14.2881218 L3.28835281,3.7089029 L4.15612297,3.7089029 -C6.24610462,3.7089029 7.51414904,4.0685197 8.5835841,5.00293385 -C9.70190761,5.96387711 10.3741239,7.45245485 10.3741239,8.98524778 -C10.3771795,10.5209884 9.70190761,12.056729 8.5835841,13.0176722 -L8.5835841,13.0176722 Z" /> - <path - android:fillColor="#231F20" - android:fillType="evenOdd" - android:strokeWidth="1" - android:pathData="M 15.1957483 0.997038492 H 18.43155323 V 16.997038492 H 15.1957483 V 0.997038492 Z" /> - <path - android:fillColor="#231F20" - android:fillType="evenOdd" - android:strokeWidth="1" - android:pathData="M26.3423171,7.16111621 C24.4020563,6.46569698 23.8306725,6.00701621 -23.8306725,5.13996159 C23.8306725,4.12790466 24.845108,3.35850466 -26.2414846,3.35850466 C27.2100872,3.35850466 28.0075802,3.74320466 -28.8509062,4.6605662 L30.5436691,2.51512388 C29.1534035,1.33735003 -27.4881404,0.733666952 25.6701008,0.733666952 C22.7367932,0.733666952 -20.4970906,2.70747388 20.4970906,5.33527082 C20.4970906,7.54877544 -21.5390259,8.68216083 24.5762215,9.73860622 C25.8412104,10.1706539 -26.4859269,10.4606585 26.8128685,10.6530085 C27.4606406,11.0613824 -27.7814711,11.6413916 27.7814711,12.3160962 C27.7814711,13.6181578 -26.7120361,14.582867 25.2698265,14.582867 C23.7267845,14.582867 -22.4831843,13.8371409 21.7406908,12.4403839 L19.6507092,14.390517 -C21.1418072,16.5093263 22.932347,17.4474024 25.3920476,17.4474024 -C28.7531292,17.4474024 31.1119974,15.2842047 31.1119974,12.1740532 -C31.1119974,9.62023699 30.0211737,8.46613699 26.3423171,7.16111621 -L26.3423171,7.16111621 Z" /> - <path - android:fillColor="#231F20" - android:fillType="evenOdd" - android:strokeWidth="1" - android:pathData="M32.132544,9.04022776 C32.132544,13.7602009 35.9611215,17.4207693 -40.8866338,17.4207693 C42.2799549,17.4207693 43.4716111,17.1544386 -44.9413205,16.4856524 L44.9413205,12.7984509 C43.6488318,14.0531647 -42.5030085,14.5562339 41.0363547,14.5562339 C37.7791611,14.5562339 -35.4661259,12.2687485 35.4661259,9.01655391 C35.4661259,5.93303544 -37.8524938,3.50054773 40.8866338,3.50054773 C42.4296758,3.50054773 -43.5968878,4.03320927 44.9413205,5.30863774 L44.9413205,1.62143619 -C43.5204996,0.923057722 42.3532876,0.636012336 40.9630221,0.636012336 -C36.061954,0.636012336 32.132544,4.37056158 32.132544,9.04022776 -L32.132544,9.04022776 Z" /> - <path - android:fillColor="#231F20" - android:fillType="evenOdd" - android:strokeWidth="1" - android:pathData="M 70.5924841 11.7902985 L 66.1680785 0.997038492 L 62.6358873 0.997038492 L 69.67277 17.477038 L 71.4144214 17.477038 L 78.5796362 0.997038492 L 75.0718893 0.997038492 Z" /> - <path - android:fillColor="#F68221" - android:fillType="evenOdd" - android:strokeWidth="1" - android:pathData="M 54.7155963 0.31999969 C 59.681092217 0.31999969 63.70642199 4.22253031673 63.70642199 9.03654581 C 63.70642199 13.8505613033 59.681092217 17.75309193 54.7155963 17.75309193 C 49.750100383 17.75309193 45.72477061 13.8505613033 45.72477061 9.03654581 C 45.72477061 4.22253031673 49.750100383 0.31999969 54.7155963 0.31999969 Z" /> - <path - android:fillColor="#231F20" - android:fillType="evenOdd" - android:strokeWidth="1" - android:pathData="M 80.040179 16.9970385 L 89.2159318 16.9970385 L 89.2159318 14.2881218 L 83.2729284 14.2881218 L 83.2729284 9.96977246 L 88.9959337 9.96977246 L 88.9959337 7.26085574 L 83.2729284 7.26085574 L 83.2729284 3.7089029 L 89.2159318 3.7089029 L 89.2159318 0.997038492 L 80.040179 0.997038492 Z" /> - <path - android:fillColor="#231F20" - android:fillType="evenOdd" - android:strokeWidth="1" - android:pathData="M102.024708,5.722179 C102.024708,2.72733744 99.8858381,0.999997723 -96.1550375,0.999997723 L91.3578574,0.999997723 L91.3578574,16.9999977 -L94.5875513,16.9999977 L94.5875513,10.5740582 L95.0092142,10.5740582 -L99.4855638,16.9999977 L103.463862,16.9999977 L98.2419636,10.2586565 -C100.683331,9.7781849 102.024708,8.17170001 102.024708,5.722179 -L102.024708,5.722179 Z M95.5347652,8.36329912 L94.5906068,8.36329912 -L94.5906068,3.51731534 L95.5867092,3.51731534 C97.6003026,3.51731534 -98.6972374,4.33087466 98.6972374,5.88724901 C98.6941819,7.49668158 -97.6003026,8.36329912 95.5347652,8.36329912 L95.5347652,8.36329912 Z" /> - </group> + android:strokeWidth="1"/> + <path + android:pathData="M4,8L4,72C4,74.21 5.79,76 8.01,76L119.99,76C122.2,76 124,74.21 124,72L124,8C124,5.79 122.21,4 119.99,4L8.01,4C5.8,4 4,5.79 4,8Z" + android:strokeColor="#00000000" + android:fillColor="#FFFFFF" + android:strokeWidth="1"/> + <path + android:pathData="M36,76L119.99,76C122.2,76 124,74.21 124,72L124,46C124,46 90.89,67.1 36,76Z" + android:strokeColor="#00000000" + android:fillColor="#F68221" + android:strokeWidth="1"/> + <path + android:pathData="M16.8,28L12.06,28L12.06,44L16.78,44C19.29,44 21.11,43.43 22.7,42.15C24.59,40.64 25.71,38.36 25.71,36.01C25.71,31.29 22.05,28 16.8,28L16.8,28ZM20.58,40.02C19.57,40.9 18.25,41.29 16.16,41.29L15.29,41.29L15.29,30.71L16.16,30.71C18.25,30.71 19.51,31.07 20.58,32C21.7,32.96 22.37,34.45 22.37,35.99C22.38,37.52 21.7,39.06 20.58,40.02L20.58,40.02Z" + android:strokeColor="#00000000" + android:fillColor="#231F20" + android:strokeWidth="1"/> + <path + android:pathData="M27.2,28h3.24v16h-3.24z" + android:strokeColor="#00000000" + android:fillColor="#231F20" + android:strokeWidth="1"/> + <path + android:pathData="M38.34,34.16C36.4,33.47 35.83,33.01 35.83,32.14C35.83,31.13 36.85,30.36 38.24,30.36C39.21,30.36 40.01,30.74 40.85,31.66L42.54,29.52C41.15,28.34 39.49,27.73 37.67,27.73C34.74,27.73 32.5,29.71 32.5,32.34C32.5,34.55 33.54,35.68 36.58,36.74C37.84,37.17 38.49,37.46 38.81,37.65C39.46,38.06 39.78,38.64 39.78,39.32C39.78,40.62 38.71,41.58 37.27,41.58C35.73,41.58 34.48,40.84 33.74,39.44L31.65,41.39C33.14,43.51 34.93,44.45 37.39,44.45C40.75,44.45 43.11,42.28 43.11,39.17C43.11,36.62 42.02,35.47 38.34,34.16L38.34,34.16Z" + android:strokeColor="#00000000" + android:fillColor="#231F20" + android:strokeWidth="1"/> + <path + android:pathData="M44.13,36.04C44.13,40.76 47.96,44.42 52.89,44.42C54.28,44.42 55.47,44.15 56.94,43.49L56.94,39.8C55.65,41.05 54.5,41.56 53.04,41.56C49.78,41.56 47.47,39.27 47.47,36.02C47.47,32.93 49.85,30.5 52.89,30.5C54.43,30.5 55.6,31.03 56.94,32.31L56.94,28.62C55.52,27.92 54.35,27.64 52.96,27.64C48.06,27.64 44.13,31.37 44.13,36.04L44.13,36.04Z" + android:strokeColor="#00000000" + android:fillColor="#231F20" + android:strokeWidth="1"/> + <path + android:pathData="M82.59,38.79l-4.42,-10.79l-3.53,0l7.04,16.48l1.74,0l7.17,-16.48l-3.51,0z" + android:strokeColor="#00000000" + android:fillColor="#231F20" + android:strokeWidth="1"/> + <path + android:pathData="M57.72,36.04a8.99,8.72 0,1 0,17.98 0a8.99,8.72 0,1 0,-17.98 0z" + android:strokeColor="#00000000" + android:fillColor="#F68221" + android:strokeWidth="1"/> + <path + android:pathData="M92.04,44l9.18,0l0,-2.71l-5.94,0l0,-4.32l5.72,0l0,-2.71l-5.72,0l0,-3.55l5.94,0l0,-2.71l-9.18,0z" + android:strokeColor="#00000000" + android:fillColor="#231F20" + android:strokeWidth="1"/> + <path + android:pathData="M114.02,32.72C114.02,29.73 111.89,28 108.16,28L103.36,28L103.36,44L106.59,44L106.59,37.57L107.01,37.57L111.49,44L115.46,44L110.24,37.26C112.68,36.78 114.02,35.17 114.02,32.72L114.02,32.72ZM107.53,35.36L106.59,35.36L106.59,30.52L107.59,30.52C109.6,30.52 110.7,31.33 110.7,32.89C110.69,34.5 109.6,35.36 107.53,35.36L107.53,35.36Z" + android:strokeColor="#00000000" + android:fillColor="#231F20" + android:strokeWidth="1"/> </vector> +
diff --git a/chrome/android/java/res/drawable/mir_card.xml b/chrome/android/java/res/drawable/mir_card.xml new file mode 100644 index 0000000..06deb0c --- /dev/null +++ b/chrome/android/java/res/drawable/mir_card.xml
@@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + tools:targetApi="21" + android:width="32dp" + android:height="20dp" + android:viewportWidth="128" + android:viewportHeight="80"> + + <path + android:fillColor="#E0E0E0" + android:fillType="evenOdd" + android:strokeWidth="1" + android:pathData="M0,8.00005106 C0,3.58174486 3.59075293,0 8.00697327,0 L119.993027,0 +C124.415156,0 128,3.5797863 128,8.00005106 L128,71.9999489 C128,76.4182551 +124.409247,80 119.993027,80 L8.00697327,80 C3.58484404,80 0,76.4202137 +0,71.9999489 L0,8.00005106 Z" /> + <path + android:fillColor="#FFFFFF" + android:fillType="evenOdd" + android:strokeWidth="1" + android:pathData="M4,8.00005106 L4,71.9999489 C4,74.2094718 5.79238055,76 8.00697327,76 +L119.993027,76 C122.203379,76 124,74.2058465 124,71.9999489 L124,8.00005106 +C124,5.79052815 122.207619,4 119.993027,4 L8.00697327,4 C5.79662132,4 +4,5.79415354 4,8.00005106 Z" /> + <path android:fillColor="#3BA536" + android:pathData="M34.86,29.77L31.05,42.52C30.95,42.86 30.44,42.86 30.34,42.52L26.53,29.77C25.87,27.54 23.74,26 21.31,26L21.31,26L12,26L12,54L21.31,54L21.31,37.62C21.31,37.22 21.9,37.13 22.03,37.51L27.47,54L33.92,54L39.36,37.51C39.48,37.13 40.08,37.22 40.08,37.62L40.08,54L49.39,54L49.39,26L40.08,26L40.08,26C37.65,26 35.52,27.54 34.86,29.77" + android:strokeColor="#00000000" android:strokeWidth="1"/> + <path android:fillColor="#3BA536" + android:pathData="M74.71,26C72.62,26 70.72,27.17 69.84,28.99L63.44,42.25C63.28,42.59 62.74,42.48 62.74,42.1L62.74,26L53.43,26L53.43,54L61.31,54L61.31,54C63.38,54 65.25,52.83 66.09,51.01L72.58,36.87C72.74,36.52 73.28,36.63 73.28,37.01L73.28,54L73.28,54L73.28,54L82.59,54L82.59,26L74.71,26Z" + android:strokeColor="#00000000" android:strokeWidth="1"/> + <path android:fillColor="#3BA536" + android:pathData="M86.63,38.9L86.63,54L95.94,54L95.94,45.06L105.85,45.06C110.1,45.06 113.73,42.5 115.15,38.9L86.63,38.9Z" + android:strokeColor="#00000000" android:strokeWidth="1"/> + <path android:fillColor="#0093D3" + android:pathData="M105.85,26L85.42,26C86.14,32.48 91.86,37.53 98.81,37.53L115.57,37.53C115.72,36.88 115.8,36.21 115.8,35.53L115.8,35.53C115.8,30.27 111.34,26 105.85,26" + android:strokeColor="#00000000" android:strokeWidth="1"/> +</vector> +
diff --git a/chrome/android/java/res/drawable/unionpay_card.xml b/chrome/android/java/res/drawable/unionpay_card.xml index 7e1a077..4e3c228 100644 --- a/chrome/android/java/res/drawable/unionpay_card.xml +++ b/chrome/android/java/res/drawable/unionpay_card.xml
@@ -4,74 +4,111 @@ found in the LICENSE file. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - tools:targetApi="21" - android:viewportWidth="128" - android:viewportHeight="80" - android:width="32dp" - android:height="20dp"> + xmlns:tools="http://schemas.android.com/tools" + tools:targetApi="21" + android:width="32dp" + android:height="20dp" + android:viewportWidth="128" + android:viewportHeight="80"> + <path - android:pathData="M0 8.0000511C0 3.5817449 3.5907529 0 8.0069733 0L119.99303 0C124.41516 0 128 3.5797863 128 8.0000511l0 63.9998979C128 76.418255 124.40925 80 119.99303 80L8.0069733 80C3.584844 80 0 76.420214 0 71.999949L0 8.0000511Z" - android:fillColor="#e0e0e0" /> + android:pathData="M0,8C0,3.58 3.59,0 8.01,0L119.99,0C124.42,0 128,3.58 128,8L128,72C128,76.42 124.41,80 119.99,80L8.01,80C3.58,80 0,76.42 0,72L0,8Z" + android:strokeColor="#00000000" + android:fillColor="#E0E0E0" + android:strokeWidth="1"/> <path - android:pathData="M4 8.0000511L4 71.999949C4 74.209472 5.7923805 76 8.0069733 76L119.99303 76C122.20338 76 124 74.205847 124 71.999949L124 8.0000511C124 5.7905281 122.20762 4 119.99303 4L8.0069733 4C5.7966213 4 4 5.7941535 4 8.0000511Z" - android:fillColor="#ffffff" /> - <group - android:translateX="19" - android:translateY="12"> - <path - android:pathData="M20.740341 50.248637L31.191144 5.6617631c0.741483 -3.1240388 3.871032 -5.66198057573 7.006602 -5.66198057573l-20.582577 0c-3.137759 0 -6.273875 2.53794177573 -7.004961 5.66198057573L0.1533857 50.248637c-0.73108561 3.113709 1.222489 5.653281 4.3520388 5.653281l20.5803885 0c-3.139947 0 -5.083125 -2.539572 -4.345472 -5.653281" - android:fillColor="#e21836" /> - <path - android:pathData="M45.534102 50.248637L55.987094 5.6617631C56.717633 2.5377243 59.85156 -0.00021747573 62.991507 -0.00021747573l-22.925225 0 -1.868208 0c-3.136116 0 -6.265119 2.53794177573 -7.007149 5.66198057573L20.740122 50.248637c-0.737105 3.113709 1.206072 5.653281 4.346019 5.653281l1.868208 0 22.931792 0c-3.139947 0 -5.087502 -2.539572 -4.352039 -5.653281" - android:fillColor="#00447c" /> - <path - android:pathData="M85.442676 -0.0001631068l-21.426937 0 -1.023848 0c-3.140495 0 -6.273875 2.5379417068 -7.004961 5.6619806068L45.533938 50.248691c-0.734916 3.113165 1.212092 5.653282 4.352039 5.653282l1.017829 0 21.422559 0c3.138306 0 6.278253 -2.540117 7.015905 -5.653282L89.792526 5.6618175C90.530178 2.5377786 88.580434 -0.0001631068 85.442676 -0.0001631068" - android:fillColor="#007b84" /> - <path - android:pathData="M62.502184 34.74713c-0.42519 0.116893 -1.21647 0.471379 -1.21647 0.471379l0.703725 -2.299806 2.109532 0 -0.508914 1.67565c0 0 -0.651739 0.03806 -1.087873 0.152777l0 0zm0.04049 3.285515c0 0 -0.662683 0.08264 -1.098818 0.180504 -0.429567 0.129399 -1.235075 0.537166 -1.235075 0.537166l0.726708 -2.393321 2.120477 0 -0.513292 1.675651zm-1.181995 3.905864l-2.116099 0 0.613434 -2.019806 2.109532 0 -0.606867 2.019806zm3.311227 -0.0212l-0.739841 0 2.738288 -8.998602 0.908384 0 0.287838 -0.92699 0.029 1.030835c-0.03448 0.637203 0.470061 1.202097 1.795428 1.108582l1.532762 0 0.52752 -1.732738 -0.57677 0c-0.331615 0 -0.485383 -0.08318 -0.466231 -0.261514l-0.02791 -1.048777 -2.838429 0 0 0.0054c-0.917687 0.01957 -3.658164 0.08808 -4.213045 0.23433 -0.671439 0.171806 -1.378994 0.677437 -1.378994 0.677437l0.277988 -0.928078 -2.65511 0 -0.55324 1.841476 -2.774951 9.136155 -0.538464 0 -0.528067 1.720777 5.288331 0 -0.177299 0.573048 2.605861 0 0.172921 -0.573048 0.731086 0 0.572939 -1.85833z" - android:fillColor="#fefefe" /> - <path - android:pathData="M66.456722 36.35694l3.050203 0 -0.438323 1.41033 -3.090697 0 -0.464043 1.541903 2.70436 0 -2.047696 2.864699c-0.143372 0.210408 -0.271968 0.284893 -0.414792 0.344155 -0.143372 0.07231 -0.331616 0.157126 -0.549409 0.157126l-0.750239 0 -0.515481 1.688699 1.962331 0c1.020017 0 1.622506 -0.461048 2.067396 -1.066174l1.404166 -1.909437 0.301518 1.938796c0.06403 0.363184 0.32669 0.575767 0.504537 0.658408 0.196451 0.09786 0.39947 0.265864 0.685666 0.290873 0.308085 0.01305 0.530256 0.02338 0.678005 0.02338l0.963654 0 0.579506 -1.889864 -0.380318 0c-0.218341 0 -0.594281 -0.03643 -0.658305 -0.104388 -0.06403 -0.08264 -0.06403 -0.209864 -0.0985 -0.403418l-0.305896 -1.943145 -1.252586 0 0.549409 -0.649709 3.084678 0 0.474439 -1.541903 -2.85594 0 0.44489 -1.41033 2.847185 0 0.528067 -1.739262 -8.488474 0 -0.519311 1.739262z" - android:fillColor="#fefefe" /> - <path - android:pathData="M40.6946 42.331161l0.711933 -2.353087 2.925984 0 0.534634 -1.750136 -2.92872 0 0.447078 -1.448388 2.86196 0 0.530256 -1.69468 -7.160918 0 -0.519312 1.69468 1.626884 0 -0.433945 1.448388 -1.631262 0 -0.540653 1.780039 1.626337 0 -0.948879 3.113165c-0.128049 0.412116 0.06019 0.569242 0.179488 0.760621 0.12203 0.186486 0.246249 0.309903 0.52369 0.380039 0.286743 0.06361 0.483194 0.10167 0.750238 0.10167l3.298641 0 0.587714 -1.938796 -1.462172 0.199534c-0.282365 0 -1.064342 -0.03371 -0.978976 -0.293049" - android:fillColor="#fefefe" /> - <path - android:pathData="M41.03021 31.066625l-0.74203 1.331495c-0.158146 0.290874 -0.300971 0.471379 -0.429568 0.554563 -0.113274 0.07014 -0.337634 0.0995 -0.662683 0.0995l-0.386884 0 -0.517123 1.703378 1.284872 0c0.617812 0 1.092251 -0.225087 1.3188 -0.337631 0.243513 -0.129398 0.307537 -0.05546 0.495781 -0.235961l0.433945 -0.373515 4.012216 0 0.532445 -1.773514 -2.936929 0 0.512745 -0.968311 -2.915587 0z" - android:fillColor="#fefefe" /> - <path - android:pathData="M48.843086 35.6944l4.097581 0 -0.260476 0.811184c-0.03666 0.01903 -0.124219 -0.04023 -0.541201 0.0087l-3.548173 0 0.252269 -0.819883zm0.820829 -2.720621l4.132057 0 -0.297141 0.977009c0 0 -1.947555 -0.01903 -2.25947 0.03806 -1.372427 0.235961 -2.174104 0.964504 -2.174104 0.964504l0.598658 -1.979572zm-2.710379 9.391145c-0.0684 -0.09732 -0.01915 -0.26967 0.08537 -0.628505l1.096629 -3.606291 3.901129 0c0.568561 -0.0082 0.978976 -0.01468 1.24602 -0.03371 0.286743 -0.0299 0.598658 -0.131572 0.938481 -0.314252 0.350768 -0.191379 0.530257 -0.393087 0.681836 -0.624699 0.169091 -0.231068 0.440512 -0.736699 0.673628 -1.51635l1.378447 -4.563728 -4.048332 0.02338c0 0 -1.246567 0.182679 -1.795976 0.384388 -0.553239 0.225088 -1.344519 0.853592 -1.344519 0.853592l0.365543 -1.251029 -2.500794 0 -3.501112 11.536544c-0.124219 0.448 -0.207397 0.773126 -0.226549 0.968311 -0.0066 0.210407 0.267043 0.41864 0.444342 0.575767 0.209585 0.157126 0.519312 0.131573 0.816452 0.157126 0.312463 0.02338 0.756805 0.03806 1.370238 0.03806l1.921836 0 0.589903 -1.979029 -1.720459 0.161476c-0.183866 0 -0.31684 -0.09786 -0.372109 -0.181049l0 0z" - android:fillColor="#fefefe" /> - <path - android:pathData="M52.771905 39.221965c-0.03393 0.121243 -0.08755 0.195184 -0.162525 0.250641 -0.08318 0.05274 -0.217793 0.07231 -0.418623 0.07231l-0.583883 0 0.03448 -0.987883 -2.428562 0 -0.0985 4.829592c-0.0038 0.348505 0.0301 0.550214 0.286743 0.71169 0.256646 0.201708 1.047378 0.227262 2.111721 0.227262l1.522365 0 0.548862 -1.807767 -1.324819 0.07231 -0.440512 0.02555c-0.06019 -0.02555 -0.117652 -0.04893 -0.181677 -0.112544 -0.05582 -0.05546 -0.149938 -0.0212 -0.134616 -0.369709l0.0104 -1.23798 1.389391 -0.05709c0.750238 0 1.070909 -0.242485 1.344519 -0.473553 0.261024 -0.221282 0.34639 -0.475728 0.44489 -0.819884l0.233115 -1.096077 -1.90925 0 -0.243512 0.773126z" - android:fillColor="#fefefe" /> - <path - android:pathData="M23.478574 14.288699c-2.308721 0.02338 -2.990556 0 -3.20835 -0.05111 -0.08372 0.395262 -1.641659 7.535534 -1.646037 7.541515 -0.335446 1.444582 -0.579506 2.47433 -1.408544 3.139262 -0.470609 0.386563 -1.020017 0.573048 -1.656981 0.573048 -1.023848 0 -1.620318 -0.505087 -1.720459 -1.463068l-0.01915 -0.328932c0 0 0.311916 -1.93499 0.311916 -1.945864 0 0 1.635092 -6.506873 1.927855 -7.36699 0.01532 -0.04893 0.0197 -0.07449 0.02353 -0.09786 -3.18263 0.02773 -3.746814 0 -3.785666 -0.05111 -0.02134 0.07014 -0.100141 0.473554 -0.100141 0.473554l-1.669568 7.333825 -0.143371 0.62198 -0.277441 2.034486c0 0.603495 0.119294 1.096078 0.356788 1.512544 0.761182 1.320621 2.930361 1.518524 4.157775 1.518524 1.581465 0 3.064978 -0.333825 4.067485 -0.943301 1.740159 -1.021592 2.195446 -2.618408 2.601483 -4.037437l0.188243 -0.728c0 0 1.684343 -6.758058 1.970539 -7.637204 0.01094 -0.04893 0.01532 -0.07449 0.0301 -0.09786" - android:fillColor="#fefefe" /> - <path - android:pathData="M29.209387 19.740435c-0.406037 0 -1.148067 0.09786 -1.81458 0.422447 -0.241871 0.123417 -0.470609 0.265864 -0.711933 0.407766l0.217793 -0.781281 -0.119294 -0.131573c-1.412921 0.28435 -1.729761 0.322408 -3.035428 0.505088l-0.108897 0.07231c-0.152127 1.248855 -0.286743 2.187806 -0.848737 4.642563 -0.213963 0.904699 -0.436135 1.818097 -0.658853 2.720622l0.06019 0.114718c1.337953 -0.07014 1.74399 -0.07014 2.906832 -0.05111l0.09412 -0.10167c0.14775 -0.751922 0.166902 -0.928077 0.49414 -2.450951 0.153769 -0.722019 0.474439 -2.308505 0.632586 -2.873398 0.290574 -0.133748 0.577317 -0.265321 0.850927 -0.265321 0.651738 0 0.572939 0.564894 0.547219 0.789981 -0.02791 0.377864 -0.265401 1.612039 -0.508914 2.671689l-0.162524 0.683962c-0.113275 0.505087 -0.237494 0.996038 -0.350768 1.496776l0.04925 0.100039c1.318799 -0.07014 1.721006 -0.07014 2.847184 -0.05111l0.132427 -0.10167c0.203566 -1.174369 0.263213 -1.488621 0.624378 -3.198524l0.181677 -0.785631C30.881144 22.03861 31.058443 21.258959 30.7914 20.62393 30.509034 19.912241 29.831576 19.740435 29.209387 19.740435" - android:fillColor="#fefefe" /> - <path - android:pathData="M35.611476 21.350299c-0.700989 0.133748 -1.148067 0.222913 -1.59241 0.280544 -0.440512 0.06959 -0.870079 0.133747 -1.547537 0.227262l-0.05363 0.04839 -0.04925 0.0386c-0.07059 0.501282 -0.119841 0.934602 -0.213415 1.444039 -0.07935 0.526835 -0.201377 1.125437 -0.400018 1.985553 -0.153769 0.658408 -0.233116 0.887845 -0.320671 1.119457 -0.08537 0.231611 -0.179488 0.456699 -0.352409 1.104233l0.04049 0.05981 0.03393 0.05491c0.633133 -0.0299 1.047378 -0.05111 1.473115 -0.05491 0.42519 -0.01522 0.865702 0 1.547538 0.0038l0.05965 -0.04893 0.06402 -0.05274c0.0985 -0.583922 0.113275 -0.741048 0.173469 -1.025941 0.05965 -0.305554 0.162524 -0.728544 0.414793 -1.85833 0.119294 -0.530641 0.252268 -1.059651 0.37594 -1.601165 0.128596 -0.53934 0.263212 -1.070525 0.391262 -1.601166l-0.01915 -0.06415 -0.02572 -0.05926z" - android:fillColor="#fefefe" /> - <path - android:pathData="M39.37788 23.949786c0.29714 -1.305941 0.647908 -2.402019 1.54316 -2.402019 0.701536 0 0.752427 0.815534 0.440512 2.125825 -0.05582 0.290874 -0.311916 1.372272 -0.658306 1.832777 -0.241871 0.339806 -0.528067 0.545864 -0.84436 0.545864 -0.09412 0 -0.653928 0 -0.662683 -0.825864 -0.0044 -0.407767 0.07935 -0.824233 0.181677 -1.276583m0.100688 3.880311c1.288703 0 2.609691 -0.352854 3.60399 -1.4 0.765013 -0.849243 1.115781 -2.112777 1.237264 -2.633087 0.39564 -1.724583 0.08755 -2.529787 -0.299329 -3.020194 -0.587715 -0.747573 -1.626338 -0.98734 -2.703813 -0.98734 -0.647909 0 -2.191068 0.06361 -3.396594 1.167844 -0.865701 0.796505 -1.265719 1.87736 -1.507043 2.913631 -0.243513 1.055845 -0.523689 2.956583 1.235622 3.663923 0.542842 0.231068 1.325367 0.295223 1.829903 0.295223" - android:fillColor="#fefefe" /> - <path - android:pathData="M67.630235 24.087829c0.301518 -1.282563 0.647908 -2.368311 1.545348 -2.368311 0.567467 0 0.866796 0.520855 0.805508 1.408156 -0.04816 0.221281 -0.100141 0.454524 -0.161977 0.718213 -0.08974 0.381127 -0.187149 0.758991 -0.281818 1.137398 -0.09631 0.258253 -0.207944 0.502913 -0.331616 0.665476 -0.230926 0.325126 -0.780335 0.526835 -1.096628 0.526835 -0.08974 0 -0.64353 0 -0.662683 -0.811184 -0.0044 -0.403962 0.07935 -0.819884 0.183866 -1.276583m-2.95827 -0.06361c-0.245702 1.040622 -0.528067 2.94136 1.222489 3.618797 0.558164 0.235961 1.058323 0.306097 1.56669 0.280543 0.536823 -0.02881 1.034245 -0.29631 1.495004 -0.681242 -0.04159 0.158213 -0.08263 0.316427 -0.124766 0.475184l0.07935 0.10167c1.259153 -0.05274 1.650415 -0.05274 3.014086 -0.04241l0.123672 -0.09351c0.199188 -1.163495 0.386885 -2.293826 0.904554 -4.519146 0.252269 -1.066175 0.50399 -2.122019 0.762825 -3.183845l-0.04049 -0.116893c-1.408544 0.25934 -1.785031 0.314796 -3.139947 0.505631l-0.102878 0.08319c-0.01423 0.108194 -0.02736 0.212038 -0.04104 0.315883 -0.21068 -0.338175 -0.516028 -0.626874 -0.987185 -0.806835 -0.602489 -0.235417 -2.017599 0.06796 -3.234069 1.168388 -0.854757 0.785632 -1.265172 1.862136 -1.498287 2.894602" - android:fillColor="#fefefe" /> - <path - android:pathData="M47.54125 27.662206l0.100688 -0.10167c0.142825 -0.751922 0.166355 -0.928621 0.483195 -2.450952 0.158147 -0.722019 0.484837 -2.308504 0.638606 -2.873398 0.291121 -0.134291 0.572939 -0.265864 0.855304 -0.265864 0.647908 0 0.568562 0.564893 0.542842 0.789981 -0.02353 0.378408 -0.261024 1.612039 -0.508914 2.671689l-0.153769 0.683961c-0.117652 0.505631 -0.245702 0.996039 -0.358976 1.497321l0.04925 0.100039c1.323177 -0.07014 1.710061 -0.07014 2.842806 -0.05111l0.136805 -0.10167c0.198641 -1.174913 0.252269 -1.489165 0.624378 -3.198524l0.177299 -0.786175c0.354599 -1.537554 0.534087 -2.31666 0.271421 -2.951689 -0.290573 -0.71169 -0.972409 -0.883496 -1.585843 -0.883496 -0.406584 0 -1.152444 0.09732 -1.815128 0.422447 -0.236946 0.123417 -0.474439 0.26532 -0.707555 0.407767l0.203019 -0.781282 -0.108897 -0.132116C47.81486 19.942361 47.492 19.980419 46.187975 20.163099l-0.100141 0.07231c-0.158146 1.248854 -0.286743 2.187262 -0.848738 4.642563 -0.213963 0.904699 -0.436134 1.818097 -0.658305 2.720621l0.05965 0.114719c1.340141 -0.07014 1.740159 -0.07014 2.900812 -0.05111" - android:fillColor="#fefefe" /> - <path - android:pathData="M58.883255 20.560264c0 0 0.929726 -4.018408 0.925349 -4.003184l0.0301 -0.206059 0.01259 -0.157126 0.372109 0.03806c0 0 1.917458 0.163651 1.96233 0.168 0.756805 0.290874 1.068721 1.040622 0.850927 2.019262 -0.198641 0.894369 -0.782524 1.646292 -1.532762 2.009476 -0.617812 0.307728 -1.374617 0.333282 -2.154405 0.333282l-0.504536 0 0.03831 -0.201709zm-1.620318 7.152777c0.08318 -0.403418 0.577317 -2.794563 0.581695 -2.794563 0 0 0.420812 -1.754486 0.446531 -1.818097 0 0 0.132428 -0.18268 0.264855 -0.254991l0.19481 0c1.838111 0 3.913716 0 5.5406 -1.189048 1.107026 -0.815534 1.863831 -2.019806 2.201465 -3.483418 0.08756 -0.358835 0.152127 -0.785631 0.152127 -1.212427 0 -0.560544 -0.113274 -1.115107 -0.440512 -1.548427 -0.829585 -1.153165 -2.481641 -1.174369 -4.388702 -1.183068 -0.006 0 -0.940124 0.0087 -0.940124 0.0087 -2.441147 0.0299 -3.420123 0.0212 -3.82233 -0.02773 -0.03393 0.176699 -0.09795 0.490951 -0.09795 0.490951 0 0 -0.874457 4.026563 -0.874457 4.033088 0 0 -2.092569 8.560932 -2.191068 8.964349 2.130874 -0.02555 3.005331 -0.02555 3.373062 0.01468l0 0z" - android:fillColor="#fefefe" /> - <path - android:pathData="M83.078523 19.853033l-0.108897 -0.123417c-1.393769 0.280543 -1.646037 0.325126 -2.926532 0.496932l-0.09412 0.09351c-0.0044 0.01522 -0.0082 0.0386 -0.01478 0.05981l-0.0044 -0.0212c-0.953257 2.185087 -0.925349 1.713709 -1.701306 3.433942 -0.0044 -0.07829 -0.0044 -0.127224 -0.0088 -0.210408l-0.194263 -3.729165 -0.12203 -0.123417c-1.459982 0.280543 -1.494457 0.325126 -2.842807 0.496932l-0.105066 0.09351c-0.01478 0.04458 -0.01478 0.09352 -0.02353 0.146796l0.0088 0.01903c0.168544 0.855767 0.12805 0.664932 0.297141 2.015457 0.0788 0.662757 0.183866 1.32932 0.262665 1.983378 0.132427 1.096078 0.207396 1.635418 0.369921 3.307263 -0.910574 1.49297 -1.126726 2.057863 -2.002825 3.368155l0.006 0.01359 -0.617264 0.969398c-0.07059 0.102214 -0.134616 0.17235 -0.22436 0.202252 -0.0985 0.04839 -0.226549 0.05709 -0.404396 0.05709l-0.342012 0 -0.508367 1.68 1.743989 0.0299c1.023848 -0.0043 1.667379 -0.480078 2.013769 -1.119457l1.096628 -1.867029 -0.01806 0 0.116011 -0.131572c0.737652 -1.577787 6.348844 -11.141282 6.348844 -11.141282" - android:fillColor="#fefefe" /> - <path - android:pathData="M35.626415 19.179837c-0.636964 -0.373515 -1.754934 -0.25499 -2.507361 0.260971 -0.750239 0.505631 -0.835605 1.223301 -0.20083 1.601709 0.62602 0.363184 1.748367 0.254446 2.494228 -0.265321 0.748596 -0.516505 0.842171 -1.22765 0.213963 -1.597359" - android:fillColor="#fefefe" /> - </group> -</vector> \ No newline at end of file + android:pathData="M4,8L4,72C4,74.21 5.79,76 8.01,76L119.99,76C122.2,76 124,74.21 124,72L124,8C124,5.79 122.21,4 119.99,4L8.01,4C5.8,4 4,5.79 4,8Z" + android:strokeColor="#00000000" + android:fillColor="#FFFFFF" + android:strokeWidth="1"/> + <path + android:pathData="M39.74,62.25L50.19,17.66C50.93,14.54 54.06,12 57.2,12L36.62,12C33.48,12 30.34,14.54 29.61,17.66L19.15,62.25C18.42,65.36 20.38,67.9 23.51,67.9L44.09,67.9C40.95,67.9 39,65.36 39.74,62.25" + android:strokeColor="#00000000" + android:fillColor="#E21836" + android:strokeWidth="1"/> + <path + android:pathData="M64.53,62.25L74.99,17.66C75.72,14.54 78.85,12 81.99,12L59.07,12L57.2,12C54.06,12 50.93,14.54 50.19,17.66L39.74,62.25C39,65.36 40.95,67.9 44.09,67.9L45.95,67.9L68.89,67.9C65.75,67.9 63.8,65.36 64.53,62.25" + android:strokeColor="#00000000" + android:fillColor="#00447C" + android:strokeWidth="1"/> + <path + android:pathData="M104.44,12L83.02,12L81.99,12C78.85,12 75.72,14.54 74.99,17.66L64.53,62.25C63.8,65.36 65.75,67.9 68.89,67.9L69.9,67.9L91.33,67.9C94.46,67.9 97.6,65.36 98.34,62.25L108.79,17.66C109.53,14.54 107.58,12 104.44,12" + android:strokeColor="#00000000" + android:fillColor="#007B84" + android:strokeWidth="1"/> + <path + android:pathData="M81.5,46.75C81.08,46.86 80.29,47.22 80.29,47.22L80.99,44.92L83.1,44.92L82.59,46.59C82.59,46.59 81.94,46.63 81.5,46.75L81.5,46.75ZM81.54,50.03C81.54,50.03 80.88,50.12 80.44,50.21C80.01,50.34 79.21,50.75 79.21,50.75L79.94,48.36L82.06,48.36L81.54,50.03ZM80.36,53.94L78.24,53.94L78.86,51.92L80.97,51.92L80.36,53.94ZM83.67,53.92L82.93,53.92L85.67,44.92L86.58,44.92L86.87,43.99L86.9,45.02C86.86,45.66 87.37,46.22 88.69,46.13L90.22,46.13L90.75,44.4L90.17,44.4C89.84,44.4 89.69,44.32 89.71,44.14L89.68,43.09L86.84,43.09L86.84,43.09C85.92,43.11 83.18,43.18 82.63,43.33C81.96,43.5 81.25,44.01 81.25,44.01L81.53,43.08L78.87,43.08L78.32,44.92L75.54,54.05L75.01,54.05L74.48,55.78L79.77,55.78L79.59,56.35L82.19,56.35L82.37,55.78L83.1,55.78L83.67,53.92Z" + android:strokeColor="#00000000" + android:fillColor="#FEFEFE" + android:strokeWidth="1"/> + <path + android:pathData="M85.46,48.36L88.51,48.36L88.07,49.77L84.98,49.77L84.51,51.31L87.22,51.31L85.17,54.17C85.03,54.38 84.9,54.46 84.76,54.52C84.61,54.59 84.42,54.68 84.21,54.68L83.46,54.68L82.94,56.36L84.9,56.36C85.92,56.36 86.53,55.9 86.97,55.3L88.37,53.39L88.68,55.33C88.74,55.69 89,55.9 89.18,55.99C89.38,56.08 89.58,56.25 89.87,56.28C90.17,56.29 90.4,56.3 90.54,56.3L91.51,56.3L92.09,54.41L91.71,54.41C91.49,54.41 91.11,54.37 91.05,54.31C90.98,54.22 90.98,54.1 90.95,53.9L90.64,51.96L89.39,51.96L89.94,51.31L93.03,51.31L93.5,49.77L90.64,49.77L91.09,48.36L93.94,48.36L94.46,46.62L85.98,46.62L85.46,48.36Z" + android:strokeColor="#00000000" + android:fillColor="#FEFEFE" + android:strokeWidth="1"/> + <path + android:pathData="M59.69,54.33L60.41,51.98L63.33,51.98L63.87,50.23L60.94,50.23L61.39,48.78L64.25,48.78L64.78,47.08L57.62,47.08L57.1,48.78L58.72,48.78L58.29,50.23L56.66,50.23L56.12,52.01L57.74,52.01L56.8,55.12C56.67,55.53 56.86,55.69 56.98,55.88C57.1,56.07 57.22,56.19 57.5,56.26C57.79,56.33 57.98,56.36 58.25,56.36L61.55,56.36L62.14,54.42L60.67,54.62C60.39,54.62 59.61,54.59 59.69,54.33" + android:strokeColor="#00000000" + android:fillColor="#FEFEFE" + android:strokeWidth="1"/> + <path + android:pathData="M60.03,43.07L59.29,44.4C59.13,44.69 58.99,44.87 58.86,44.95C58.75,45.02 58.52,45.05 58.2,45.05L57.81,45.05L57.29,46.76L58.58,46.76C59.19,46.76 59.67,46.53 59.9,46.42C60.14,46.29 60.2,46.36 60.39,46.18L60.83,45.81L64.84,45.81L65.37,44.03L62.43,44.03L62.95,43.07L60.03,43.07Z" + android:strokeColor="#00000000" + android:fillColor="#FEFEFE" + android:strokeWidth="1"/> + <path + android:pathData="M67.84,47.69L71.94,47.69L71.68,48.51C71.64,48.52 71.56,48.47 71.14,48.51L67.59,48.51L67.84,47.69ZM68.66,44.97L72.8,44.97L72.5,45.95C72.5,45.95 70.55,45.93 70.24,45.99C68.87,46.22 68.07,46.95 68.07,46.95L68.66,44.97ZM65.95,54.36C65.89,54.27 65.93,54.1 66.04,53.74L67.14,50.13L71.04,50.13C71.61,50.12 72.02,50.12 72.28,50.1C72.57,50.07 72.88,49.96 73.22,49.78C73.57,49.59 73.75,49.39 73.9,49.16C74.07,48.93 74.34,48.42 74.58,47.64L75.96,43.08L71.91,43.1C71.91,43.1 70.66,43.28 70.11,43.49C69.56,43.71 68.77,44.34 68.77,44.34L69.13,43.09L66.63,43.09L63.13,54.62C63.01,55.07 62.92,55.4 62.9,55.59C62.9,55.8 63.17,56.01 63.35,56.17C63.56,56.33 63.87,56.3 64.16,56.33C64.48,56.35 64.92,56.36 65.53,56.36L67.46,56.36L68.05,54.38L66.33,54.55C66.14,54.55 66.01,54.45 65.95,54.36L65.95,54.36Z" + android:strokeColor="#00000000" + android:fillColor="#FEFEFE" + android:strokeWidth="1"/> + <path + android:pathData="M71.77,51.22C71.74,51.34 71.68,51.42 71.61,51.47C71.53,51.53 71.39,51.54 71.19,51.54L70.61,51.54L70.64,50.56L68.21,50.56L68.11,55.39C68.11,55.74 68.14,55.94 68.4,56.1C68.66,56.3 69.45,56.33 70.51,56.33L72.04,56.33L72.58,54.52L71.26,54.59L70.82,54.62C70.76,54.59 70.7,54.57 70.64,54.5C70.58,54.45 70.49,54.48 70.5,54.13L70.51,52.9L71.9,52.84C72.65,52.84 72.97,52.6 73.25,52.36C73.51,52.14 73.59,51.89 73.69,51.54L73.92,50.45L72.02,50.45L71.77,51.22Z" + android:strokeColor="#00000000" + android:fillColor="#FEFEFE" + android:strokeWidth="1"/> + <path + android:pathData="M42.48,26.29C40.17,26.31 39.49,26.29 39.27,26.24C39.19,26.63 37.63,33.77 37.62,33.78C37.29,35.22 37.04,36.25 36.22,36.92C35.75,37.3 35.2,37.49 34.56,37.49C33.53,37.49 32.94,36.99 32.84,36.03L32.82,35.7C32.82,35.7 33.13,33.76 33.13,33.75C33.13,33.75 34.77,27.25 35.06,26.39C35.07,26.34 35.08,26.31 35.08,26.29C31.9,26.32 31.34,26.29 31.3,26.24C31.28,26.31 31.2,26.71 31.2,26.71L29.53,34.04L29.38,34.67L29.11,36.7C29.11,37.3 29.23,37.8 29.46,38.21C30.22,39.53 32.39,39.73 33.62,39.73C35.2,39.73 36.69,39.4 37.69,38.79C39.43,37.77 39.88,36.17 40.29,34.75L40.48,34.02C40.48,34.02 42.16,27.27 42.45,26.39C42.46,26.34 42.46,26.31 42.48,26.29" + android:strokeColor="#00000000" + android:fillColor="#FEFEFE" + android:strokeWidth="1"/> + <path + android:pathData="M48.21,31.74C47.8,31.74 47.06,31.84 46.39,32.16C46.15,32.29 45.92,32.43 45.68,32.57L45.9,31.79L45.78,31.66C44.37,31.94 44.05,31.98 42.75,32.16L42.64,32.24C42.48,33.48 42.35,34.42 41.79,36.88C41.57,37.78 41.35,38.7 41.13,39.6L41.19,39.71C42.53,39.64 42.93,39.64 44.1,39.66L44.19,39.56C44.34,38.81 44.36,38.63 44.68,37.11C44.84,36.39 45.16,34.8 45.32,34.24C45.61,34.1 45.89,33.97 46.17,33.97C46.82,33.97 46.74,34.54 46.72,34.76C46.69,35.14 46.45,36.37 46.21,37.43L46.04,38.12C45.93,38.62 45.81,39.11 45.69,39.61L45.74,39.71C47.06,39.64 47.46,39.64 48.59,39.66L48.72,39.56C48.93,38.39 48.99,38.07 49.35,36.36L49.53,35.58C49.88,34.04 50.06,33.26 49.79,32.62C49.51,31.91 48.83,31.74 48.21,31.74" + android:strokeColor="#00000000" + android:fillColor="#FEFEFE" + android:strokeWidth="1"/> + <path + android:pathData="M54.61,33.35C53.91,33.48 53.46,33.57 53.02,33.63C52.58,33.7 52.15,33.76 51.47,33.86L51.42,33.91L51.37,33.95C51.3,34.45 51.25,34.88 51.16,35.39C51.08,35.92 50.95,36.51 50.76,37.37C50.6,38.03 50.52,38.26 50.43,38.49C50.35,38.73 50.26,38.95 50.08,39.6L50.12,39.66L50.16,39.71C50.79,39.68 51.2,39.66 51.63,39.66C52.05,39.64 52.5,39.66 53.18,39.66L53.24,39.61L53.3,39.56C53.4,38.98 53.41,38.82 53.47,38.53C53.53,38.23 53.64,37.81 53.89,36.68C54.01,36.15 54.14,35.62 54.27,35.07C54.39,34.54 54.53,34 54.66,33.47L54.64,33.41L54.61,33.35Z" + android:strokeColor="#00000000" + android:fillColor="#FEFEFE" + android:strokeWidth="1"/> + <path + android:pathData="M58.38,35.95C58.68,34.64 59.03,33.55 59.92,33.55C60.62,33.55 60.67,34.36 60.36,35.67C60.31,35.96 60.05,37.05 59.7,37.51C59.46,37.85 59.18,38.05 58.86,38.05C58.76,38.05 58.2,38.05 58.2,37.23C58.19,36.82 58.28,36.4 58.38,35.95M58.48,39.83C59.77,39.83 61.09,39.48 62.08,38.43C62.85,37.58 63.2,36.32 63.32,35.8C63.72,34.07 63.41,33.27 63.02,32.78C62.43,32.03 61.39,31.79 60.32,31.79C59.67,31.79 58.13,31.85 56.92,32.96C56.05,33.75 55.65,34.83 55.41,35.87C55.17,36.93 54.89,38.83 56.65,39.53C57.19,39.77 57.97,39.83 58.48,39.83" + android:strokeColor="#00000000" + android:fillColor="#FEFEFE" + android:strokeWidth="1"/> + <path + android:pathData="M86.63,36.09C86.93,34.81 87.28,33.72 88.18,33.72C88.74,33.72 89.04,34.24 88.98,35.13C88.93,35.35 88.88,35.58 88.82,35.85C88.73,36.23 88.63,36.6 88.54,36.98C88.44,37.24 88.33,37.49 88.21,37.65C87.97,37.97 87.43,38.18 87.11,38.18C87.02,38.18 86.47,38.18 86.45,37.36C86.44,36.96 86.53,36.54 86.63,36.09M83.67,36.02C83.43,37.06 83.14,38.97 84.89,39.64C85.45,39.88 85.95,39.95 86.46,39.92C87,39.89 87.5,39.63 87.96,39.24C87.91,39.4 87.87,39.56 87.83,39.72L87.91,39.82C89.17,39.77 89.56,39.77 90.92,39.78L91.05,39.68C91.25,38.52 91.44,37.39 91.95,35.16C92.21,34.1 92.46,33.04 92.72,31.98L92.68,31.86C91.27,32.12 90.89,32.18 89.54,32.37L89.43,32.45C89.42,32.56 89.41,32.66 89.39,32.77C89.18,32.43 88.88,32.14 88.4,31.96C87.8,31.73 86.39,32.03 85.17,33.13C84.32,33.92 83.91,34.99 83.67,36.02" + android:strokeColor="#00000000" + android:fillColor="#FEFEFE" + android:strokeWidth="1"/> + <path + android:pathData="M66.54,39.66L66.64,39.56C66.78,38.81 66.81,38.63 67.13,37.11C67.28,36.39 67.61,34.8 67.76,34.24C68.05,34.1 68.34,33.97 68.62,33.97C69.27,33.97 69.19,34.54 69.16,34.76C69.14,35.14 68.9,36.37 68.65,37.43L68.5,38.12C68.38,38.62 68.25,39.11 68.14,39.61L68.19,39.71C69.51,39.64 69.9,39.64 71.03,39.66L71.17,39.56C71.37,38.39 71.42,38.07 71.79,36.36L71.97,35.58C72.33,34.04 72.5,33.26 72.24,32.62C71.95,31.91 71.27,31.74 70.66,31.74C70.25,31.74 69.5,31.84 68.84,32.16C68.6,32.29 68.37,32.43 68.13,32.57L68.34,31.79L68.23,31.66C66.81,31.94 66.49,31.98 65.19,32.16L65.09,32.24C64.93,33.48 64.8,34.42 64.24,36.88C64.03,37.78 63.8,38.7 63.58,39.6L63.64,39.71C64.98,39.64 65.38,39.64 66.54,39.66" + android:strokeColor="#00000000" + android:fillColor="#FEFEFE" + android:strokeWidth="1"/> + <path + android:pathData="M77.88,32.56C77.88,32.56 78.81,28.54 78.81,28.56L78.84,28.35L78.85,28.19L79.22,28.23C79.22,28.23 81.14,28.4 81.19,28.4C81.94,28.69 82.25,29.44 82.04,30.42C81.84,31.31 81.25,32.07 80.5,32.43C79.89,32.74 79.13,32.76 78.35,32.76L77.84,32.76L77.88,32.56ZM76.26,39.71C76.35,39.31 76.84,36.92 76.84,36.92C76.84,36.92 77.27,35.16 77.29,35.1C77.29,35.1 77.42,34.92 77.56,34.85L77.75,34.85C79.59,34.85 81.66,34.85 83.29,33.66C84.4,32.84 85.16,31.64 85.49,30.17C85.58,29.81 85.65,29.39 85.65,28.96C85.65,28.4 85.53,27.85 85.2,27.41C84.37,26.26 82.72,26.24 80.82,26.23C80.81,26.23 79.88,26.24 79.88,26.24C77.43,26.27 76.46,26.26 76.05,26.21C76.02,26.39 75.96,26.7 75.96,26.7C75.96,26.7 75.08,30.73 75.08,30.73C75.08,30.73 72.99,39.29 72.89,39.7C75.02,39.67 75.9,39.67 76.26,39.71L76.26,39.71Z" + android:strokeColor="#00000000" + android:fillColor="#FEFEFE" + android:strokeWidth="1"/> + <path + android:pathData="M102.08,31.85L101.97,31.73C100.58,32.01 100.32,32.05 99.04,32.23L98.95,32.32C98.94,32.34 98.94,32.36 98.93,32.38L98.93,32.36C97.98,34.54 98,34.07 97.23,35.79C97.22,35.71 97.22,35.67 97.22,35.58L97.03,31.85L96.9,31.73C95.44,32.01 95.41,32.05 94.06,32.23L93.96,32.32C93.94,32.36 93.94,32.41 93.93,32.47L93.94,32.49C94.11,33.34 94.07,33.15 94.24,34.5C94.32,35.16 94.42,35.83 94.5,36.48C94.63,37.58 94.71,38.12 94.87,39.79C93.96,41.28 93.74,41.85 92.87,43.16L92.87,43.17L92.26,44.14C92.19,44.25 92.12,44.32 92.03,44.35C91.93,44.39 91.81,44.4 91.63,44.4L91.29,44.4L90.78,46.08L92.52,46.11C93.55,46.11 94.19,45.63 94.54,44.99L95.63,43.13L95.61,43.13L95.73,42.99C96.47,41.42 102.08,31.85 102.08,31.85" + android:strokeColor="#00000000" + android:fillColor="#FEFEFE" + android:strokeWidth="1"/> + <path + android:pathData="M54.63,31.18C53.99,30.81 52.87,30.92 52.12,31.44C51.37,31.95 51.28,32.66 51.92,33.04C52.54,33.41 53.67,33.3 54.41,32.78C55.16,32.26 55.25,31.55 54.63,31.18" + android:strokeColor="#00000000" + android:fillColor="#FEFEFE" + android:strokeWidth="1"/> +</vector>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index c8b72ea..8f3f744 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -98,7 +98,7 @@ <dimen name="infobar_big_icon_margin">16dp</dimen> <!-- Dimensions for compact infobars are a little shorter. --> - <dimen name="infobar_compact_size">48dp</dimen> + <dimen name="infobar_compact_size">56dp</dimen> <!-- Dimensions for compact translate infobar. --> <dimen name="infobar_translate_fade_edge_length">18dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ContentSuggestionsNotificationHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/ContentSuggestionsNotificationHelper.java index 793c7df4..3c26b3e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ContentSuggestionsNotificationHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/ContentSuggestionsNotificationHelper.java
@@ -96,8 +96,7 @@ int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1); String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITHIN_CATEGORY_EXTRA); openUrl(intent.getData()); - recordCachedActionMetric(ContentSuggestionsNotificationAction.TAP); - removeActiveNotification(category, idWithinCategory); + hideNotification(category, idWithinCategory, ContentSuggestionsNotificationAction.TAP); } } @@ -109,8 +108,9 @@ public void onReceive(Context context, Intent intent) { int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1); String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITHIN_CATEGORY_EXTRA); - recordCachedActionMetric(ContentSuggestionsNotificationAction.DISMISSAL); - removeActiveNotification(category, idWithinCategory); + if (removeActiveNotification(category, idWithinCategory)) { + recordCachedActionMetric(ContentSuggestionsNotificationAction.DISMISSAL); + } } } @@ -122,10 +122,6 @@ public void onReceive(Context context, Intent intent) { int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1); String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITHIN_CATEGORY_EXTRA); - if (findActiveNotification(category, idWithinCategory) == null) { - return; // tapped or swiped - } - hideNotification( category, idWithinCategory, ContentSuggestionsNotificationAction.HIDE_DEADLINE); } @@ -172,7 +168,6 @@ NotificationBuilderFactory .createChromeNotificationBuilder( true /* preferCompat */, ChannelDefinitions.CHANNEL_ID_BROWSER) - .setAutoCancel(true) .setContentIntent(contentIntent) .setDeleteIntent(deleteIntent) .setContentTitle(title) @@ -206,17 +201,22 @@ return true; } + /** + * Hides a notification and records an action to the Actions histogram. + * + * If the notification is not actually visible, then no action will be taken, and the action + * will not be recorded. + */ @CalledByNative private static void hideNotification(int category, String idWithinCategory, int why) { + ActiveNotification activeNotification = findActiveNotification(category, idWithinCategory); + if (!removeActiveNotification(category, idWithinCategory)) return; + Context context = ContextUtils.getApplicationContext(); NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - ActiveNotification activeNotification = findActiveNotification(category, idWithinCategory); - if (activeNotification == null) return; manager.cancel(NOTIFICATION_TAG, activeNotification.mId); - if (removeActiveNotification(category, idWithinCategory)) { - recordCachedActionMetric(why); - } + recordCachedActionMetric(why); } @CalledByNative @@ -285,6 +285,7 @@ return new HashSet<String>(prefValue); } + /** Adds notification to the "active" set. */ private static void addActiveNotification(ActiveNotification notification) { SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); Set<String> activeNotifications = @@ -293,6 +294,7 @@ prefs.edit().putStringSet(PREF_ACTIVE_NOTIFICATIONS, activeNotifications).apply(); } + /** Removes notification from the "active" set. Returns false if it wasn't there. */ private static boolean removeActiveNotification(int category, String idWithinCategory) { SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); ActiveNotification notification = findActiveNotification(category, idWithinCategory);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/VisibleNetworks.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/VisibleNetworks.java index 0910cce6..517d3f8e1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/VisibleNetworks.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/VisibleNetworks.java
@@ -33,10 +33,10 @@ private VisibleNetworks(@Nullable VisibleWifi connectedWifi, @Nullable VisibleCell connectedCell, @Nullable Set<VisibleWifi> allVisibleWifis, @Nullable Set<VisibleCell> allVisibleCells) { - this.mConnectedWifi = connectedWifi; - this.mConnectedCell = connectedCell; - this.mAllVisibleWifis = allVisibleWifis; - this.mAllVisibleCells = allVisibleCells; + mConnectedWifi = connectedWifi; + mConnectedCell = connectedCell; + mAllVisibleWifis = allVisibleWifis; + mAllVisibleCells = allVisibleCells; } public static VisibleNetworks create(@Nullable VisibleWifi connectedWifi, @@ -101,11 +101,10 @@ return false; } VisibleNetworks that = (VisibleNetworks) object; - return ApiCompatibilityUtils.objectEquals(this.mConnectedWifi, that.connectedWifi()) - && ApiCompatibilityUtils.objectEquals(this.mConnectedCell, that.connectedCell()) - && ApiCompatibilityUtils.objectEquals(this.mAllVisibleWifis, that.allVisibleWifis()) - && ApiCompatibilityUtils.objectEquals( - this.mAllVisibleCells, that.allVisibleCells()); + return ApiCompatibilityUtils.objectEquals(mConnectedWifi, that.connectedWifi()) + && ApiCompatibilityUtils.objectEquals(mConnectedCell, that.connectedCell()) + && ApiCompatibilityUtils.objectEquals(mAllVisibleWifis, that.allVisibleWifis()) + && ApiCompatibilityUtils.objectEquals(mAllVisibleCells, that.allVisibleCells()); } private static int objectsHashCode(Object o) { @@ -118,8 +117,8 @@ @Override public int hashCode() { - return objectsHash(this.mConnectedWifi, this.mConnectedCell, - objectsHashCode(this.mAllVisibleWifis), objectsHashCode(this.mAllVisibleCells)); + return objectsHash(mConnectedWifi, mConnectedCell, objectsHashCode(mAllVisibleWifis), + objectsHashCode(mAllVisibleCells)); } /** @@ -139,10 +138,10 @@ private VisibleWifi(@Nullable String ssid, @Nullable String bssid, @Nullable Integer level, @Nullable Long timestampMs) { - this.mSsid = ssid; - this.mBssid = bssid; - this.mLevel = level; - this.mTimestampMs = timestampMs; + mSsid = ssid; + mBssid = bssid; + mLevel = level; + mTimestampMs = timestampMs; } public static VisibleWifi create(@Nullable String ssid, @Nullable String bssid, @@ -194,13 +193,34 @@ } VisibleWifi that = (VisibleWifi) object; - return ApiCompatibilityUtils.objectEquals(this.mSsid, that.ssid()) - && ApiCompatibilityUtils.objectEquals(this.mBssid, that.bssid()); + return ApiCompatibilityUtils.objectEquals(mSsid, that.ssid()) + && ApiCompatibilityUtils.objectEquals(mBssid, that.bssid()); } @Override public int hashCode() { - return VisibleNetworks.objectsHash(this.mSsid, this.mBssid); + return VisibleNetworks.objectsHash(mSsid, mBssid); + } + + /** + * Encodes a VisibleWifi into its corresponding PartnerLocationDescriptor.VisibleNetwork + * proto. + */ + public PartnerLocationDescriptor.VisibleNetwork toProto(boolean connected) { + PartnerLocationDescriptor.VisibleNetwork visibleNetwork = + new PartnerLocationDescriptor.VisibleNetwork(); + + PartnerLocationDescriptor.VisibleNetwork.WiFi wifi = + new PartnerLocationDescriptor.VisibleNetwork.WiFi(); + + wifi.bssid = bssid(); + wifi.levelDbm = level(); + + visibleNetwork.wifi = wifi; + visibleNetwork.timestampMs = timestampMs(); + visibleNetwork.connected = connected; + + return visibleNetwork; } } @@ -252,15 +272,15 @@ private Long mTimestampMs; private VisibleCell(Builder builder) { - this.mRadioType = builder.mRadioType; - this.mCellId = builder.mCellId; - this.mLocationAreaCode = builder.mLocationAreaCode; - this.mMobileCountryCode = builder.mMobileCountryCode; - this.mMobileNetworkCode = builder.mMobileNetworkCode; - this.mPrimaryScramblingCode = builder.mPrimaryScramblingCode; - this.mPhysicalCellId = builder.mPhysicalCellId; - this.mTrackingAreaCode = builder.mTrackingAreaCode; - this.mTimestampMs = builder.mTimestampMs; + mRadioType = builder.mRadioType; + mCellId = builder.mCellId; + mLocationAreaCode = builder.mLocationAreaCode; + mMobileCountryCode = builder.mMobileCountryCode; + mMobileNetworkCode = builder.mMobileNetworkCode; + mPrimaryScramblingCode = builder.mPrimaryScramblingCode; + mPhysicalCellId = builder.mPhysicalCellId; + mTrackingAreaCode = builder.mTrackingAreaCode; + mTimestampMs = builder.mTimestampMs; } /** @@ -347,27 +367,71 @@ return false; } VisibleCell that = (VisibleCell) object; - return ApiCompatibilityUtils.objectEquals(this.mRadioType, that.radioType()) - && ApiCompatibilityUtils.objectEquals(this.mCellId, that.cellId()) + return ApiCompatibilityUtils.objectEquals(mRadioType, that.radioType()) + && ApiCompatibilityUtils.objectEquals(mCellId, that.cellId()) && ApiCompatibilityUtils.objectEquals( - this.mLocationAreaCode, that.locationAreaCode()) + mLocationAreaCode, that.locationAreaCode()) && ApiCompatibilityUtils.objectEquals( - this.mMobileCountryCode, that.mobileCountryCode()) + mMobileCountryCode, that.mobileCountryCode()) && ApiCompatibilityUtils.objectEquals( - this.mMobileNetworkCode, that.mobileNetworkCode()) + mMobileNetworkCode, that.mobileNetworkCode()) && ApiCompatibilityUtils.objectEquals( - this.mPrimaryScramblingCode, that.primaryScramblingCode()) + mPrimaryScramblingCode, that.primaryScramblingCode()) + && ApiCompatibilityUtils.objectEquals(mPhysicalCellId, that.physicalCellId()) && ApiCompatibilityUtils.objectEquals( - this.mPhysicalCellId, that.physicalCellId()) - && ApiCompatibilityUtils.objectEquals( - this.mTrackingAreaCode, that.trackingAreaCode()); + mTrackingAreaCode, that.trackingAreaCode()); } @Override public int hashCode() { - return VisibleNetworks.objectsHash(this.mRadioType, this.mCellId, - this.mLocationAreaCode, this.mMobileCountryCode, this.mMobileNetworkCode, - this.mPrimaryScramblingCode, this.mPhysicalCellId, this.mTrackingAreaCode); + return VisibleNetworks.objectsHash(mRadioType, mCellId, mLocationAreaCode, + mMobileCountryCode, mMobileNetworkCode, mPrimaryScramblingCode, mPhysicalCellId, + mTrackingAreaCode); + } + + /** + * Encodes a VisibleCell into its corresponding PartnerLocationDescriptor.VisibleNetwork + * proto. + */ + public PartnerLocationDescriptor.VisibleNetwork toProto(boolean connected) { + PartnerLocationDescriptor.VisibleNetwork visibleNetwork = + new PartnerLocationDescriptor.VisibleNetwork(); + + PartnerLocationDescriptor.VisibleNetwork.Cell cell = + new PartnerLocationDescriptor.VisibleNetwork.Cell(); + + switch (radioType()) { + case VisibleCell.CDMA_RADIO_TYPE: + cell.type = PartnerLocationDescriptor.VisibleNetwork.Cell.CDMA; + break; + case VisibleCell.GSM_RADIO_TYPE: + cell.type = PartnerLocationDescriptor.VisibleNetwork.Cell.GSM; + break; + case VisibleCell.LTE_RADIO_TYPE: + cell.type = PartnerLocationDescriptor.VisibleNetwork.Cell.LTE; + break; + case VisibleCell.WCDMA_RADIO_TYPE: + cell.type = PartnerLocationDescriptor.VisibleNetwork.Cell.WCDMA; + break; + case VisibleCell.UNKNOWN_RADIO_TYPE: + case VisibleCell.UNKNOWN_MISSING_LOCATION_PERMISSION_RADIO_TYPE: + default: + cell.type = PartnerLocationDescriptor.VisibleNetwork.Cell.UNKNOWN; + break; + } + cell.cellId = cellId(); + cell.locationAreaCode = locationAreaCode(); + cell.mobileCountryCode = mobileCountryCode(); + cell.mobileNetworkCode = mobileNetworkCode(); + cell.primaryScramblingCode = primaryScramblingCode(); + cell.physicalCellId = physicalCellId(); + cell.trackingAreaCode = trackingAreaCode(); + + visibleNetwork.cell = cell; + visibleNetwork.timestampMs = timestampMs(); + visibleNetwork.connected = connected; + + return visibleNetwork; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java index efaf9f0b..864760e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java
@@ -27,6 +27,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.components.url_formatter.UrlFormatter; import org.chromium.content_public.browser.WebContents; import org.chromium.payments.mojom.PaymentCurrencyAmount; import org.chromium.payments.mojom.PaymentDetailsModifier; @@ -166,9 +167,9 @@ public void onServiceDisconnected(ComponentName name) {} }; - mIsReadyToPayIntent.putExtras(buildExtras(null /* id */, null /* merchantName */, origin, - iframeOrigin, certificateChain, methodDataMap, total, null /* displayItems */, - null /* modifiers */)); + mIsReadyToPayIntent.putExtras(buildExtras(null /* id */, null /* merchantName */, + removeUrlScheme(origin), removeUrlScheme(iframeOrigin), certificateChain, + methodDataMap, total, null /* displayItems */, null /* modifiers */)); try { if (!ContextUtils.getApplicationContext().bindService( mIsReadyToPayIntent, mServiceConnection, Context.BIND_AUTO_CREATE)) { @@ -264,17 +265,19 @@ } @Override - public void invokePaymentApp(final String id, final String merchantName, final String origin, - final String iframeOrigin, final byte[][] certificateChain, + public void invokePaymentApp(final String id, final String merchantName, String origin, + String iframeOrigin, final byte[][] certificateChain, final Map<String, PaymentMethodData> methodDataMap, final PaymentItem total, final List<PaymentItem> displayItems, final Map<String, PaymentDetailsModifier> modifiers, InstrumentDetailsCallback callback) { mInstrumentDetailsCallback = callback; + final String schemelessOrigin = removeUrlScheme(origin); + final String schemelessIframeOrigin = removeUrlScheme(iframeOrigin); if (!mIsIncognito) { - launchPaymentApp(id, merchantName, origin, iframeOrigin, certificateChain, - methodDataMap, total, displayItems, modifiers); + launchPaymentApp(id, merchantName, schemelessOrigin, schemelessIframeOrigin, + certificateChain, methodDataMap, total, displayItems, modifiers); return; } @@ -291,9 +294,9 @@ new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - launchPaymentApp(id, merchantName, origin, iframeOrigin, - certificateChain, methodDataMap, total, displayItems, - modifiers); + launchPaymentApp(id, merchantName, schemelessOrigin, + schemelessIframeOrigin, certificateChain, methodDataMap, + total, displayItems, modifiers); } }) .setNegativeButton(R.string.cancel, @@ -312,6 +315,10 @@ .show(); } + private static String removeUrlScheme(String url) { + return UrlFormatter.formatUrlForSecurityDisplay(url, false /* omit scheme */); + } + private void launchPaymentApp(String id, String merchantName, String origin, String iframeOrigin, byte[][] certificateChain, Map<String, PaymentMethodData> methodDataMap, PaymentItem total,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentInstrument.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentInstrument.java index f8973c96d..b10e349 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentInstrument.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentInstrument.java
@@ -5,10 +5,10 @@ package org.chromium.chrome.browser.payments; import android.content.Context; +import android.support.v7.content.res.AppCompatResources; import android.text.TextUtils; import android.util.JsonWriter; -import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.autofill.PersonalDataManager; @@ -66,8 +66,8 @@ if (context == null) return; if (card.getIssuerIconDrawableId() != 0) { - updateDrawableIcon(ApiCompatibilityUtils.getDrawable( - context.getResources(), card.getIssuerIconDrawableId())); + updateDrawableIcon( + AppCompatResources.getDrawable(context, card.getIssuerIconDrawableId())); } checkAndUpateCardCompleteness(context); @@ -261,8 +261,7 @@ if (context == null) return; updateIdentifierLabelsAndIcon(card.getGUID(), card.getObfuscatedNumber(), card.getName(), - null, ApiCompatibilityUtils.getDrawable( - context.getResources(), card.getIssuerIconDrawableId())); + null, AppCompatResources.getDrawable(context, card.getIssuerIconDrawableId())); checkAndUpateCardCompleteness(context); assert mIsComplete; assert mHasValidNumberAndName;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java index f12ab2e..281c0fb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java
@@ -54,7 +54,7 @@ private static class CardIssuerNetwork { /** * The identifier for the drawable resource of the card issuer network, e.g., - * R.drawable.pr_visa. + * R.drawable.visa_card. */ public final int icon; @@ -211,21 +211,21 @@ mCardIssuerNetworks = new HashMap<>(); mCardIssuerNetworks.put( - AMEX, new CardIssuerNetwork(R.drawable.pr_amex, R.string.autofill_cc_amex)); - mCardIssuerNetworks.put(DINERS, - new CardIssuerNetwork(R.drawable.pr_dinersclub, R.string.autofill_cc_diners)); + AMEX, new CardIssuerNetwork(R.drawable.amex_card, R.string.autofill_cc_amex)); + mCardIssuerNetworks.put( + DINERS, new CardIssuerNetwork(R.drawable.diners_card, R.string.autofill_cc_diners)); mCardIssuerNetworks.put(DISCOVER, - new CardIssuerNetwork(R.drawable.pr_discover, R.string.autofill_cc_discover)); + new CardIssuerNetwork(R.drawable.discover_card, R.string.autofill_cc_discover)); mCardIssuerNetworks.put( - JCB, new CardIssuerNetwork(R.drawable.pr_jcb, R.string.autofill_cc_jcb)); + JCB, new CardIssuerNetwork(R.drawable.jcb_card, R.string.autofill_cc_jcb)); mCardIssuerNetworks.put(MASTERCARD, - new CardIssuerNetwork(R.drawable.pr_mc, R.string.autofill_cc_mastercard)); + new CardIssuerNetwork(R.drawable.mc_card, R.string.autofill_cc_mastercard)); mCardIssuerNetworks.put( - MIR, new CardIssuerNetwork(R.drawable.pr_mir, R.string.autofill_cc_mir)); + MIR, new CardIssuerNetwork(R.drawable.mir_card, R.string.autofill_cc_mir)); mCardIssuerNetworks.put(UNIONPAY, - new CardIssuerNetwork(R.drawable.pr_unionpay, R.string.autofill_cc_union_pay)); + new CardIssuerNetwork(R.drawable.unionpay_card, R.string.autofill_cc_union_pay)); mCardIssuerNetworks.put( - VISA, new CardIssuerNetwork(R.drawable.pr_visa, R.string.autofill_cc_visa)); + VISA, new CardIssuerNetwork(R.drawable.visa_card, R.string.autofill_cc_visa)); mAcceptedIssuerNetworks = new HashSet<>(); mAcceptedBasicCardIssuerNetworks = new HashSet<>();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java index a5ecb24a..d21b6367 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -257,9 +257,8 @@ private final Handler mHandler = new Handler(); private final RenderFrameHost mRenderFrameHost; private final WebContents mWebContents; - private final String mSchemelessOriginForPaymentApp; - private final String mOriginForDisplay; - private final String mSchemelessIFrameOriginForPaymentApp; + private final String mTopLevelOrigin; + private final String mPaymentRequestOrigin; private final String mMerchantName; @Nullable private final byte[][] mCertificateChain; @@ -364,15 +363,12 @@ assert renderFrameHost != null; mRenderFrameHost = renderFrameHost; - mSchemelessIFrameOriginForPaymentApp = UrlFormatter.formatUrlForSecurityDisplay( - mRenderFrameHost.getLastCommittedURL(), false /* omit scheme for payment apps. */); mWebContents = WebContentsStatics.fromRenderFrameHost(renderFrameHost); - mSchemelessOriginForPaymentApp = UrlFormatter.formatUrlForSecurityDisplay( - mWebContents.getLastCommittedUrl(), false /* omit scheme for payment apps. */); - - mOriginForDisplay = UrlFormatter.formatUrlForSecurityDisplay( - mWebContents.getLastCommittedUrl(), true /* include scheme in display */); + mPaymentRequestOrigin = UrlFormatter.formatUrlForSecurityDisplay( + mRenderFrameHost.getLastCommittedURL(), true); + mTopLevelOrigin = + UrlFormatter.formatUrlForSecurityDisplay(mWebContents.getLastCommittedUrl(), true); mMerchantName = mWebContents.getTitle(); @@ -521,7 +517,7 @@ mUI = new PaymentRequestUI(activity, this, mRequestShipping, mRequestPayerName || mRequestPayerPhone || mRequestPayerEmail, mMerchantSupportsAutofillPaymentInstruments, - !PaymentPreferencesUtil.isPaymentCompleteOnce(), mMerchantName, mOriginForDisplay, + !PaymentPreferencesUtil.isPaymentCompleteOnce(), mMerchantName, mTopLevelOrigin, SecurityStateModel.getSecurityLevelForWebContents(mWebContents), new ShippingStrings(mShippingType)); @@ -717,8 +713,7 @@ } if (queryApps.isEmpty()) { - CanMakePaymentQuery query = - sCanMakePaymentQueries.get(mSchemelessIFrameOriginForPaymentApp); + CanMakePaymentQuery query = sCanMakePaymentQueries.get(mPaymentRequestOrigin); if (query != null && query.matchesPaymentMethods(mMethodData)) { query.notifyObserversOfResponse(mCanMakePayment); } @@ -730,8 +725,8 @@ // so a fast response from a non-autofill payment app at the front of the app list does not // cause NOT_SUPPORTED payment rejection. for (Map.Entry<PaymentApp, Map<String, PaymentMethodData>> q : queryApps.entrySet()) { - q.getKey().getInstruments(q.getValue(), mSchemelessOriginForPaymentApp, - mSchemelessIFrameOriginForPaymentApp, mCertificateChain, mRawTotal, this); + q.getKey().getInstruments(q.getValue(), mTopLevelOrigin, mPaymentRequestOrigin, + mCertificateChain, mRawTotal, this); } } @@ -1302,10 +1297,9 @@ } } - instrument.invokePaymentApp(mId, mMerchantName, mSchemelessOriginForPaymentApp, - mSchemelessIFrameOriginForPaymentApp, mCertificateChain, - Collections.unmodifiableMap(methodData), mRawTotal, mRawLineItems, - Collections.unmodifiableMap(modifiers), this); + instrument.invokePaymentApp(mId, mMerchantName, mTopLevelOrigin, mPaymentRequestOrigin, + mCertificateChain, Collections.unmodifiableMap(methodData), mRawTotal, + mRawLineItems, Collections.unmodifiableMap(modifiers), this); mJourneyLogger.setEventOccurred(JourneyLogger.EVENT_PAY_CLICKED); return !(instrument instanceof AutofillPaymentInstrument); @@ -1391,19 +1385,18 @@ public void canMakePayment() { if (mClient == null) return; - CanMakePaymentQuery query = - sCanMakePaymentQueries.get(mSchemelessIFrameOriginForPaymentApp); + CanMakePaymentQuery query = sCanMakePaymentQueries.get(mPaymentRequestOrigin); if (query == null) { // If there has not been a canMakePayment() query in the last 30 minutes, take a note // that one has happened just now. Remember the payment method names and the // corresponding data for the next 30 minutes. Forget about it after the 30 minute // period expires. query = new CanMakePaymentQuery(Collections.unmodifiableMap(mMethodData)); - sCanMakePaymentQueries.put(mSchemelessIFrameOriginForPaymentApp, query); + sCanMakePaymentQueries.put(mPaymentRequestOrigin, query); mHandler.postDelayed(new Runnable() { @Override public void run() { - sCanMakePaymentQueries.remove(mSchemelessIFrameOriginForPaymentApp); + sCanMakePaymentQueries.remove(mPaymentRequestOrigin); } }, CAN_MAKE_PAYMENT_QUERY_PERIOD_MS); } else if (shouldEnforceCanMakePaymentQueryQuota() @@ -1427,8 +1420,7 @@ boolean isIgnoringQueryQuota = false; if (!shouldEnforceCanMakePaymentQueryQuota()) { - CanMakePaymentQuery query = - sCanMakePaymentQueries.get(mSchemelessIFrameOriginForPaymentApp); + CanMakePaymentQuery query = sCanMakePaymentQueries.get(mPaymentRequestOrigin); // The cached query may have expired between instantiation of PaymentRequest and // finishing the query of the payment apps. if (query != null) { @@ -1572,8 +1564,7 @@ } } - CanMakePaymentQuery query = - sCanMakePaymentQueries.get(mSchemelessIFrameOriginForPaymentApp); + CanMakePaymentQuery query = sCanMakePaymentQueries.get(mPaymentRequestOrigin); if (query != null && query.matchesPaymentMethods(mMethodData)) { query.notifyObserversOfResponse(mCanMakePayment); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorIconsField.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorIconsField.java index afce857..b9b48d67 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorIconsField.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorIconsField.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.payments.ui; import android.content.Context; +import android.support.v7.content.res.AppCompatResources; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -47,8 +48,8 @@ ApiCompatibilityUtils.setMarginEnd(layoutParams, margin); for (int i = 0; i < fieldModel.getIconResourceIds().size(); i++) { ImageView icon = new ImageView(context); - icon.setImageResource(fieldModel.getIconResourceIds().get(i)); - icon.setBackgroundResource(R.drawable.payments_ui_logo_bg); + icon.setImageDrawable(AppCompatResources.getDrawable( + context, fieldModel.getIconResourceIds().get(i))); icon.setContentDescription(context.getString( fieldModel.getIconDescriptionsForAccessibility().get(i))); icon.setAdjustViewBounds(true);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorLabelField.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorLabelField.java index 9b1eece8..695fe43 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorLabelField.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorLabelField.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.payments.ui; import android.content.Context; +import android.support.v7.content.res.AppCompatResources; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -49,11 +50,9 @@ ((TextView) mLayout.findViewById(R.id.top_label)).setText(fieldModel.getLabel()); ((TextView) mLayout.findViewById(R.id.mid_label)).setText(fieldModel.getMidLabel()); ((TextView) mLayout.findViewById(R.id.bottom_label)).setText(fieldModel.getBottomLabel()); - - ((ImageView) mLayout.findViewById(R.id.icon)).setImageResource( - fieldModel.getLabelIconResourceId()); ((ImageView) mLayout.findViewById(R.id.icon)) - .setBackgroundResource(R.drawable.payments_ui_logo_bg); + .setImageDrawable(AppCompatResources.getDrawable( + context, fieldModel.getLabelIconResourceId())); } /** @return The View containing everything. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorTextField.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorTextField.java index 46a027a..d7838c7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorTextField.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorTextField.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.payments.ui; import android.content.Context; +import android.support.v7.content.res.AppCompatResources; import android.text.Editable; import android.text.InputFilter; import android.text.InputType; @@ -91,7 +92,6 @@ if (fieldModel.getValueIconGenerator() != null) { mValueIcon = (ImageView) mIconsLayer.findViewById(R.id.value_icon); - mValueIcon.setBackgroundResource(R.drawable.payments_ui_logo_bg); mValueIcon.setVisibility(VISIBLE); } @@ -270,7 +270,7 @@ if (mValueIconId == 0) { mValueIcon.setVisibility(GONE); } else { - mValueIcon.setImageResource(mValueIconId); + mValueIcon.setImageDrawable(AppCompatResources.getDrawable(getContext(), mValueIconId)); mValueIcon.setVisibility(VISIBLE); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java index 665f1a3b..0ca58da 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java
@@ -184,17 +184,11 @@ * Sets what logo should be displayed. * * @param logo The logo to display. - * @param drawBorder Whether draw border background for the logo. */ - protected void setLogoDrawable(Drawable logo, boolean drawBorder) { + protected void setLogoDrawable(Drawable logo) { assert isLogoNecessary(); mLogo = logo; - - if (drawBorder) { - mLogoView.setBackgroundResource(R.drawable.payments_ui_logo_bg); - } else { - mLogoView.setBackgroundResource(0); - } + mLogoView.setBackgroundResource(0); mLogoView.setImageDrawable(mLogo); } @@ -1111,8 +1105,6 @@ ImageView optionIcon = new ImageView(parent.getContext()); optionIcon.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO); if (mOption.isEditable()) { - // Draw border background for the icon if the option is editable. - optionIcon.setBackgroundResource(R.drawable.payments_ui_logo_bg); optionIcon.setMaxWidth(mEditableOptionIconMaxWidth); } else { optionIcon.setMaxWidth(mNonEditableOptionIconMaxWidth); @@ -1376,7 +1368,7 @@ } if (selectedItem == null) { - setLogoDrawable(null, false); + setLogoDrawable(null); // Section summary should be displayed as R.style.PaymentsUiSectionDescriptiveText. if (!mSummaryInDescriptiveText) { ApiCompatibilityUtils.setTextAppearance( @@ -1386,7 +1378,7 @@ SectionUiUtils.showSectionSummaryInTextViewInSingeLine( getContext(), mSectionInformation, getSummaryLeftTextView()); } else { - setLogoDrawable(selectedItem.getDrawableIcon(), selectedItem.isEditable()); + setLogoDrawable(selectedItem.getDrawableIcon()); // Selected item summary should be displayed as // R.style.PaymentsUiSectionDefaultText. if (mSummaryInDescriptiveText) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java index 56968d8..c573b63 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java
@@ -71,8 +71,12 @@ if (isMovingUp && !mAnimatingToolbarButtonDisappearance && mToolbarButtonVisibilityPercent != 0.f) { animateToolbarButtonVisibility(false); - } else if (isMovingDown && heightFraction <= 0.5f && !mAnimatingToolbarButtonAppearance + } else if (isMovingDown && heightFraction < 0.45f && !mAnimatingToolbarButtonAppearance && mToolbarButtonVisibilityPercent != 1.f) { + // If the sheet is moving down and the height is less than 45% of the max, start + // showing the toolbar buttons. 45% is used rather than 50% so that the buttons + // aren't shown in the half height state if the user is dragging the sheet down + // slowly and releases at exactly the half way point. animateToolbarButtonVisibility(true); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestAbortTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestAbortTest.java index 13ebc38f8..024d116 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestAbortTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestAbortTest.java
@@ -45,7 +45,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "555-555-5555", "jon.doe@google.com", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBasicCardTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBasicCardTest.java index b89923c..ae6adbd 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBasicCardTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBasicCardTest.java
@@ -34,7 +34,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "555-555-5555", "", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressTest.java index d5e3226..4276ede 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressTest.java
@@ -59,7 +59,7 @@ "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "650-253-0000", "jon.doe@gmail.com", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, profile1, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, profile1, "" /* serverId */)); String profile2 = helper.setProfile(new AutofillProfile("", "https://example.com", true, "Rob Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", @@ -94,7 +94,7 @@ // This card has no billing address selected. helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jane Doe", - "4242424242424242", "1111", "12", "2050", "visa", R.drawable.pr_visa, profile6, + "4242424242424242", "1111", "12", "2050", "visa", R.drawable.visa_card, profile6, "" /* serverId */)); // Assign use stats so that incomplete profiles have the highest frecency, profile2 has the
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressWithoutPhoneTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressWithoutPhoneTest.java index 1352ed3c..ad4c946 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressWithoutPhoneTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressWithoutPhoneTest.java
@@ -60,7 +60,7 @@ "https://example.com", true, "Jon NoPhone", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "", "jon.doe@gmail.com", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, address_without_phone, "" /* serverId */)); String address_with_phone = helper.setProfile(new AutofillProfile("", "https://example.com", true, "Rob Phone", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentQueryNoCardTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentQueryNoCardTest.java index 3b3b6c7..362acde 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentQueryNoCardTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentQueryNoCardTest.java
@@ -49,7 +49,7 @@ // canMakePayment() to return true. new AutofillTestHelper().setCreditCard(new CreditCard("", "https://example.com", true, true, "" /* nameOnCard */, "4111111111111111", "1111", "12", "2050", "visa", - R.drawable.pr_visa, "" /* billingAddressId */, "" /* serverId */)); + R.drawable.visa_card, "" /* billingAddressId */, "" /* serverId */)); } @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentQueryTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentQueryTest.java index c5e22816..139c647 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentQueryTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentQueryTest.java
@@ -48,7 +48,7 @@ // The user has a valid credit card without a billing address on file. This is sufficient // for canMakePayment() to return true. new AutofillTestHelper().setCreditCard(new CreditCard("", "https://example.com", true, true, - "Jon Doe", "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "Jon Doe", "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, "" /* billingAddressId */, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCardEditorAutoAdvanceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCardEditorAutoAdvanceTest.java index d8b71c3..65adf11 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCardEditorAutoAdvanceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCardEditorAutoAdvanceTest.java
@@ -53,7 +53,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "555-555-5555", "", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "1", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "1", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCcCanMakePaymentQueryNoCardTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCcCanMakePaymentQueryNoCardTest.java index ba4bd4e..2188897b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCcCanMakePaymentQueryNoCardTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCcCanMakePaymentQueryNoCardTest.java
@@ -44,7 +44,7 @@ // canMakePayment() to return true. new AutofillTestHelper().setCreditCard(new CreditCard("", "https://example.com", true, true, "" /* nameOnCard */, "4111111111111111", "1111", "12", "2050", "visa", - R.drawable.pr_visa, "" /* billingAddressId */, "" /* serverId */)); + R.drawable.visa_card, "" /* billingAddressId */, "" /* serverId */)); } @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCcCanMakePaymentQueryTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCcCanMakePaymentQueryTest.java index c52f299..9e98dbe 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCcCanMakePaymentQueryTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCcCanMakePaymentQueryTest.java
@@ -30,7 +30,7 @@ // The user has a valid credit card without a billing address on file. This is sufficient // for canMakePayment() to return true. new AutofillTestHelper().setCreditCard(new CreditCard("", "https://example.com", true, true, - "Jon Doe", "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "Jon Doe", "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, "" /* billingAddressId */, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsAndFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsAndFreeShippingTest.java index 98b2821..0e95190a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsAndFreeShippingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsAndFreeShippingTest.java
@@ -51,7 +51,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "555-555-5555", "jon.doe@google.com", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDynamicShippingSingleAddressTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDynamicShippingSingleAddressTest.java index 539f284..e768058 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDynamicShippingSingleAddressTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDynamicShippingSingleAddressTest.java
@@ -52,7 +52,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "650-253-0000", "", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndFreeShippingTest.java index d53e2fc..24e21c71 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndFreeShippingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndFreeShippingTest.java
@@ -50,7 +50,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "555-555-5555", "jon.doe@google.com", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExpiredLocalCardTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExpiredLocalCardTest.java index 1877d7f..665ae83 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExpiredLocalCardTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExpiredLocalCardTest.java
@@ -54,7 +54,7 @@ "US", "555-555-5555", "", "en-US")); // Create an expired credit card mCreditCardId = mHelper.setCreditCard(new CreditCard("", "https://example.com", true, true, - "Jon Doe", "4111111111111111", "1111", "1", "2016", "visa", R.drawable.pr_visa, + "Jon Doe", "4111111111111111", "1111", "1", "2016", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExtraShippingOptionsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExtraShippingOptionsTest.java index 3ea9de7d..8fbf9afe 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExtraShippingOptionsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExtraShippingOptionsTest.java
@@ -47,7 +47,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "555-555-5555", "", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFailCompleteTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFailCompleteTest.java index d879f73..b206d0e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFailCompleteTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFailCompleteTest.java
@@ -46,7 +46,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "310-310-6000", "jon.doe@gmail.com", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFreeShippingTest.java index 3fd3d47..7b1892d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFreeShippingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFreeShippingTest.java
@@ -51,7 +51,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "650-253-0000", "", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIdTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIdTest.java index 4e0192e9..330687e4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIdTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIdTest.java
@@ -47,7 +47,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "555-555-5555", "", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteServerCardTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteServerCardTest.java index 703de2e..9b48730a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteServerCardTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteServerCardTest.java
@@ -49,7 +49,7 @@ "US", "310-310-6000", "jon.doe@gmail.com", "en-US")); helper.addServerCreditCard(new CreditCard("", "https://example.com", false /* isLocal */, true /* isCached */, "Jon Doe", "4111111111111111", "1111", "12", "2050", "visa", - R.drawable.pr_visa, "" /* billing address */, "" /* serverId */)); + R.drawable.visa_card, "" /* billing address */, "" /* serverId */)); } /** Click [PAY] and dismiss the card unmask dialog. */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java index 6172c6c..7bce4839 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java
@@ -52,14 +52,14 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "650-253-0000", "", "en-US")); mHelper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, mBillingAddressId, "" /* serverId */)); // The user also has an incomplete address and an incomplete card saved. String mIncompleteAddressId = mHelper.setProfile(new AutofillProfile("", "https://example.com", true, "In Complete", "Google", "344 Main St", "CA", "", "", "90291", "", "US", "650-253-0000", "", "en-US")); mHelper.setCreditCard(new CreditCard("", "https://example.com", true, true, "", - "4111111111111111", "1111", "18", "2075", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "18", "2075", "visa", R.drawable.visa_card, mIncompleteAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMetricsTest.java index e4d72a6..d7a9fb9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMetricsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMetricsTest.java
@@ -58,7 +58,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "650-253-0000", "", "en-US")); mHelper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, mBillingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameAndFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameAndFreeShippingTest.java index 7917fba5..068ed39 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameAndFreeShippingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameAndFreeShippingTest.java
@@ -50,7 +50,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "555-555-5555", "", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameTest.java index e653ece..e9a58e5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameTest.java
@@ -49,7 +49,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "555-555-5555", "jon.doe@google.com", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); // Add the same profile but with a different address.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java index 486cd42f..4324a007 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java
@@ -55,7 +55,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "650-253-0000", "jon.doe@gmail.com", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppAndCardsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppAndCardsTest.java index 9e0b35a..67d311f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppAndCardsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppAndCardsTest.java
@@ -53,12 +53,12 @@ "US", "310-310-6000", "jon.doe@gmail.com", "en-US")); // Mastercard card without a billing address. helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "5454545454545454", "", "12", "2050", "mastercard", R.drawable.pr_mc, + "5454545454545454", "", "12", "2050", "mastercard", R.drawable.mc_card, "" /* billingAddressId */, "" /* serverId */)); // Visa card with complete set of information. helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "", "12", "2050", "visa", R.drawable.pr_visa, billingAddressId, - "" /* serverId */)); + "4111111111111111", "", "12", "2050", "visa", R.drawable.visa_card, + billingAddressId, "" /* serverId */)); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppsSortingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppsSortingTest.java index 86a7bff..d969128 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppsSortingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppsSortingTest.java
@@ -55,8 +55,8 @@ // Visa card with complete set of information. This payment method is always listed // behind non-autofill payment instruments in payment request. helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "", "12", "2050", "visa", R.drawable.pr_visa, billingAddressId, - "" /* serverId */)); + "4111111111111111", "", "12", "2050", "visa", R.drawable.visa_card, + billingAddressId, "" /* serverId */)); } @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneAndFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneAndFreeShippingTest.java index bd46925..fc11573 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneAndFreeShippingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneAndFreeShippingTest.java
@@ -50,7 +50,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "555-555-5555", "", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRemoveBillingAddressTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRemoveBillingAddressTest.java index d7bf7f5..4f35fb7a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRemoveBillingAddressTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRemoveBillingAddressTest.java
@@ -53,7 +53,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "555-555-5555", "jon.doe@google.com", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Alice", - "4111111111111111", "1111", "1", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "1", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); helper.deleteProfile(billingAddressId); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestServerCardTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestServerCardTest.java index 5ac47af..44ee6d60 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestServerCardTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestServerCardTest.java
@@ -47,7 +47,7 @@ "US", "310-310-6000", "jon.doe@gmail.com", "en-US")); helper.addServerCreditCard(new CreditCard("4754d21d-8773-40b6-b4be-5f7486be834f", "https://example.com", false /* isLocal */, true /* isCached */, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShippingAddressChangeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShippingAddressChangeTest.java index e99e614..fcd116f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShippingAddressChangeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShippingAddressChangeTest.java
@@ -46,7 +46,7 @@ true, "Jon Doe", "Google", "340 Main St", "California", "Los Angeles", "", "90291", "", "US", "650-253-0000", "", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShippingAddressTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShippingAddressTest.java index 396761ca..00f2979 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShippingAddressTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShippingAddressTest.java
@@ -47,7 +47,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "555-555-5555", "", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, firstAddressId, "" /* serverId */)); // The user has a second address.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowTwiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowTwiceTest.java index c1470c1..509b0bb2 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowTwiceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowTwiceTest.java
@@ -47,7 +47,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "555-555-5555", "", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTabTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTabTest.java index 6e292dd..1ff76c0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTabTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTabTest.java
@@ -53,7 +53,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "555-555-5555", "jon.doe@google.com", "en-US")); helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, billingAddressId, "" /* serverId */)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestUseStatsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestUseStatsTest.java index f23aff8..4991fc1a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestUseStatsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestUseStatsTest.java
@@ -53,7 +53,7 @@ true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "555-555-5555", "", "en-US")); mCreditCardId = mHelper.setCreditCard(new CreditCard("", "https://example.com", true, true, - "Jon Doe", "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa, + "Jon Doe", "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, mBillingAddressId, "" /* serverId */)); // Set specific use stats for the profile and credit card. mHelper.setProfileUseStatsForTesting(mBillingAddressId, 20, 5000);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/geo/VisibleNetworksTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/geo/VisibleNetworksTest.java index 18d612d..6d20856 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/geo/VisibleNetworksTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/geo/VisibleNetworksTest.java
@@ -7,8 +7,13 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import android.util.Base64; + +import com.google.protobuf.nano.MessageNano; + import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.annotation.Config; @@ -50,8 +55,11 @@ .setLocationAreaCode(11) .setMobileCountryCode(12) .setMobileNetworkCode(13); - private static final VisibleCell VISIBLE_CELL1 = - sVisibleCellCommunBuilder.setTimestamp(10L).build(); + private static final VisibleCell VISIBLE_CELL1 = sVisibleCellCommunBuilder.setPhysicalCellId(14) + .setPrimaryScramblingCode(15) + .setTrackingAreaCode(16) + .setTimestamp(10L) + .build(); private static final VisibleCell VISIBLE_CELL1_DIFFERENT_TIMESTAMP = sVisibleCellCommunBuilder.setTimestamp(20L).build(); private static final VisibleCell VISIBLE_CELL2 = VisibleCell.builder(VisibleCell.GSM_RADIO_TYPE) @@ -61,6 +69,10 @@ .setMobileNetworkCode(33) .setTimestamp(30L) .build(); + private static final VisibleCell EMPTY_CELL = + VisibleCell.builder(VisibleCell.UNKNOWN_RADIO_TYPE).build(); + private static final VisibleWifi EMPTY_WIFI = VisibleWifi.create(null, null, null, null); + private static Set<VisibleCell> sAllVisibleCells = new HashSet<VisibleCell>(Arrays.asList(VISIBLE_CELL1, VISIBLE_CELL2)); private static Set<VisibleCell> sAllVisibleCells2 = new HashSet<VisibleCell>( @@ -74,6 +86,13 @@ private static final VisibleNetworks VISIBLE_NETWORKS2 = VisibleNetworks.create( VISIBLE_WIFI2, VISIBLE_CELL2, sAllVisibleWifis, sAllVisibleCells2); + private static final String VISIBLE_CELL1_PROTO_ENCODED = + "CAEQDLoBFhIQCAEQChgLIAwoDTAPOA5AEBgBIAo="; + private static final String VISIBLE_WIFI1_PROTO_ENCODED = + "CAEQDLoBJAoeChExMToxMToxMToxMToxMToxMRD___________8BGAEgCg=="; + private static final String EMPTY_CELL_PROTO_ENCODED = "CAEQDLoBBhICCAAYAQ=="; + private static final String EMPTY_WIFI_PROTO_ENCODED = "CAEQDLoBBAoAGAE="; + @Test public void testVisibleWifiCreate() { VisibleWifi visibleWifi = VisibleWifi.create(SSID1, BSSID1, LEVEL1, TIMESTAMP1); @@ -119,6 +138,34 @@ } @Test + public void testVisibleWifiToProto() { + boolean connected = true; + PartnerLocationDescriptor.VisibleNetwork visibleNetwork = VISIBLE_WIFI1.toProto(connected); + PartnerLocationDescriptor.VisibleNetwork.WiFi wifi = visibleNetwork.wifi; + + assertEquals(VISIBLE_WIFI1.bssid(), wifi.bssid); + assertEquals(VISIBLE_WIFI1.level(), wifi.levelDbm); + assertEquals(VISIBLE_WIFI1.timestampMs(), visibleNetwork.timestampMs); + assertEquals(connected, visibleNetwork.connected); + + assertEquals(VISIBLE_WIFI1_PROTO_ENCODED, encodeVisibleNetwork(visibleNetwork)); + } + + @Test + public void testVisibleWifiToProtoEmptyWifi() { + boolean connected = true; + PartnerLocationDescriptor.VisibleNetwork visibleNetwork = EMPTY_WIFI.toProto(connected); + PartnerLocationDescriptor.VisibleNetwork.WiFi wifi = visibleNetwork.wifi; + + assertNull(wifi.bssid); + assertNull(wifi.levelDbm); + assertNull(visibleNetwork.timestampMs); + assertEquals(connected, visibleNetwork.connected); + + assertEquals(EMPTY_WIFI_PROTO_ENCODED, encodeVisibleNetwork(visibleNetwork)); + } + + @Test public void testVisibleCellBuilder() { for (@RadioType int radioType : RADIO_TYPES) { VisibleCell visibleCell = VisibleCell.builder(radioType).build(); @@ -134,6 +181,9 @@ .setLocationAreaCode(VISIBLE_CELL1.locationAreaCode()) .setMobileCountryCode(VISIBLE_CELL1.mobileCountryCode()) .setMobileNetworkCode(VISIBLE_CELL1.mobileNetworkCode()) + .setPhysicalCellId(VISIBLE_CELL1.physicalCellId()) + .setPrimaryScramblingCode(VISIBLE_CELL1.primaryScramblingCode()) + .setTrackingAreaCode(VISIBLE_CELL1.trackingAreaCode()) .setTimestamp(VISIBLE_CELL1.timestampMs()) .build(); assertNotEquals(VISIBLE_CELL2, VISIBLE_CELL1); @@ -154,6 +204,9 @@ .setLocationAreaCode(VISIBLE_CELL1.locationAreaCode()) .setMobileCountryCode(VISIBLE_CELL1.mobileCountryCode()) .setMobileNetworkCode(VISIBLE_CELL1.mobileNetworkCode()) + .setPhysicalCellId(VISIBLE_CELL1.physicalCellId()) + .setPrimaryScramblingCode(VISIBLE_CELL1.primaryScramblingCode()) + .setTrackingAreaCode(VISIBLE_CELL1.trackingAreaCode()) .setTimestamp(VISIBLE_CELL1.timestampMs()) .build(); @@ -168,6 +221,46 @@ } @Test + public void testVisibleCellToProto() { + boolean connected = true; + PartnerLocationDescriptor.VisibleNetwork visibleNetwork = VISIBLE_CELL1.toProto(connected); + PartnerLocationDescriptor.VisibleNetwork.Cell cell = visibleNetwork.cell; + + assertEquals(VISIBLE_CELL1.cellId(), cell.cellId); + assertEquals(VISIBLE_CELL1.locationAreaCode(), cell.locationAreaCode); + assertEquals(VISIBLE_CELL1.mobileCountryCode(), cell.mobileCountryCode); + assertEquals(VISIBLE_CELL1.mobileNetworkCode(), cell.mobileNetworkCode); + assertEquals(VISIBLE_CELL1.primaryScramblingCode(), cell.primaryScramblingCode); + assertEquals(VISIBLE_CELL1.physicalCellId(), cell.physicalCellId); + assertEquals(VISIBLE_CELL1.trackingAreaCode(), cell.trackingAreaCode); + assertEquals(VISIBLE_CELL1.timestampMs(), visibleNetwork.timestampMs); + assertEquals(connected, visibleNetwork.connected); + assertEquals(PartnerLocationDescriptor.VisibleNetwork.Cell.GSM, cell.type.intValue()); + + assertEquals(VISIBLE_CELL1_PROTO_ENCODED, encodeVisibleNetwork(visibleNetwork)); + } + + @Test + public void testVisibleCellToProtoEmptyCell() { + boolean connected = true; + PartnerLocationDescriptor.VisibleNetwork visibleNetwork = EMPTY_CELL.toProto(connected); + PartnerLocationDescriptor.VisibleNetwork.Cell cell = visibleNetwork.cell; + + assertEquals(VisibleCell.UNKNOWN_RADIO_TYPE, cell.type.intValue()); + assertNull(cell.cellId); + assertNull(cell.locationAreaCode); + assertNull(cell.mobileCountryCode); + assertNull(cell.mobileNetworkCode); + assertNull(cell.primaryScramblingCode); + assertNull(cell.physicalCellId); + assertNull(cell.trackingAreaCode); + assertNull(visibleNetwork.timestampMs); + assertEquals(connected, visibleNetwork.connected); + + assertEquals(EMPTY_CELL_PROTO_ENCODED, encodeVisibleNetwork(visibleNetwork)); + } + + @Test public void testVisibleNetworksCreate() { Set<VisibleCell> expectedVisibleCells = new HashSet<VisibleCell>(Arrays.asList(VISIBLE_CELL1, VISIBLE_CELL2)); @@ -207,4 +300,17 @@ assertTrue(visibleNetworks.isEmpty()); assertFalse(VISIBLE_NETWORKS1.isEmpty()); } -} \ No newline at end of file + + private static String encodeVisibleNetwork( + PartnerLocationDescriptor.VisibleNetwork visibleNetwork) { + PartnerLocationDescriptor.LocationDescriptor locationDescriptor = + new PartnerLocationDescriptor.LocationDescriptor(); + locationDescriptor.role = PartnerLocationDescriptor.CURRENT_LOCATION; + locationDescriptor.producer = PartnerLocationDescriptor.DEVICE_LOCATION; + locationDescriptor.visibleNetwork = new PartnerLocationDescriptor.VisibleNetwork[1]; + locationDescriptor.visibleNetwork[0] = visibleNetwork; + + return Base64.encodeToString( + MessageNano.toByteArray(locationDescriptor), Base64.NO_WRAP | Base64.URL_SAFE); + } +}
diff --git a/chrome/browser/android/resource_id.h b/chrome/browser/android/resource_id.h index e355c095..7b0a881b 100644 --- a/chrome/browser/android/resource_id.h +++ b/chrome/browser/android/resource_id.h
@@ -66,10 +66,10 @@ // We use Android's |VectorDrawableCompat| for the following images that are // displayed using |DropdownAdapter|. LINK_RESOURCE_ID(IDR_AUTOFILL_CC_AMEX, R.drawable.amex_card) -LINK_RESOURCE_ID(IDR_AUTOFILL_CC_DINERS, R.drawable.ic_credit_card_black) +LINK_RESOURCE_ID(IDR_AUTOFILL_CC_DINERS, R.drawable.diners_card) LINK_RESOURCE_ID(IDR_AUTOFILL_CC_DISCOVER, R.drawable.discover_card) LINK_RESOURCE_ID(IDR_AUTOFILL_CC_GENERIC, R.drawable.ic_credit_card_black) -LINK_RESOURCE_ID(IDR_AUTOFILL_CC_JCB, R.drawable.ic_credit_card_black) +LINK_RESOURCE_ID(IDR_AUTOFILL_CC_JCB, R.drawable.jcb_card) LINK_RESOURCE_ID(IDR_AUTOFILL_CC_MASTERCARD, R.drawable.mc_card) LINK_RESOURCE_ID(IDR_AUTOFILL_CC_MIR, R.drawable.mir_card) LINK_RESOURCE_ID(IDR_AUTOFILL_CC_UNIONPAY, R.drawable.unionpay_card) @@ -86,14 +86,3 @@ // We use PNG files for the following images. LINK_RESOURCE_ID(IDR_CREDIT_CARD_CVC_HINT, R.drawable.cvc_icon) LINK_RESOURCE_ID(IDR_CREDIT_CARD_CVC_HINT_AMEX, R.drawable.cvc_icon_amex) - -// PaymentRequest images. -LINK_RESOURCE_ID(IDR_AUTOFILL_PR_AMEX, R.drawable.pr_amex) -LINK_RESOURCE_ID(IDR_AUTOFILL_PR_DINERS, R.drawable.pr_dinersclub) -LINK_RESOURCE_ID(IDR_AUTOFILL_PR_DISCOVER, R.drawable.pr_discover) -LINK_RESOURCE_ID(IDR_AUTOFILL_PR_GENERIC, R.drawable.pr_generic) -LINK_RESOURCE_ID(IDR_AUTOFILL_PR_JCB, R.drawable.pr_jcb) -LINK_RESOURCE_ID(IDR_AUTOFILL_PR_MASTERCARD, R.drawable.pr_mc) -LINK_RESOURCE_ID(IDR_AUTOFILL_PR_MIR, R.drawable.pr_mir) -LINK_RESOURCE_ID(IDR_AUTOFILL_PR_UNIONPAY, R.drawable.pr_unionpay) -LINK_RESOURCE_ID(IDR_AUTOFILL_PR_VISA, R.drawable.pr_visa)
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_data.cc b/chrome/browser/chromeos/app_mode/kiosk_app_data.cc index af66f76..75fd783 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_data.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_app_data.cc
@@ -12,7 +12,6 @@ #include "base/macros.h" #include "base/memory/ref_counted_memory.h" #include "base/task_scheduler/post_task.h" -#include "base/threading/sequenced_worker_pool.h" #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_data_delegate.h" @@ -78,18 +77,14 @@ const base::FilePath& crx_file) : client_(client), crx_file_(crx_file), - success_(false) { - } + success_(false), + task_runner_(base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) {} void Start() { - base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool(); - base::SequencedWorkerPool::SequenceToken token = - pool->GetNamedSequenceToken("KioskAppData.CrxLoaderWorker"); - task_runner_ = pool->GetSequencedTaskRunnerWithShutdownBehavior( - token, - base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); task_runner_->PostTask(FROM_HERE, - base::Bind(&CrxLoader::StartOnBlockingPool, this)); + base::BindOnce(&CrxLoader::StartInThreadPool, this)); } bool success() const { return success_; } @@ -122,21 +117,21 @@ icon_ = install_icon; required_platform_version_ = info->required_platform_version; } - NotifyFinishedOnBlockingPool(); + NotifyFinishedInThreadPool(); } void OnUnpackFailure(const extensions::CrxInstallError& error) override { DCHECK(task_runner_->RunsTasksInCurrentSequence()); success_ = false; - NotifyFinishedOnBlockingPool(); + NotifyFinishedInThreadPool(); } - void StartOnBlockingPool() { + void StartInThreadPool() { DCHECK(task_runner_->RunsTasksInCurrentSequence()); if (!temp_dir_.CreateUniqueTempDir()) { success_ = false; - NotifyFinishedOnBlockingPool(); + NotifyFinishedInThreadPool(); return; } @@ -147,7 +142,7 @@ unpacker->StartWithCrx(extensions::CRXFileInfo(crx_file_)); } - void NotifyFinishedOnBlockingPool() { + void NotifyFinishedInThreadPool() { DCHECK(task_runner_->RunsTasksInCurrentSequence()); if (!temp_dir_.Delete()) { @@ -171,7 +166,7 @@ base::FilePath crx_file_; bool success_; - scoped_refptr<base::SequencedTaskRunner> task_runner_; + const scoped_refptr<base::SequencedTaskRunner> task_runner_; base::ScopedTempDir temp_dir_; // Extracted meta data.
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index e78cf457..435157d 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -18,6 +18,7 @@ #include "base/files/file_util.h" #include "base/lazy_instance.h" #include "base/linux_util.h" +#include "base/logging.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" @@ -112,6 +113,7 @@ #include "chromeos/cryptohome/cryptohome_parameters.h" #include "chromeos/cryptohome/homedir_methods.h" #include "chromeos/cryptohome/system_salt_getter.h" +#include "chromeos/dbus/cryptohome_client.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/power_policy_controller.h" #include "chromeos/dbus/services/console_service_provider.h" @@ -409,6 +411,42 @@ // Entry point, called on UI thread. void Initialize() { + // Only start loading the system token once cryptohome is available and only + // if the TPM is ready (available && owned && not being owned). + DBusThreadManager::Get() + ->GetCryptohomeClient() + ->WaitForServiceToBeAvailable( + base::Bind(&SystemTokenCertDBInitializer::OnCryptohomeAvailable, + weak_ptr_factory_.GetWeakPtr())); + } + + private: + // Called once the cryptohome service is available. + void OnCryptohomeAvailable(bool available) { + if (!available) { + LOG(ERROR) << "SystemTokenCertDBInitializer: Failed to wait for " + "cryptohome to become available."; + return; + } + + VLOG(1) << "SystemTokenCertDBInitializer: Cryptohome available."; + DBusThreadManager::Get()->GetCryptohomeClient()->TpmIsReady( + base::Bind(&SystemTokenCertDBInitializer::OnGotTpmIsReady, + weak_ptr_factory_.GetWeakPtr())); + } + + // This is a callback for the cryptohome TpmIsReady query. Note that this is + // not a listener which would be called once TPM becomes ready if it was not + // ready on startup (e.g. after device enrollment), see crbug.com/725500. + void OnGotTpmIsReady(DBusMethodCallStatus call_status, bool tpm_is_ready) { + if (!tpm_is_ready) { + VLOG(1) << "SystemTokenCertDBInitializer: TPM is not ready - not loading " + "system token."; + return; + } + VLOG(1) + << "SystemTokenCertDBInitializer: TPM is ready, loading system token."; + TPMTokenLoader::Get()->EnsureStarted(); base::Callback<void(crypto::ScopedPK11Slot)> callback = base::BindRepeating(&SystemTokenCertDBInitializer::InitializeDatabase, weak_ptr_factory_.GetWeakPtr()); @@ -417,7 +455,6 @@ base::BindOnce(&GetSystemSlotOnIOThread, callback)); } - private: // Initializes the global system token NSSCertDatabase with |system_slot|. // Also starts CertLoader with the system token database. void InitializeDatabase(crypto::ScopedPK11Slot system_slot) { @@ -434,6 +471,8 @@ database->SetSystemSlot(std::move(system_slot_copy)); system_token_cert_database_ = std::move(database); + VLOG(1) << "SystemTokenCertDBInitializer: Passing system token NSS " + "database to CertLoader."; CertLoader::Get()->SetSystemNSSDB(system_token_cert_database_.get()); } @@ -541,7 +580,6 @@ content::BrowserThread::IO)); // Initialize NSS database for system token. - TPMTokenLoader::Get()->EnsureStarted(); system_token_certdb_initializer_ = base::MakeUnique<internal::SystemTokenCertDBInitializer>(); system_token_certdb_initializer_->Initialize();
diff --git a/chrome/browser/chromeos/drive/download_handler.cc b/chrome/browser/chromeos/drive/download_handler.cc index 468f503..4be75ca 100644 --- a/chrome/browser/chromeos/drive/download_handler.cc +++ b/chrome/browser/chromeos/drive/download_handler.cc
@@ -6,6 +6,8 @@ #include <stddef.h> +#include <utility> + #include "base/bind.h" #include "base/files/file_util.h" #include "base/macros.h" @@ -104,10 +106,10 @@ // Used to implement CheckForFileExistence(). void ContinueCheckingForFileExistence( - const content::CheckForFileExistenceCallback& callback, + content::CheckForFileExistenceCallback callback, FileError error, std::unique_ptr<ResourceEntry> entry) { - callback.Run(error == FILE_ERROR_OK); + std::move(callback).Run(error == FILE_ERROR_OK); } // Returns true if |download| is a Drive download created from data persisted @@ -247,11 +249,11 @@ void DownloadHandler::CheckForFileExistence( const DownloadItem* download, - const content::CheckForFileExistenceCallback& callback) { + content::CheckForFileExistenceCallback callback) { file_system_->GetResourceEntry( util::ExtractDrivePath(GetTargetPath(download)), base::Bind(&ContinueCheckingForFileExistence, - callback)); + base::Passed(std::move(callback)))); } void DownloadHandler::SetFreeDiskSpaceDelayForTesting(
diff --git a/chrome/browser/chromeos/drive/download_handler.h b/chrome/browser/chromeos/drive/download_handler.h index d42b845..1cff079 100644 --- a/chrome/browser/chromeos/drive/download_handler.h +++ b/chrome/browser/chromeos/drive/download_handler.h
@@ -71,9 +71,8 @@ bool IsDriveDownload(const content::DownloadItem* download); // Checks a file corresponding to the download item exists in Drive. - void CheckForFileExistence( - const content::DownloadItem* download, - const content::CheckForFileExistenceCallback& callback); + void CheckForFileExistence(const content::DownloadItem* download, + content::CheckForFileExistenceCallback callback); // Calculates request space for |downloads|. int64_t CalculateRequestSpace(
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index deae260..16e2bff 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -252,8 +252,8 @@ } #endif -// Callback to GetNSSCertDatabaseForProfile. It starts CertLoader using the -// provided NSS database. It must be called for primary user only. +// Callback to GetNSSCertDatabaseForProfile. It passes the user-specific NSS +// database to CertLoader. It must be called for primary user only. void OnGetNSSCertDatabaseForUser(net::NSSCertDatabase* database) { if (!CertLoader::IsInitialized()) return;
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc index 37c55d6..3ecbff8 100644 --- a/chrome/browser/download/chrome_download_manager_delegate.cc +++ b/chrome/browser/download/chrome_download_manager_delegate.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/download/chrome_download_manager_delegate.h" #include <string> +#include <utility> #include "base/bind.h" #include "base/bind_helpers.h" @@ -17,7 +18,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/task_runner.h" #include "base/task_scheduler/post_task.h" -#include "base/threading/sequenced_worker_pool.h" #include "base/time/time.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" @@ -212,8 +212,11 @@ : profile_(profile), next_download_id_(content::DownloadItem::kInvalidId), download_prefs_(new DownloadPrefs(profile)), - weak_ptr_factory_(this) { -} + check_for_file_existence_task_runner_( + base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND, + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})), + weak_ptr_factory_(this) {} ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() { // If a DownloadManager was set for this, Shutdown() must be called. @@ -533,29 +536,28 @@ platform_util::ShowItemInFolder(profile_, platform_path); } +void ContinueCheckingForFileExistence( + content::CheckForFileExistenceCallback callback) { + std::move(callback).Run(false); +} + void ChromeDownloadManagerDelegate::CheckForFileExistence( DownloadItem* download, - const content::CheckForFileExistenceCallback& callback) { + content::CheckForFileExistenceCallback callback) { #if defined(OS_CHROMEOS) drive::DownloadHandler* drive_download_handler = drive::DownloadHandler::GetForProfile(profile_); if (drive_download_handler && drive_download_handler->IsDriveDownload(download)) { - drive_download_handler->CheckForFileExistence(download, callback); + drive_download_handler->CheckForFileExistence(download, + std::move(callback)); return; } #endif - static const char kSequenceToken[] = "ChromeDMD-FileExistenceChecker"; - base::SequencedWorkerPool* worker_pool = BrowserThread::GetBlockingPool(); - scoped_refptr<base::SequencedTaskRunner> task_runner = - worker_pool->GetSequencedTaskRunnerWithShutdownBehavior( - worker_pool->GetNamedSequenceToken(kSequenceToken), - base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); base::PostTaskAndReplyWithResult( - task_runner.get(), - FROM_HERE, - base::Bind(&base::PathExists, download->GetTargetFilePath()), - callback); + check_for_file_existence_task_runner_.get(), FROM_HERE, + base::BindOnce(&base::PathExists, download->GetTargetFilePath()), + std::move(callback)); } std::string
diff --git a/chrome/browser/download/chrome_download_manager_delegate.h b/chrome/browser/download/chrome_download_manager_delegate.h index a03a227c..5d9fd8a8 100644 --- a/chrome/browser/download/chrome_download_manager_delegate.h +++ b/chrome/browser/download/chrome_download_manager_delegate.h
@@ -16,6 +16,7 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/sequenced_task_runner.h" #include "chrome/browser/download/download_path_reservation_tracker.h" #include "chrome/browser/download/download_target_determiner_delegate.h" #include "chrome/browser/download/download_target_info.h" @@ -85,7 +86,7 @@ void ShowDownloadInShell(content::DownloadItem* download) override; void CheckForFileExistence( content::DownloadItem* download, - const content::CheckForFileExistenceCallback& callback) override; + content::CheckForFileExistenceCallback callback) override; std::string ApplicationClientIdForFileScanning() const override; // Opens a download using the platform handler. DownloadItem::OpenDownload, @@ -168,6 +169,12 @@ IdCallbackVector id_callbacks_; std::unique_ptr<DownloadPrefs> download_prefs_; + // SequencedTaskRunner to check for file existence. A sequence is used so that + // a large download history doesn't cause a large number of concurrent disk + // operations. + const scoped_refptr<base::SequencedTaskRunner> + check_for_file_existence_task_runner_; + #if BUILDFLAG(ENABLE_EXTENSIONS) // Maps from pending extension installations to DownloadItem IDs. typedef base::hash_map<extensions::CrxInstaller*,
diff --git a/chrome/browser/extensions/extension_apitest.cc b/chrome/browser/extensions/extension_apitest.cc index 672f7c8..e67ba97 100644 --- a/chrome/browser/extensions/extension_apitest.cc +++ b/chrome/browser/extensions/extension_apitest.cc
@@ -156,7 +156,6 @@ test_config_.reset(new base::DictionaryValue()); test_config_->SetString(kTestDataDirectory, net::FilePathToFileURL(test_data_dir_).spec()); - test_config_->SetInteger(kTestWebSocketPort, 0); extensions::TestGetConfigFunction::set_test_config_state( test_config_.get()); }
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc index 6c04bc1..6686bd3c 100644 --- a/chrome/browser/net/chrome_network_delegate.cc +++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -546,6 +546,42 @@ return true; } +bool ChromeNetworkDelegate::OnCanQueueReportingReport( + const url::Origin& origin) const { + if (!cookie_settings_) + return true; + + return cookie_settings_->IsCookieAccessAllowed(origin.GetURL(), + origin.GetURL()); +} + +bool ChromeNetworkDelegate::OnCanSendReportingReport( + const url::Origin& origin) const { + if (!cookie_settings_) + return true; + + return cookie_settings_->IsCookieAccessAllowed(origin.GetURL(), + origin.GetURL()); +} + +bool ChromeNetworkDelegate::OnCanSetReportingClient( + const url::Origin& origin, + const GURL& endpoint) const { + if (!cookie_settings_) + return true; + + return cookie_settings_->IsCookieAccessAllowed(endpoint, origin.GetURL()); +} + +bool ChromeNetworkDelegate::OnCanUseReportingClient( + const url::Origin& origin, + const GURL& endpoint) const { + if (!cookie_settings_) + return true; + + return cookie_settings_->IsCookieAccessAllowed(endpoint, origin.GetURL()); +} + void ChromeNetworkDelegate::ReportDataUsageStats(net::URLRequest* request, int64_t tx_bytes, int64_t rx_bytes) {
diff --git a/chrome/browser/net/chrome_network_delegate.h b/chrome/browser/net/chrome_network_delegate.h index fc0d59a..d4e94a9e 100644 --- a/chrome/browser/net/chrome_network_delegate.h +++ b/chrome/browser/net/chrome_network_delegate.h
@@ -182,6 +182,12 @@ const net::URLRequest& request, const GURL& target_url, const GURL& referrer_url) const override; + bool OnCanQueueReportingReport(const url::Origin& origin) const override; + bool OnCanSendReportingReport(const url::Origin& origin) const override; + bool OnCanSetReportingClient(const url::Origin& origin, + const GURL& endpoint) const override; + bool OnCanUseReportingClient(const url::Origin& origin, + const GURL& endpoint) const override; // Convenience function for reporting network usage to the // |data_use_aggregator_|.
diff --git a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc index 6d029c4..30c0dd4 100644 --- a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc +++ b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc
@@ -165,10 +165,9 @@ #endif // OS_ANDROID void RegisterBookmarkProvider(BookmarkModel* bookmark_model, - ContentSuggestionsService* service, - PrefService* pref_service) { - auto provider = base::MakeUnique<BookmarkSuggestionsProvider>( - service, bookmark_model, pref_service); + ContentSuggestionsService* service) { + auto provider = + base::MakeUnique<BookmarkSuggestionsProvider>(service, bookmark_model); service->RegisterProvider(std::move(provider)); } @@ -372,7 +371,7 @@ BookmarkModelFactory::GetForBrowserContext(profile); if (base::FeatureList::IsEnabled(ntp_snippets::kBookmarkSuggestionsFeature) && bookmark_model && !IsChromeHomeEnabled()) { - RegisterBookmarkProvider(bookmark_model, service, pref_service); + RegisterBookmarkProvider(bookmark_model, service); } #if defined(OS_ANDROID)
diff --git a/chrome/browser/plugins/plugin_infobar_delegates.cc b/chrome/browser/plugins/plugin_infobar_delegates.cc index 851098c4..6c4d83c 100644 --- a/chrome/browser/plugins/plugin_infobar_delegates.cc +++ b/chrome/browser/plugins/plugin_infobar_delegates.cc
@@ -53,7 +53,7 @@ infobar_service->AddInfoBar(infobar_service->CreateConfirmInfoBar( std::unique_ptr<ConfirmInfoBarDelegate>(new OutdatedPluginInfoBarDelegate( installer, std::move(plugin_metadata), - l10n_util::GetStringUTF16(IDS_PLUGIN_OUTDATED_PROMPT))))); + l10n_util::GetStringFUTF16(IDS_PLUGIN_OUTDATED_PROMPT, name))))); } OutdatedPluginInfoBarDelegate::OutdatedPluginInfoBarDelegate(
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index e1090ec7..09ecf6da 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -79,7 +79,6 @@ #include "components/gcm_driver/gcm_channel_status_syncer.h" #include "components/metrics/metrics_service.h" #include "components/network_time/network_time_tracker.h" -#include "components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h" #include "components/ntp_snippets/content_suggestions_service.h" #include "components/ntp_snippets/remote/remote_suggestions_provider_impl.h" #include "components/ntp_snippets/remote/remote_suggestions_scheduler_impl.h" @@ -491,7 +490,6 @@ MediaStreamDevicesController::RegisterProfilePrefs(registry); NetHttpSessionParamsObserver::RegisterProfilePrefs(registry); NotifierStateTracker::RegisterProfilePrefs(registry); - ntp_snippets::BookmarkSuggestionsProvider::RegisterProfilePrefs(registry); ntp_snippets::ContentSuggestionsService::RegisterProfilePrefs(registry); ntp_snippets::ForeignSessionsSuggestionsProvider::RegisterProfilePrefs( registry);
diff --git a/chrome/browser/safe_browsing/OWNERS b/chrome/browser/safe_browsing/OWNERS index 104ba73..442ab174 100644 --- a/chrome/browser/safe_browsing/OWNERS +++ b/chrome/browser/safe_browsing/OWNERS
@@ -1,5 +1,6 @@ mattm@chromium.org nparker@chromium.org - -# For download-protection- and reporting-related changes: jialiul@chromium.org + +# For interstitial-related changes: +per-file safe_browsing_blocking_page*=felt@chromium.org
diff --git a/chrome/browser/ui/views/payments/contact_info_editor_view_controller.cc b/chrome/browser/ui/views/payments/contact_info_editor_view_controller.cc index 8a08f9a4c6..ac449ba 100644 --- a/chrome/browser/ui/views/payments/contact_info_editor_view_controller.cc +++ b/chrome/browser/ui/views/payments/contact_info_editor_view_controller.cc
@@ -16,6 +16,7 @@ #include "components/autofill/core/common/autofill_constants.h" #include "components/payments/content/payment_request_spec.h" #include "components/payments/content/payment_request_state.h" +#include "components/payments/core/payment_request_data_util.h" #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/models/simple_combobox_model.h" @@ -69,6 +70,11 @@ if (!profile_to_edit_) return base::string16(); + if (type == autofill::PHONE_HOME_WHOLE_NUMBER) { + return data_util::GetFormattedPhoneNumberForDisplay( + *profile_to_edit_, state()->GetApplicationLocale()); + } + return profile_to_edit_->GetInfo(autofill::AutofillType(type), state()->GetApplicationLocale()); }
diff --git a/chrome/browser/ui/views/payments/contact_info_editor_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/contact_info_editor_view_controller_browsertest.cc index 3738f155..ca1ddb2 100644 --- a/chrome/browser/ui/views/payments/contact_info_editor_view_controller_browsertest.cc +++ b/chrome/browser/ui/views/payments/contact_info_editor_view_controller_browsertest.cc
@@ -237,8 +237,9 @@ OpenContactInfoScreen(); PaymentRequest* request = GetPaymentRequests(GetActiveWebContents()).front(); - EXPECT_EQ(request->state()->contact_profiles().front(), - request->state()->selected_contact_profile()); + + // No contact profiles are selected because both are incomplete. + EXPECT_EQ(nullptr, request->state()->selected_contact_profile()); views::View* list_view = dialog_view()->GetViewByID( static_cast<int>(DialogViewID::CONTACT_INFO_SHEET_LIST_VIEW)); @@ -269,6 +270,7 @@ profile->GetInfo(autofill::AutofillType(autofill::EMAIL_ADDRESS), GetLocale())); + // Expect the newly-completed profile to be selected. EXPECT_EQ(2U, request->state()->contact_profiles().size()); EXPECT_EQ(request->state()->contact_profiles().back(), profile); }
diff --git a/chrome/browser/ui/views/payments/order_summary_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/order_summary_view_controller_browsertest.cc index 77d3fded..7eec7b6 100644 --- a/chrome/browser/ui/views/payments/order_summary_view_controller_browsertest.cc +++ b/chrome/browser/ui/views/payments/order_summary_view_controller_browsertest.cc
@@ -71,7 +71,7 @@ EXPECT_EQ( base::ASCIIToUTF16("ACME, 123 Main Street, Unit 1, Greensdale, MI 48838"), shipping_address_labels[1]); - EXPECT_EQ(base::ASCIIToUTF16("13105557889"), shipping_address_labels[2]); + EXPECT_EQ(base::ASCIIToUTF16("+1 310-555-7889"), shipping_address_labels[2]); std::vector<base::string16> shipping_option_labels = GetShippingOptionLabelValues( DialogViewID::PAYMENT_SHEET_SHIPPING_OPTION_SECTION); @@ -113,7 +113,7 @@ EXPECT_EQ(base::ASCIIToUTF16( "Underworld, 666 Erebus St., Apt 8, Elysium, CA 91111"), shipping_address_labels[1]); - EXPECT_EQ(base::ASCIIToUTF16("16502111111"), shipping_address_labels[2]); + EXPECT_EQ(base::ASCIIToUTF16("+1 650-211-1111"), shipping_address_labels[2]); shipping_option_labels = GetShippingOptionLabelValues( DialogViewID::PAYMENT_SHEET_SHIPPING_OPTION_SECTION); EXPECT_EQ(base::ASCIIToUTF16("Free shipping in California"),
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.cc b/chrome/browser/ui/views/payments/payment_request_views_util.cc index 9d87756d..cc45006 100644 --- a/chrome/browser/ui/views/payments/payment_request_views_util.cc +++ b/chrome/browser/ui/views/payments/payment_request_views_util.cc
@@ -20,6 +20,7 @@ #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/field_types.h" #include "components/payments/core/payment_options_provider.h" +#include "components/payments/core/payment_request_data_util.h" #include "components/payments/core/payments_profile_comparator.h" #include "ui/base/default_style.h" #include "ui/base/l10n/l10n_util.h" @@ -132,8 +133,8 @@ base::string16 address = GetAddressFromProfile(profile, locale); - base::string16 phone = profile.GetInfo( - autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER), locale); + base::string16 phone = + data_util::GetFormattedPhoneNumberForDisplay(profile, locale); return GetBaseProfileLabel(type, name, address, phone, disabled_state); } @@ -200,16 +201,16 @@ views::ColumnSet* columns = layout->AddColumnSet(0); // A column for the optional back arrow. - columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, - 0, views::GridLayout::USE_PREF, 0, 0); + columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0, + views::GridLayout::USE_PREF, 0, 0); constexpr int kPaddingBetweenArrowAndTitle = 16; if (show_back_arrow) columns->AddPaddingColumn(0, kPaddingBetweenArrowAndTitle); // A column for the title. - columns->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, - 1, views::GridLayout::USE_PREF, 0, 0); + columns->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, 1, + views::GridLayout::USE_PREF, 0, 0); layout->StartRow(0, 0); if (!show_back_arrow) { @@ -220,8 +221,8 @@ constexpr int kBackArrowSize = 16; back_arrow->SetSize(gfx::Size(kBackArrowSize, kBackArrowSize)); back_arrow->SetFocusBehavior(views::View::FocusBehavior::ALWAYS); - back_arrow->set_tag(static_cast<int>( - PaymentRequestCommonTags::BACK_BUTTON_TAG)); + back_arrow->set_tag( + static_cast<int>(PaymentRequestCommonTags::BACK_BUTTON_TAG)); back_arrow->set_id(static_cast<int>(DialogViewID::BACK_BUTTON)); layout->AddView(back_arrow); } @@ -320,9 +321,7 @@ base::string16 phone = options.request_payer_phone() - ? profile.GetInfo( - autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER), - locale) + ? data_util::GetFormattedPhoneNumberForDisplay(profile, locale) : base::string16(); base::string16 email =
diff --git a/chrome/browser/ui/views/payments/profile_list_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/profile_list_view_controller_browsertest.cc new file mode 100644 index 0000000..319443f --- /dev/null +++ b/chrome/browser/ui/views/payments/profile_list_view_controller_browsertest.cc
@@ -0,0 +1,78 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/guid.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/ui/views/payments/payment_request_browsertest_base.h" +#include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" +#include "components/autofill/core/browser/autofill_profile.h" +#include "components/autofill/core/browser/autofill_test_utils.h" +#include "components/autofill/core/browser/field_types.h" +#include "components/autofill/core/browser/personal_data_manager.h" +#include "ui/views/controls/label.h" + +namespace payments { + +autofill::AutofillProfile CreateProfileWithPartialAddress() { + autofill::AutofillProfile profile = autofill::test::GetFullProfile2(); + profile.SetRawInfo(autofill::ADDRESS_HOME_LINE1, base::ASCIIToUTF16("")); + profile.SetRawInfo(autofill::ADDRESS_HOME_LINE2, base::ASCIIToUTF16("")); + profile.SetRawInfo(autofill::ADDRESS_HOME_CITY, base::ASCIIToUTF16("")); + profile.SetRawInfo(autofill::ADDRESS_HOME_STATE, base::ASCIIToUTF16("")); + return profile; +} + +class PaymentRequestProfileListTest : public PaymentRequestBrowserTestBase { + protected: + PaymentRequestProfileListTest() + : PaymentRequestBrowserTestBase( + "/payment_request_free_shipping_test.html") {} +}; + +IN_PROC_BROWSER_TEST_F(PaymentRequestProfileListTest, PrioritizeCompleteness) { + autofill::AutofillProfile complete = autofill::test::GetFullProfile(); + autofill::AutofillProfile partial = CreateProfileWithPartialAddress(); + partial.set_use_count(1000); + + AddAutofillProfile(complete); + AddAutofillProfile(partial); + + // In the Personal Data Manager, the partial address is more frecent. + autofill::PersonalDataManager* personal_data_manager = GetDataManager(); + std::vector<autofill::AutofillProfile*> profiles = + personal_data_manager->GetProfiles(); + ASSERT_EQ(2UL, profiles.size()); + EXPECT_EQ(partial, *profiles[0]); + EXPECT_EQ(complete, *profiles[1]); + + InvokePaymentRequestUI(); + + PaymentRequest* request = GetPaymentRequests(GetActiveWebContents()).front(); + + // The complete profile should be selected. + ASSERT_TRUE(request->state()->selected_shipping_profile()); + EXPECT_EQ(complete, *request->state()->selected_shipping_profile()); + + // It should appear first in the shipping profiles. + ASSERT_EQ(2UL, request->state()->shipping_profiles().size()); + EXPECT_EQ(complete, *request->state()->shipping_profiles()[0]); + EXPECT_EQ(partial, *request->state()->shipping_profiles()[1]); + + // And both should appear in the UI. + OpenShippingAddressSectionScreen(); + views::View* sheet = dialog_view()->GetViewByID( + static_cast<int>(DialogViewID::SHIPPING_ADDRESS_SHEET_LIST_VIEW)); + ASSERT_EQ(2, sheet->child_count()); + views::View* first_label = sheet->child_at(0)->GetViewByID( + static_cast<int>(DialogViewID::PROFILE_LABEL_LINE_1)); + views::View* second_label = sheet->child_at(1)->GetViewByID( + static_cast<int>(DialogViewID::PROFILE_LABEL_LINE_1)); + + EXPECT_EQ(base::ASCIIToUTF16("John H. Doe"), + static_cast<views::Label*>(first_label)->text()); + EXPECT_EQ(base::ASCIIToUTF16("Jane A. Smith"), + static_cast<views::Label*>(second_label)->text()); +} + +} // namespace payments
diff --git a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc index 0d783e3..33d8ee5 100644 --- a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc +++ b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller.cc
@@ -25,6 +25,7 @@ #include "components/autofill/core/browser/validation.h" #include "components/autofill/core/common/autofill_constants.h" #include "components/payments/content/payment_request_state.h" +#include "components/payments/core/payment_request_data_util.h" #include "components/payments/core/payments_profile_comparator.h" #include "components/strings/grit/components_strings.h" #include "third_party/libaddressinput/messages.h" @@ -78,6 +79,11 @@ if (!profile_to_edit_) return base::string16(); + if (type == autofill::PHONE_HOME_WHOLE_NUMBER) { + return data_util::GetFormattedPhoneNumberForDisplay( + *profile_to_edit_, state()->GetApplicationLocale()); + } + return profile_to_edit_->GetInfo(autofill::AutofillType(type), state()->GetApplicationLocale()); }
diff --git a/chrome/browser/ui/views/payments/shipping_option_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/shipping_option_view_controller_browsertest.cc index a4108d9..e1ed5ebe 100644 --- a/chrome/browser/ui/views/payments/shipping_option_view_controller_browsertest.cc +++ b/chrome/browser/ui/views/payments/shipping_option_view_controller_browsertest.cc
@@ -75,7 +75,7 @@ EXPECT_EQ( base::ASCIIToUTF16("ACME, 123 Main Street, Unit 1, Greensdale, MI 48838"), shipping_address_labels[1]); - EXPECT_EQ(base::ASCIIToUTF16("13105557889"), shipping_address_labels[2]); + EXPECT_EQ(base::ASCIIToUTF16("+1 310-555-7889"), shipping_address_labels[2]); // The shipping option section exists, and the shipping option is shown. std::vector<base::string16> shipping_option_labels =
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 87478f0..53c5a05 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2058,6 +2058,7 @@ "../browser/ui/views/payments/payment_request_payment_response_browsertest.cc", "../browser/ui/views/payments/payment_request_use_stats_browsertest.cc", "../browser/ui/views/payments/payment_sheet_view_controller_browsertest.cc", + "../browser/ui/views/payments/profile_list_view_controller_browsertest.cc", "../browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc", "../browser/ui/views/payments/shipping_option_view_controller_browsertest.cc", "../browser/ui/views/select_file_dialog_extension_browsertest.cc",
diff --git a/chrome/test/base/chrome_test_launcher.cc b/chrome/test/base/chrome_test_launcher.cc index 3bd57a6a..8ba431f 100644 --- a/chrome/test/base/chrome_test_launcher.cc +++ b/chrome/test/base/chrome_test_launcher.cc
@@ -16,7 +16,6 @@ #include "base/memory/ptr_util.h" #include "base/process/process_metrics.h" #include "base/run_loop.h" -#include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/test/test_file_util.h" #include "build/build_config.h" @@ -30,6 +29,7 @@ #include "content/public/common/content_switches.h" #include "content/public/test/test_launcher.h" #include "content/public/test/test_utils.h" +#include "services/service_manager/runner/common/switches.h" #include "ui/base/test/ui_controls.h" #if defined(OS_MACOSX) @@ -53,7 +53,6 @@ #endif #if defined(OS_WIN) -#include <shellapi.h> #include "base/win/registry.h" #include "chrome/app/chrome_crash_reporter_client_win.h" #include "chrome/install_static/install_util.h" @@ -63,6 +62,12 @@ ChromeTestSuiteRunner::~ChromeTestSuiteRunner() {} int ChromeTestSuiteRunner::RunTestSuite(int argc, char** argv) { +#if defined(USE_AURA) + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(service_manager::switches::kServicePipeToken)) + content::GetContentMainParams()->env_mode = aura::Env::Mode::MUS; +#endif // defined(USE_AURA) + return ChromeTestSuite(argc, argv).Run(); } @@ -102,37 +107,26 @@ void ChromeTestLauncherDelegate::PreSharding() { #if defined(OS_WIN) - // Construct the distribution specific equivalent of - // "delete HKCU\\SOFTWARE\\Chromium\\PreferenceMACs /f". - base::string16 operation(L"delete HKCU\\"); - operation.append(install_static::GetRegistryPath()); - operation.append(L"\\PreferenceMACs /f"); - // TODO(gab): This is a nuclear option while the cleanup below doesn't work as - // the bots are in such bad shape per https://crbug.com/721245 that doing any - // registry operations from C++ results in fatal error 1450 (insufficient - // resources). Hopefully ShellExecute works... - ::ShellExecute(NULL, NULL, L"reg.exe", operation.c_str(), NULL, 0); + // Pre-test cleanup for registry state keyed off the profile dir (which can + // proliferate with the use of uniquely named scoped_dirs): + // https://crbug.com/721245. This needs to be here in order not to be racy + // with any tests that will access that state. + base::win::RegKey distrubution_key; + LONG result = distrubution_key.Open(HKEY_CURRENT_USER, + install_static::GetRegistryPath().c_str(), + KEY_SET_VALUE); -// // Pre-test cleanup for registry state keyed off the profile dir (which can -// // proliferate with the use of uniquely named scoped_dirs): -// // https://crbug.com/721245. This needs to be here in order not to be racy -// // with any tests that will access that state. -// base::win::RegKey distrubution_key; -// LONG result = distrubution_key.Open( -// HKEY_CURRENT_USER, install_static::GetRegistryPath().c_str(), -// KEY_SET_VALUE); + if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) { + LOG(ERROR) << "Failed to open distribution key for cleanup: " << result; + return; + } -// if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) { -// LOG(ERROR) << "Failed to open distribution key for cleanup: " << result; -// return; -// } + result = distrubution_key.DeleteKey(L"PreferenceMACs"); -// result = distrubution_key.DeleteKey(L"PreferenceMACs"); - -// if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) { -// LOG(ERROR) << "Failed to cleanup PreferenceMACs: " << result; -// return; -// } + if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) { + LOG(ERROR) << "Failed to cleanup PreferenceMACs: " << result; + return; + } #endif }
diff --git a/chrome/test/base/mash_browser_tests_main.cc b/chrome/test/base/mash_browser_tests_main.cc index 7ff38d4..e5e68a0 100644 --- a/chrome/test/base/mash_browser_tests_main.cc +++ b/chrome/test/base/mash_browser_tests_main.cc
@@ -153,9 +153,11 @@ std::unique_ptr<content::ServiceManagerConnection> CreateServiceManagerConnection(MashTestLauncherDelegate* delegate) { + delegate->GetMojoTestConnectorForSingleProcess()->Init(); std::unique_ptr<content::ServiceManagerConnection> connection( content::ServiceManagerConnection::Create( - delegate->GetMojoTestConnectorForSingleProcess()->Init(), + delegate->GetMojoTestConnectorForSingleProcess() + ->InitBackgroundServiceManager(), base::ThreadTaskRunnerHandle::Get())); connection->Start(); connection->GetConnector()->StartService(mash::session::mojom::kServiceName);
diff --git a/chrome/test/base/mojo_test_connector.cc b/chrome/test/base/mojo_test_connector.cc index 2293250..c42f42d9 100644 --- a/chrome/test/base/mojo_test_connector.cc +++ b/chrome/test/base/mojo_test_connector.cc
@@ -18,6 +18,7 @@ #include "content/public/common/content_switches.h" #include "content/public/common/service_names.mojom.h" #include "content/public/test/test_launcher.h" +#include "mash/session/public/interfaces/constants.mojom.h" #include "mojo/edk/embedder/embedder.h" #include "mojo/edk/embedder/outgoing_broker_client_invitation.h" #include "mojo/edk/embedder/platform_channel_pair.h" @@ -43,13 +44,12 @@ // service manager. class MojoTestState : public content::TestState { public: - explicit MojoTestState( - service_manager::BackgroundServiceManager* background_service_manager, - base::CommandLine* command_line, - base::TestLauncher::LaunchOptions* test_launch_options, - const std::string& mus_config_switch, - base::OnceClosure on_process_launched) - : background_service_manager_(background_service_manager), + MojoTestState(MojoTestConnector* connector, + base::CommandLine* command_line, + base::TestLauncher::LaunchOptions* test_launch_options, + const std::string& mus_config_switch, + base::OnceClosure on_process_launched) + : connector_(connector), platform_channel_(base::MakeUnique<mojo::edk::PlatformChannelPair>()), main_task_runner_(base::ThreadTaskRunnerHandle::Get()), on_process_launched_(std::move(on_process_launched)), @@ -99,7 +99,10 @@ // after ChildProcessLaunched as previous test runs will tear down existing // connections. void SetupService(base::ProcessId pid) { - background_service_manager_->RegisterService( + connector_->InitBackgroundServiceManager(); + service_manager::BackgroundServiceManager* background_service_manager = + connector_->background_service_manager(); + background_service_manager->RegisterService( service_manager::Identity(content::mojom::kPackagedServicesServiceName, service_manager::mojom::kRootUserID), std::move(service_), mojo::MakeRequest(&pid_receiver_)); @@ -112,7 +115,7 @@ } mojo::edk::OutgoingBrokerClientInvitation broker_client_invitation_; - service_manager::BackgroundServiceManager* const background_service_manager_; + MojoTestConnector* connector_; // The ServicePtr must be created before child process launch so that the pipe // can be set on the command line. It is held until SetupService is called at @@ -200,7 +203,7 @@ background_service_manager_(nullptr), catalog_contents_(std::move(catalog_contents)) {} -service_manager::mojom::ServiceRequest MojoTestConnector::Init() { +void MojoTestConnector::Init() { // In single-process test mode, browser code will initialize the EDK and IPC. // Otherwise we ensure it's initialized here. if (!base::CommandLine::ForCurrentProcess()->HasSwitch( @@ -213,7 +216,10 @@ ipc_thread_->task_runner(), mojo::edk::ScopedIPCSupport::ShutdownPolicy::FAST); } +} +service_manager::mojom::ServiceRequest +MojoTestConnector::InitBackgroundServiceManager() { service_manager::mojom::ServicePtr service; auto request = mojo::MakeRequest(&service); @@ -223,7 +229,7 @@ background_service_manager_ = base::MakeUnique<service_manager::BackgroundServiceManager>( service_process_launcher_delegate_.get(), - std::move(catalog_contents_)); + catalog_contents_->CreateDeepCopy()); background_service_manager_->RegisterService( service_manager::Identity(config_ == MojoTestConnector::Config::MASH ? kMashTestRunnerName @@ -240,7 +246,7 @@ base::TestLauncher::LaunchOptions* test_launch_options, base::OnceClosure on_process_launched) { return base::MakeUnique<MojoTestState>( - background_service_manager_.get(), command_line, test_launch_options, + this, command_line, test_launch_options, config_ == MojoTestConnector::Config::MASH ? switches::kMash : switches::kMus, std::move(on_process_launched));
diff --git a/chrome/test/base/mojo_test_connector.h b/chrome/test/base/mojo_test_connector.h index 441cc8df7..fbeb11c 100644 --- a/chrome/test/base/mojo_test_connector.h +++ b/chrome/test/base/mojo_test_connector.h
@@ -57,8 +57,15 @@ Config config); ~MojoTestConnector(); + service_manager::BackgroundServiceManager* background_service_manager() { + return background_service_manager_.get(); + } + + // Initializes the Mojo environment, and IPC thread. + void Init(); + // Initializes the background thread the ServiceManager runs on. - service_manager::mojom::ServiceRequest Init(); + service_manager::mojom::ServiceRequest InitBackgroundServiceManager(); std::unique_ptr<content::TestState> PrepareForTest( base::CommandLine* command_line,
diff --git a/chromeos/cert_loader.h b/chromeos/cert_loader.h index e575c08..a3704ce 100644 --- a/chromeos/cert_loader.h +++ b/chromeos/cert_loader.h
@@ -69,20 +69,20 @@ static std::string GetPkcs11IdAndSlotForCert(const net::X509Certificate& cert, int* slot_id); - // Starts the CertLoader with the passed system NSS cert database. - // The CertLoader will _not_ take ownership of the database - see comment on - // SetUserNSSDB. - // CertLoader supports working with only one database or with both (system and - // user) databases. + // Sets the NSS cert database which CertLoader should use to access system + // slot certificates. The CertLoader will _not_ take ownership of the database + // - see comment on SetUserNSSDB. CertLoader supports working with only one + // database or with both (system and user) databases. void SetSystemNSSDB(net::NSSCertDatabase* system_slot_database); - // Starts the CertLoader with the passed user NSS cert database. + // Sets the NSS cert database which CertLoader should use to access user slot + // certificates. CertLoader understands the edge case that this database could + // also give access to system slot certificates (e.g. for affiliated users). // The CertLoader will _not_ take the ownership of the database, but it // expects it to stay alive at least until the shutdown starts on the main - // thread. This assumes that SetUserNSSDB and other methods directly - // using |database_| are not called during shutdown. - // CertLoader supports working with only one database or with both (system and - // user) databases. + // thread. This assumes that SetUserNSSDB and other methods directly using + // |database_| are not called during shutdown. CertLoader supports working + // with only one database or with both (system and user) databases. void SetUserNSSDB(net::NSSCertDatabase* user_database); void AddObserver(CertLoader::Observer* observer);
diff --git a/components/autofill/core/browser/autofill_data_util.cc b/components/autofill/core/browser/autofill_data_util.cc index 215b758..6a97a28 100644 --- a/components/autofill/core/browser/autofill_data_util.cc +++ b/components/autofill/core/browser/autofill_data_util.cc
@@ -25,25 +25,6 @@ // Mappings from Chrome card types to Payment Request API basic card payment // spec types and icons. Note that "generic" is not in the spec. // https://w3c.github.io/webpayments-methods-card/#method-id -#if defined(OS_ANDROID) -// On Android, use the PR-specific resource IDs. -const PaymentRequestData kPaymentRequestData[]{ - {"americanExpressCC", "amex", IDR_AUTOFILL_PR_AMEX, IDS_AUTOFILL_CC_AMEX}, - {"dinersCC", "diners", IDR_AUTOFILL_PR_DINERS, IDS_AUTOFILL_CC_DINERS}, - {"discoverCC", "discover", IDR_AUTOFILL_PR_DISCOVER, - IDS_AUTOFILL_CC_DISCOVER}, - {"jcbCC", "jcb", IDR_AUTOFILL_PR_JCB, IDS_AUTOFILL_CC_JCB}, - {"masterCardCC", "mastercard", IDR_AUTOFILL_PR_MASTERCARD, - IDS_AUTOFILL_CC_MASTERCARD}, - {"mirCC", "mir", IDR_AUTOFILL_PR_MIR, IDS_AUTOFILL_CC_MIR}, - {"unionPayCC", "unionpay", IDR_AUTOFILL_PR_UNIONPAY, - IDS_AUTOFILL_CC_UNION_PAY}, - {"visaCC", "visa", IDR_AUTOFILL_PR_VISA, IDS_AUTOFILL_CC_VISA}, -}; -const PaymentRequestData kGenericPaymentRequestData = { - "genericCC", "generic", IDR_AUTOFILL_PR_GENERIC, IDS_AUTOFILL_CC_GENERIC}; -#else // !defined(OS_ANDROID) -// On other platforms, use the Autofill resource IDs. const PaymentRequestData kPaymentRequestData[]{ {"americanExpressCC", "amex", IDR_AUTOFILL_CC_AMEX, IDS_AUTOFILL_CC_AMEX}, {"dinersCC", "diners", IDR_AUTOFILL_CC_DINERS, IDS_AUTOFILL_CC_DINERS}, @@ -59,7 +40,6 @@ }; const PaymentRequestData kGenericPaymentRequestData = { "genericCC", "generic", IDR_AUTOFILL_CC_GENERIC, IDS_AUTOFILL_CC_GENERIC}; -#endif const char* const name_prefixes[] = { "1lt", "1st", "2lt", "2nd", "3rd", "admiral", "capt",
diff --git a/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc b/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc index 436e8bc..0930a321 100644 --- a/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc +++ b/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc
@@ -18,9 +18,6 @@ #include "components/ntp_snippets/category.h" #include "components/ntp_snippets/content_suggestion.h" #include "components/ntp_snippets/features.h" -#include "components/ntp_snippets/pref_names.h" -#include "components/prefs/pref_registry_simple.h" -#include "components/prefs/pref_service.h" #include "components/strings/grit/components_strings.h" #include "components/variations/variations_associated_data.h" #include "ui/base/l10n/l10n_util.h" @@ -41,10 +38,6 @@ const char* kConsiderDesktopVisitsParamName = "bookmarks_consider_desktop_visits"; -// TODO(treib,jkrcal): Remove this after M57. -const char kDeprecatedBookmarksFirstM54StartPref[] = - "ntp_suggestions.bookmarks.first_M54_start"; - // Any bookmark created or visited after this time will be considered recent. // Note that bookmarks can be shown that do not meet this threshold. base::Time GetThresholdTime() { @@ -71,8 +64,7 @@ BookmarkSuggestionsProvider::BookmarkSuggestionsProvider( ContentSuggestionsProvider::Observer* observer, - bookmarks::BookmarkModel* bookmark_model, - PrefService* pref_service) + bookmarks::BookmarkModel* bookmark_model) : ContentSuggestionsProvider(observer), category_status_(CategoryStatus::AVAILABLE_LOADING), provided_category_( @@ -82,7 +74,6 @@ end_of_list_last_visit_date_(GetThresholdTime()), consider_bookmark_visits_from_desktop_(AreDesktopVisitsConsidered()) { observer->OnCategoryStatusChanged(this, provided_category_, category_status_); - pref_service->ClearPref(kDeprecatedBookmarksFirstM54StartPref); bookmark_model_->AddObserver(this); FetchBookmarks(); } @@ -91,12 +82,6 @@ bookmark_model_->RemoveObserver(this); } -// static -void BookmarkSuggestionsProvider::RegisterProfilePrefs( - PrefRegistrySimple* registry) { - registry->RegisterInt64Pref(kDeprecatedBookmarksFirstM54StartPref, 0); -} - //////////////////////////////////////////////////////////////////////////////// // Private methods
diff --git a/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h b/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h index 64cd6e2..404c8d6 100644 --- a/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h +++ b/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h
@@ -15,9 +15,6 @@ #include "components/ntp_snippets/category_status.h" #include "components/ntp_snippets/content_suggestions_provider.h" -class PrefRegistrySimple; -class PrefService; - namespace ntp_snippets { // Provides content suggestions from the bookmarks model. @@ -25,12 +22,9 @@ public bookmarks::BookmarkModelObserver { public: BookmarkSuggestionsProvider(ContentSuggestionsProvider::Observer* observer, - bookmarks::BookmarkModel* bookmark_model, - PrefService* pref_service); + bookmarks::BookmarkModel* bookmark_model); ~BookmarkSuggestionsProvider() override; - static void RegisterProfilePrefs(PrefRegistrySimple* registry); - private: // ContentSuggestionsProvider implementation. CategoryStatus GetCategoryStatus(Category category) override;
diff --git a/components/ntp_snippets/bookmarks/bookmark_suggestions_provider_unittest.cc b/components/ntp_snippets/bookmarks/bookmark_suggestions_provider_unittest.cc index 92682d5..fda7b18 100644 --- a/components/ntp_snippets/bookmarks/bookmark_suggestions_provider_unittest.cc +++ b/components/ntp_snippets/bookmarks/bookmark_suggestions_provider_unittest.cc
@@ -18,7 +18,6 @@ #include "components/ntp_snippets/bookmarks/bookmark_last_visit_utils.h" #include "components/ntp_snippets/category.h" #include "components/ntp_snippets/mock_content_suggestions_provider_observer.h" -#include "components/prefs/testing_pref_service.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -53,15 +52,13 @@ _, Category::FromKnownCategory(KnownCategories::BOOKMARKS), CategoryStatus::AVAILABLE)) .RetiresOnSaturation(); - BookmarkSuggestionsProvider::RegisterProfilePrefs(test_prefs_.registry()); - provider_ = base::MakeUnique<BookmarkSuggestionsProvider>( - &observer_, model_.get(), &test_prefs_); + provider_ = + base::MakeUnique<BookmarkSuggestionsProvider>(&observer_, model_.get()); } protected: std::unique_ptr<bookmarks::BookmarkModel> model_; StrictMock<MockContentSuggestionsProviderObserver> observer_; - TestingPrefServiceSimple test_prefs_; std::unique_ptr<BookmarkSuggestionsProvider> provider_; };
diff --git a/components/payments/content/payment_request_state.cc b/components/payments/content/payment_request_state.cc index 12e57cf..350cccf 100644 --- a/components/payments/content/payment_request_state.cc +++ b/components/payments/content/payment_request_state.cc
@@ -238,26 +238,22 @@ std::vector<autofill::AutofillProfile*> profiles = personal_data_manager_->GetProfilesToSuggest(); + std::vector<autofill::AutofillProfile*> raw_profiles_for_filtering; + raw_profiles_for_filtering.reserve(profiles.size()); + // PaymentRequest may outlive the Profiles returned by the Data Manager. // Thus, we store copies, and return a vector of pointers to these copies // whenever Profiles are requested. for (size_t i = 0; i < profiles.size(); i++) { profile_cache_.push_back( base::MakeUnique<autofill::AutofillProfile>(*profiles[i])); - - shipping_profiles_.push_back(profile_cache_[i].get()); + raw_profiles_for_filtering.push_back(profile_cache_.back().get()); } - std::vector<autofill::AutofillProfile*> raw_profiles_for_filtering( - profile_cache_.size()); - std::transform(profile_cache_.begin(), profile_cache_.end(), - raw_profiles_for_filtering.begin(), - [](const std::unique_ptr<autofill::AutofillProfile>& p) { - return p.get(); - }); - contact_profiles_ = profile_comparator()->FilterProfilesForContact( raw_profiles_for_filtering); + shipping_profiles_ = profile_comparator()->FilterProfilesForShipping( + raw_profiles_for_filtering); // Create the list of available instruments. A copy of each card will be made // by their respective AutofillPaymentInstrument. @@ -269,22 +265,17 @@ void PaymentRequestState::SetDefaultProfileSelections() { // Only pre-select an address if the merchant provided at least one selected - // shipping option. - if (!shipping_profiles().empty() && spec_->selected_shipping_option()) { - // Choose any complete shipping profile, or default to the most frecent - // address if no complete address could be found. - selected_shipping_profile_ = shipping_profiles_[0]; - for (autofill::AutofillProfile* profile : shipping_profiles_) { - if (profile_comparator_.IsShippingComplete(profile)) { - selected_shipping_profile_ = profile; - break; - } - } + // shipping option, and the top profile is complete. Assumes that profiles + // have already been sorted for completeness and frecency. + if (!shipping_profiles().empty() && spec_->selected_shipping_option() && + profile_comparator()->IsShippingComplete(shipping_profiles_[0])) { + selected_shipping_profile_ = shipping_profiles()[0]; } // Contact profiles were ordered by completeness in addition to frecency; // the first one is the best default selection. - if (!contact_profiles().empty()) + if (!contact_profiles().empty() && + profile_comparator()->IsContactInfoComplete(contact_profiles_[0])) selected_contact_profile_ = contact_profiles()[0]; // TODO(crbug.com/702063): Change this code to prioritize instruments by use
diff --git a/components/payments/core/payment_request_data_util.cc b/components/payments/core/payment_request_data_util.cc index 87ad961..b2b3fcc 100644 --- a/components/payments/core/payment_request_data_util.cc +++ b/components/payments/core/payment_request_data_util.cc
@@ -152,6 +152,15 @@ } } +base::string16 GetFormattedPhoneNumberForDisplay( + const autofill::AutofillProfile& profile, + const std::string& locale) { + return base::UTF8ToUTF16(FormatPhoneForDisplay( + base::UTF16ToUTF8(profile.GetInfo( + autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER), locale)), + GetCountryCodeWithFallback(&profile, locale))); +} + std::string FormatPhoneForDisplay(const std::string& phone_number, const std::string& country_code) { return FormatPhoneNumber(phone_number, country_code,
diff --git a/components/payments/core/payment_request_data_util.h b/components/payments/core/payment_request_data_util.h index 29593f6..c301946d 100644 --- a/components/payments/core/payment_request_data_util.h +++ b/components/payments/core/payment_request_data_util.h
@@ -52,6 +52,11 @@ std::vector<std::string>* out_supported_networks, std::set<std::string>* out_basic_card_supported_networks); +// Returns the phone number from the given |profile| formatted for display. +base::string16 GetFormattedPhoneNumberForDisplay( + const autofill::AutofillProfile& profile, + const std::string& locale); + // Formats the given number |phone_number| to // i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::INTERNATIONAL format // by using i18n::phonenumbers::PhoneNumberUtil::Format.
diff --git a/components/payments/core/payments_profile_comparator.cc b/components/payments/core/payments_profile_comparator.cc index 832e005..e295762 100644 --- a/components/payments/core/payments_profile_comparator.cc +++ b/components/payments/core/payments_profile_comparator.cc
@@ -118,9 +118,6 @@ int PaymentsProfileComparator::GetContactCompletenessScore( const autofill::AutofillProfile* profile) const { - if (!profile) - return 0; - // Create a bitmask of the fields that are both present and required. ProfileFields present = ~GetMissingProfileFields(profile) & GetRequiredProfileFieldsForContact(); @@ -137,18 +134,42 @@ GetRequiredProfileFieldsForContact()); } -bool PaymentsProfileComparator::IsContactMoreComplete( - const autofill::AutofillProfile* p1, - const autofill::AutofillProfile* p2) const { - return GetContactCompletenessScore(p1) > GetContactCompletenessScore(p2); -} - base::string16 PaymentsProfileComparator::GetStringForMissingContactFields( const autofill::AutofillProfile& profile) const { return GetStringForMissingFields(GetMissingProfileFields(&profile) & GetRequiredProfileFieldsForContact()); } +std::vector<autofill::AutofillProfile*> +PaymentsProfileComparator::FilterProfilesForShipping( + const std::vector<autofill::AutofillProfile*>& profiles) const { + // Since we'll be changing the order/contents of the const input vector, + // we make a copy. + std::vector<autofill::AutofillProfile*> processed = profiles; + + std::stable_sort( + processed.begin(), processed.end(), + std::bind(&PaymentsProfileComparator::IsShippingMoreComplete, this, + std::placeholders::_1, std::placeholders::_2)); + + // TODO(crbug.com/722949): Remove profiles with no relevant information, or + // which are subsets of more-complete profiles. + + return processed; +} + +int PaymentsProfileComparator::GetShippingCompletenessScore( + const autofill::AutofillProfile* profile) const { + // Create a bitmask of the fields that are both present and required. + ProfileFields present = + ~GetMissingProfileFields(profile) & GetRequiredProfileFieldsForShipping(); + + // Count how many are set. The completeness of the address is weighted so as + // to dominate the other fields. + return !!(present & kName) + !!(present & kPhone) + + (10 * !!(present & kAddress)); +} + bool PaymentsProfileComparator::IsShippingComplete( const autofill::AutofillProfile* profile) const { // Mask the fields that are missing with those that are requried. If any bits @@ -248,4 +269,16 @@ return autofill::addressinput::HasAllRequiredFields(*data); } +bool PaymentsProfileComparator::IsContactMoreComplete( + const autofill::AutofillProfile* p1, + const autofill::AutofillProfile* p2) const { + return GetContactCompletenessScore(p1) > GetContactCompletenessScore(p2); +} + +bool PaymentsProfileComparator::IsShippingMoreComplete( + const autofill::AutofillProfile* p1, + const autofill::AutofillProfile* p2) const { + return GetShippingCompletenessScore(p1) > GetShippingCompletenessScore(p2); +} + } // namespace payments
diff --git a/components/payments/core/payments_profile_comparator.h b/components/payments/core/payments_profile_comparator.h index 2c8b934a..e186e05 100644 --- a/components/payments/core/payments_profile_comparator.h +++ b/components/payments/core/payments_profile_comparator.h
@@ -71,20 +71,24 @@ // |profile|. bool IsContactInfoComplete(const autofill::AutofillProfile* profile) const; - // Comparison function suitable for sorting profiles by contact completeness - // score with std::sort. - bool IsContactMoreComplete(const autofill::AutofillProfile* p1, - const autofill::AutofillProfile* p2) const; + // Returns profiles for shipping, ordered by completeness. |profiles| should + // be passed in order of frecency, and this order will be preserved among + // equally-complete profiles. + std::vector<autofill::AutofillProfile*> FilterProfilesForShipping( + const std::vector<autofill::AutofillProfile*>& profiles) const; + + int GetShippingCompletenessScore( + const autofill::AutofillProfile* profile) const; + + // Returns true iff every field needed to use |profile| as a shipping address + // is populated. + bool IsShippingComplete(const autofill::AutofillProfile* profile) const; // Returns a localized string to be displayed in UI indicating what action, // if any, must be taken for the given profile to be used as contact info. base::string16 GetStringForMissingContactFields( const autofill::AutofillProfile& profile) const; - // Returns true iff every field needed to use |profile| as a shipping address - // is populated. - bool IsShippingComplete(const autofill::AutofillProfile* profile) const; - // Returns a localized string to be displayed in UI indicating what action, // if any, must be taken for the given profile to be used as a shipping // address. @@ -103,6 +107,14 @@ base::string16 GetStringForMissingFields(ProfileFields fields) const; bool AreRequiredAddressFieldsPresent( const autofill::AutofillProfile& profile) const; + + // Comparison functions suitable for sorting profiles by completeness + // score with std::sort. + bool IsContactMoreComplete(const autofill::AutofillProfile* p1, + const autofill::AutofillProfile* p2) const; + bool IsShippingMoreComplete(const autofill::AutofillProfile* p1, + const autofill::AutofillProfile* p2) const; + mutable std::map<std::string, ProfileFields> cache_; const PaymentOptionsProvider& options_; };
diff --git a/components/payments/core/payments_profile_comparator_unittest.cc b/components/payments/core/payments_profile_comparator_unittest.cc index ac0691e..18f3e58a 100644 --- a/components/payments/core/payments_profile_comparator_unittest.cc +++ b/components/payments/core/payments_profile_comparator_unittest.cc
@@ -247,6 +247,103 @@ EXPECT_TRUE(empty_comp.IsContactInfoComplete(nullptr)); } +TEST(PaymentRequestProfileUtilTest, FilterProfilesForShipping) { + MockPaymentOptionsProvider provider(kRequestShipping); + PaymentsProfileComparator comp("en-US", provider); + + AutofillProfile address_only = CreateProfileWithCompleteAddress("", ""); + + AutofillProfile no_name = CreateProfileWithCompleteAddress("", "6515553226"); + AutofillProfile no_phone = CreateProfileWithCompleteAddress("Homer", ""); + + AutofillProfile empty = CreateProfileWithContactInfo("", "", ""); + + AutofillProfile complete1 = + CreateProfileWithCompleteAddress("Homer", "6515553226"); + + AutofillProfile partial_address = + CreateProfileWithPartialAddress("Homer", "6515553226"); + AutofillProfile no_address = + CreateProfileWithContactInfo("Homer", "", "6515553226"); + + AutofillProfile complete2 = + CreateProfileWithCompleteAddress("Bart", "6515553226"); + + AutofillProfile partial_no_phone = + CreateProfileWithPartialAddress("", "6515553226"); + AutofillProfile partial_no_name = + CreateProfileWithPartialAddress("Homer", ""); + + std::vector<AutofillProfile*> profiles = { + &address_only, &no_name, &no_phone, &empty, + &complete1, &partial_address, &no_address, &complete2, + &partial_no_phone, &partial_no_name}; + + std::vector<AutofillProfile*> filtered = + comp.FilterProfilesForShipping(profiles); + + // Current logic does not remove profiles, only reorder them. + ASSERT_EQ(10u, filtered.size()); + + // First, the complete profiles should be hoisted to the top, keeping their + // relative order. + EXPECT_EQ(&complete1, filtered[0]); + EXPECT_EQ(&complete2, filtered[1]); + + // Next are profiles with a complete address but missing one other field. + EXPECT_EQ(&no_name, filtered[2]); + EXPECT_EQ(&no_phone, filtered[3]); + + // A profile with only a complete address should still appear before profiles + // with partial/empty addresses. + EXPECT_EQ(&address_only, filtered[4]); + + // Profiles with partial/no address then are sorted by whether or not they + // have names and/or phone numbers. + EXPECT_EQ(&partial_address, filtered[5]); + EXPECT_EQ(&no_address, filtered[6]); + + EXPECT_EQ(&partial_no_phone, filtered[7]); + EXPECT_EQ(&partial_no_name, filtered[8]); + + EXPECT_EQ(&empty, filtered[9]); +} + +TEST(PaymentRequestProfileUtilTest, GetShippingCompletenessScore) { + MockPaymentOptionsProvider provider(kRequestShipping); + PaymentsProfileComparator comp("en-US", provider); + + // 12 points for a complete profile: 10 for address, 1 each for name/phone. + AutofillProfile p1 = CreateProfileWithCompleteAddress("Homer", "6515553226"); + EXPECT_EQ(12, comp.GetShippingCompletenessScore(&p1)); + + // 11 points if name or phone is missing. + AutofillProfile p2 = CreateProfileWithCompleteAddress("", "6515553226"); + AutofillProfile p3 = CreateProfileWithCompleteAddress("Homer", ""); + EXPECT_EQ(11, comp.GetShippingCompletenessScore(&p2)); + EXPECT_EQ(11, comp.GetShippingCompletenessScore(&p3)); + + // 10 points for complete address only. + AutofillProfile p4 = CreateProfileWithCompleteAddress("", ""); + EXPECT_EQ(10, comp.GetShippingCompletenessScore(&p4)); + + // 2 points for name and phone without address. + AutofillProfile p5 = CreateProfileWithContactInfo("Homer", "", "6515553226"); + EXPECT_EQ(2, comp.GetShippingCompletenessScore(&p5)); + + // 1 point for name or phone alone. + AutofillProfile p6 = CreateProfileWithContactInfo("Homer", "", ""); + AutofillProfile p7 = CreateProfileWithContactInfo("", "", "6515553226"); + EXPECT_EQ(1, comp.GetShippingCompletenessScore(&p6)); + EXPECT_EQ(1, comp.GetShippingCompletenessScore(&p7)); + + // No points for empty profile, or profile with only a partial address. + AutofillProfile p8 = CreateProfileWithContactInfo("", "", ""); + AutofillProfile p9 = CreateProfileWithPartialAddress("", ""); + EXPECT_EQ(0, comp.GetShippingCompletenessScore(&p8)); + EXPECT_EQ(0, comp.GetShippingCompletenessScore(&p9)); +} + TEST(PaymentRequestProfileUtilTest, IsShippingComplete) { MockPaymentOptionsProvider provider(kRequestShipping); PaymentsProfileComparator comp("en-US", provider);
diff --git a/components/resources/autofill_scaled_resources.grdp b/components/resources/autofill_scaled_resources.grdp index b3a3719..5eedb43 100644 --- a/components/resources/autofill_scaled_resources.grdp +++ b/components/resources/autofill_scaled_resources.grdp
@@ -22,21 +22,6 @@ <structure type="chrome_scaled_image" name="IDR_AUTOFILL_HTTPS_INVALID_WARNING" file="autofill/cc-generic.png" /> </if> - <!-- Payment Request image variants. - NOTE: These are placeholders; actual values are not used, since IDs are - mapped to drawables in resource_id.h --> - <if expr="is_android"> - <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_AMEX" file="autofill/cc-generic.png" /> - <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_DINERS" file="autofill/cc-generic.png" /> - <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_DISCOVER" file="autofill/cc-generic.png" /> - <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_GENERIC" file="autofill/cc-generic.png" /> - <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_JCB" file="autofill/cc-generic.png" /> - <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_MASTERCARD" file="autofill/cc-generic.png" /> - <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_MIR" file="autofill/cc-generic.png" /> - <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_UNIONPAY" file="autofill/cc-generic.png" /> - <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_VISA" file="autofill/cc-generic.png" /> - </if> - <structure type="chrome_scaled_image" name="IDR_CREDIT_CARD_CVC_HINT" file="autofill/credit_card_cvc_hint.png" /> <structure type="chrome_scaled_image" name="IDR_CREDIT_CARD_CVC_HINT_AMEX" file="autofill/credit_card_cvc_hint_amex.png" /> <if expr="is_ios or is_android">
diff --git a/components/translate/core/browser/mock_translate_ranker.cc b/components/translate/core/browser/mock_translate_ranker.cc index a96813a..1aa3d14 100644 --- a/components/translate/core/browser/mock_translate_ranker.cc +++ b/components/translate/core/browser/mock_translate_ranker.cc
@@ -19,9 +19,6 @@ } bool MockTranslateRanker::ShouldOfferTranslation( - const TranslatePrefs& /* translate_prefs */, - const std::string& /* src_lang */, - const std::string& /* dst_lang */, metrics::TranslateEventProto* /*translate_event */) { return should_offer_translation_; }
diff --git a/components/translate/core/browser/mock_translate_ranker.h b/components/translate/core/browser/mock_translate_ranker.h index f2e9d446..51dae4f 100644 --- a/components/translate/core/browser/mock_translate_ranker.h +++ b/components/translate/core/browser/mock_translate_ranker.h
@@ -20,8 +20,6 @@ namespace translate { -class TranslatePrefs; - namespace testing { class MockTranslateRanker : public TranslateRanker { @@ -43,9 +41,6 @@ // TranslateRanker Implementation: uint32_t GetModelVersion() const override; bool ShouldOfferTranslation( - const TranslatePrefs& translate_prefs, - const std::string& src_lang, - const std::string& dst_lang, metrics::TranslateEventProto* translate_events) override; void FlushTranslateEvents( std::vector<metrics::TranslateEventProto>* events) override;
diff --git a/components/translate/core/browser/translate_manager.cc b/components/translate/core/browser/translate_manager.cc index a9970118..089c6137c 100644 --- a/components/translate/core/browser/translate_manager.cc +++ b/components/translate/core/browser/translate_manager.cc
@@ -220,8 +220,8 @@ // Querying the ranker now, but not exiting immediately so that we may log // other potential suppression reasons. - bool should_offer_translation = translate_ranker_->ShouldOfferTranslation( - *translate_prefs, language_code, target_lang, translate_event_.get()); + bool should_offer_translation = + translate_ranker_->ShouldOfferTranslation(translate_event_.get()); // Nothing to do if either the language Chrome is in or the language of // the page is not supported by the translation server.
diff --git a/components/translate/core/browser/translate_ranker.h b/components/translate/core/browser/translate_ranker.h index 3b095383..9867052 100644 --- a/components/translate/core/browser/translate_ranker.h +++ b/components/translate/core/browser/translate_ranker.h
@@ -20,8 +20,6 @@ namespace translate { -class TranslatePrefs; - // If enabled, downloads a translate ranker model and uses it to determine // whether the user should be given a translation prompt or not. class TranslateRanker : public KeyedService { @@ -32,14 +30,10 @@ virtual uint32_t GetModelVersion() const = 0; // Returns true if executing the ranker model in the translation prompt - // context described by |translate_prefs|, |src_lang|, |dst_lang| and possibly + // context described by |translate_event| and possibly // other global browser context attributes suggests that the user should be // prompted as to whether translation should be performed. - // TODO(hamelphi): Take only the proto as input and extract features from it. virtual bool ShouldOfferTranslation( - const TranslatePrefs& translate_prefs, - const std::string& src_lang, - const std::string& dst_lang, metrics::TranslateEventProto* translate_event) = 0; // Transfers cached translate events to the given vector pointer and clears
diff --git a/components/translate/core/browser/translate_ranker_impl.cc b/components/translate/core/browser/translate_ranker_impl.cc index 6f34fa2..d31d471 100644 --- a/components/translate/core/browser/translate_ranker_impl.cc +++ b/components/translate/core/browser/translate_ranker_impl.cc
@@ -15,7 +15,6 @@ #include "base/metrics/histogram_macros.h" #include "base/metrics/metrics_hashes.h" #include "base/profiler/scoped_tracker.h" -#include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/task_runner.h" #include "base/threading/thread_task_runner_handle.h" @@ -23,9 +22,6 @@ #include "components/translate/core/browser/proto/ranker_model.pb.h" #include "components/translate/core/browser/proto/translate_ranker_model.pb.h" #include "components/translate/core/browser/ranker_model.h" -#include "components/translate/core/browser/translate_download_manager.h" -#include "components/translate/core/browser/translate_prefs.h" -#include "components/translate/core/browser/translate_url_fetcher.h" #include "components/translate/core/common/translate_switches.h" #include "components/ukm/public/ukm_entry_builder.h" #include "components/ukm/public/ukm_recorder.h" @@ -106,17 +102,16 @@ denied_ratio(SafeRatio(denied_count, total_count)), ignored_ratio(SafeRatio(ignored_count, total_count)) {} -TranslateRankerFeatures::TranslateRankerFeatures(const TranslatePrefs& prefs, - const std::string& src, - const std::string& dst, - const std::string& locale) - : TranslateRankerFeatures(prefs.GetTranslationAcceptedCount(src), - prefs.GetTranslationDeniedCount(src), - prefs.GetTranslationIgnoredCount(src), - src, - dst, - prefs.GetCountry(), - locale) {} +// TODO(hamelphi): Log locale in TranslateEventProtos. +TranslateRankerFeatures::TranslateRankerFeatures( + const metrics::TranslateEventProto& translate_event) + : TranslateRankerFeatures(translate_event.accept_count(), + translate_event.decline_count(), + translate_event.ignore_count(), + translate_event.source_language(), + translate_event.target_language(), + translate_event.country(), + "" /*locale*/) {} TranslateRankerFeatures::~TranslateRankerFeatures() {} @@ -195,9 +190,6 @@ } bool TranslateRankerImpl::ShouldOfferTranslation( - const TranslatePrefs& translate_prefs, - const std::string& src_lang, - const std::string& dst_lang, metrics::TranslateEventProto* translate_event) { DCHECK(sequence_checker_.CalledOnValidSequence()); // The ranker is a gate in the "show a translation prompt" flow. To retain @@ -234,11 +226,8 @@ FROM_HERE_WITH_EXPLICIT_FUNCTION( "646711 translate::TranslateRankerImpl::ShouldOfferTranslation")); - TranslateRankerFeatures features( - translate_prefs, src_lang, dst_lang, - TranslateDownloadManager::GetInstance()->application_locale()); + bool result = GetModelDecision(*translate_event); - bool result = GetModelDecision(features); UMA_HISTOGRAM_BOOLEAN("Translate.Ranker.QueryResult", result); translate_event->set_ranker_response( @@ -253,33 +242,38 @@ } bool TranslateRankerImpl::GetModelDecision( - const TranslateRankerFeatures& features) { + const metrics::TranslateEventProto& translate_event) { DCHECK(sequence_checker_.CalledOnValidSequence()); SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.CalculateScore"); DCHECK(model_ != nullptr); - const TranslateRankerModel::LogisticRegressionModel& logit = + + // TODO(hamelphi): consider deprecating TranslateRankerFeatures and move the + // logic here. + const TranslateRankerFeatures features(translate_event); + + const TranslateRankerModel::LogisticRegressionModel& lr_model = model_->proto().translate().logistic_regression_model(); double dot_product = - (features.accepted_count * logit.accept_count_weight()) + - (features.denied_count * logit.decline_count_weight()) + - (features.ignored_count * logit.ignore_count_weight()) + - (features.accepted_ratio * logit.accept_ratio_weight()) + - (features.denied_ratio * logit.decline_ratio_weight()) + - (features.ignored_ratio * logit.ignore_ratio_weight()) + - ScoreComponent(logit.source_language_weight(), features.src_lang) + - ScoreComponent(logit.target_language_weight(), features.dst_lang) + - ScoreComponent(logit.country_weight(), features.country) + - ScoreComponent(logit.locale_weight(), features.app_locale); + (features.accepted_count * lr_model.accept_count_weight()) + + (features.denied_count * lr_model.decline_count_weight()) + + (features.ignored_count * lr_model.ignore_count_weight()) + + (features.accepted_ratio * lr_model.accept_ratio_weight()) + + (features.denied_ratio * lr_model.decline_ratio_weight()) + + (features.ignored_ratio * lr_model.ignore_ratio_weight()) + + ScoreComponent(lr_model.source_language_weight(), features.src_lang) + + ScoreComponent(lr_model.target_language_weight(), features.dst_lang) + + ScoreComponent(lr_model.country_weight(), features.country) + + ScoreComponent(lr_model.locale_weight(), features.app_locale); - double score = Sigmoid(dot_product + logit.bias()); + double score = Sigmoid(dot_product + lr_model.bias()); DVLOG(2) << "TranslateRankerImpl::GetModelDecision: " << "Score = " << score << ", Features=[" << features << "]"; float decision_threshold = kTranslationOfferDefaultThreshold; - if (logit.threshold() > 0) { - decision_threshold = logit.threshold(); + if (lr_model.threshold() > 0) { + decision_threshold = lr_model.threshold(); } return score >= decision_threshold;
diff --git a/components/translate/core/browser/translate_ranker_impl.h b/components/translate/core/browser/translate_ranker_impl.h index fa3eb4b..abbed4d5 100644 --- a/components/translate/core/browser/translate_ranker_impl.h +++ b/components/translate/core/browser/translate_ranker_impl.h
@@ -34,8 +34,6 @@ namespace translate { -class TranslatePrefs; - // Features used to enable ranker query, enforcement and logging. Note that // enabling enforcement implies (forces) enabling queries. extern const base::Feature kTranslateRankerQuery; @@ -53,10 +51,7 @@ const std::string& cntry, const std::string& locale); - TranslateRankerFeatures(const TranslatePrefs& prefs, - const std::string& src, - const std::string& dst, - const std::string& locale); + TranslateRankerFeatures(const metrics::TranslateEventProto& tep); ~TranslateRankerFeatures(); @@ -101,9 +96,6 @@ // TranslateRanker... uint32_t GetModelVersion() const override; bool ShouldOfferTranslation( - const TranslatePrefs& translate_prefs, - const std::string& src_lang, - const std::string& dst_lang, metrics::TranslateEventProto* translate_event) override; void FlushTranslateEvents( std::vector<metrics::TranslateEventProto>* events) override; @@ -120,8 +112,8 @@ std::unique_ptr<chrome_intelligence::RankerModel> model); // Get the model decision on whether we should show the translate - // UI or not given |features|. - bool GetModelDecision(const TranslateRankerFeatures& features); + // UI or not given |translate_event|. + bool GetModelDecision(const metrics::TranslateEventProto& translate_event); // Check if the ModelLoader has been initialized. Used to test ModelLoader // logic.
diff --git a/components/translate/core/browser/translate_ranker_impl_unittest.cc b/components/translate/core/browser/translate_ranker_impl_unittest.cc index e3a9743..b61b4b7 100644 --- a/components/translate/core/browser/translate_ranker_impl_unittest.cc +++ b/components/translate/core/browser/translate_ranker_impl_unittest.cc
@@ -16,13 +16,9 @@ #include "base/test/scoped_task_environment.h" #include "components/metrics/proto/translate_event.pb.h" #include "components/metrics/proto/ukm/source.pb.h" -#include "components/prefs/scoped_user_pref_update.h" -#include "components/sync_preferences/testing_pref_service_syncable.h" #include "components/translate/core/browser/proto/ranker_model.pb.h" #include "components/translate/core/browser/proto/translate_ranker_model.pb.h" #include "components/translate/core/browser/ranker_model.h" -#include "components/translate/core/browser/translate_download_manager.h" -#include "components/translate/core/browser/translate_prefs.h" #include "components/ukm/test_ukm_recorder.h" #include "components/ukm/ukm_source.h" #include "net/url_request/test_url_fetcher_factory.h" @@ -35,9 +31,7 @@ using translate::kTranslateRankerEnforcement; using translate::kTranslateRankerQuery; using translate::kTranslateRankerDecisionOverride; -using translate::TranslateDownloadManager; using translate::TranslateRankerFeatures; -using translate::TranslatePrefs; using translate::TranslateRankerImpl; constexpr uint32_t kModelVersion = 1234; @@ -46,15 +40,13 @@ protected: TranslateRankerImplTest(); - void SetUp() override; - - void TearDown() override; - // Initializes the explicitly |enabled| and |disabled| features for this test. void InitFeatures(const std::initializer_list<base::Feature>& enabled, const std::initializer_list<base::Feature>& disabled); - // Returns a TranslateRankerImpl object with |threshold| for testing. + // Returns a TranslateRankerImpl object with |threshold| for testing. The + // returned ranker is configured with an empty cache path and URL and will not + // invoke the model loader. std::unique_ptr<TranslateRankerImpl> GetRankerForTest(float threshold); // Implements the same sigmoid function used by TranslateRankerImpl. @@ -64,83 +56,36 @@ static metrics::TranslateEventProto CreateTranslateEvent( const std::string& src_lang, const std::string& dst_lang, + const std::string& country, int accept_count, int decline_count, int ignore_count); - // The platform-specific name of the preferred language pref. - static const char* const kPreferredLanguagePref; - - // Prefs. - std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> prefs_; - std::unique_ptr<translate::TranslatePrefs> translate_prefs_; + // Returns a translate event initialized with the given parameters. + static metrics::TranslateEventProto CreateDefaultTranslateEvent(); ukm::TestUkmRecorder* GetTestUkmRecorder() { return &test_ukm_recorder_; } - metrics::TranslateEventProto tep1_ = - CreateTranslateEvent("fr", "en", 1, 0, 3); - metrics::TranslateEventProto tep2_ = - CreateTranslateEvent("jp", "en", 2, 0, 3); - metrics::TranslateEventProto tep3_ = - CreateTranslateEvent("es", "de", 4, 5, 6); + metrics::TranslateEventProto translate_event1_ = + CreateTranslateEvent("fr", "en", "de", 1, 0, 3); + metrics::TranslateEventProto translate_event2_ = + CreateTranslateEvent("jp", "en", "de", 2, 0, 3); + metrics::TranslateEventProto translate_event3_ = + CreateTranslateEvent("es", "de", "de", 4, 5, 6); private: ukm::TestUkmRecorder test_ukm_recorder_; - // Override the default URL fetcher to return custom responses for tests. - net::TestURLFetcherFactory url_fetcher_factory_; - - // Used to initialize the translate download manager. - scoped_refptr<net::TestURLRequestContextGetter> request_context_; - // Sets up the task scheduling/task-runner environment for each test. base::test::ScopedTaskEnvironment scoped_task_environment_; // Manages the enabling/disabling of features within the scope of a test. base::test::ScopedFeatureList scoped_feature_list_; - // Cache and reset the application locale for each test. - std::string locale_; - DISALLOW_COPY_AND_ASSIGN(TranslateRankerImplTest); }; -const char* const TranslateRankerImplTest::kPreferredLanguagePref = -#if defined(OS_CHROMEOS) - "settings.language.preferred_languages"; -#else - nullptr; -#endif - TranslateRankerImplTest::TranslateRankerImplTest() {} -void TranslateRankerImplTest::SetUp() { - // Setup the translate download manager. - locale_ = TranslateDownloadManager::GetInstance()->application_locale(); - request_context_ = - new net::TestURLRequestContextGetter(base::ThreadTaskRunnerHandle::Get()); - TranslateDownloadManager::GetInstance()->set_application_locale("zh-CN"); - TranslateDownloadManager::GetInstance()->set_request_context( - request_context_.get()); - - // Setup a 50/50 accepted/denied count for "english" when initialize the - // prefs and translate prefs. - base::DictionaryValue lang_count; - lang_count.SetInteger("en", 50); - prefs_.reset(new sync_preferences::TestingPrefServiceSyncable()); - TranslatePrefs::RegisterProfilePrefs(prefs_->registry()); - prefs_->Set(TranslatePrefs::kPrefTranslateAcceptedCount, lang_count); - prefs_->Set(TranslatePrefs::kPrefTranslateDeniedCount, lang_count); - translate_prefs_.reset(new TranslatePrefs( - prefs_.get(), "intl.accept_languages", kPreferredLanguagePref)); - translate_prefs_->SetCountry("de"); -} - -void TranslateRankerImplTest::TearDown() { - base::RunLoop().RunUntilIdle(); - TranslateDownloadManager::GetInstance()->set_application_locale(locale_); - TranslateDownloadManager::GetInstance()->set_request_context(nullptr); -} - void TranslateRankerImplTest::InitFeatures( const std::initializer_list<base::Feature>& enabled, const std::initializer_list<base::Feature>& disabled) { @@ -176,11 +121,6 @@ country_weight["ca"] = 0.08f; country_weight["cn"] = 0.09f; - auto& locale_weight = *details->mutable_locale_weight(); - locale_weight["en-us"] = 0.10f; - locale_weight["en-ca"] = 0.11f; - locale_weight["zh-cn"] = 0.12f; // Normalized to lowercase. - auto impl = base::MakeUnique<TranslateRankerImpl>(base::FilePath(), GURL(), GetTestUkmRecorder()); impl->OnModelAvailable(std::move(model)); @@ -197,18 +137,27 @@ metrics::TranslateEventProto TranslateRankerImplTest::CreateTranslateEvent( const std::string& src_lang, const std::string& dst_lang, + const std::string& country, int accept_count, int decline_count, int ignore_count) { metrics::TranslateEventProto translate_event; translate_event.set_source_language(src_lang); translate_event.set_target_language(dst_lang); + translate_event.set_country(country); translate_event.set_accept_count(accept_count); translate_event.set_decline_count(decline_count); translate_event.set_ignore_count(ignore_count); return translate_event; } +// static +metrics::TranslateEventProto +TranslateRankerImplTest::CreateDefaultTranslateEvent() { + return TranslateRankerImplTest::CreateTranslateEvent("en", "fr", "de", 50, 50, + 0); +} + } // namespace TEST_F(TranslateRankerImplTest, GetVersion) { @@ -228,7 +177,7 @@ TEST_F(TranslateRankerImplTest, GetModelDecision) { InitFeatures({kTranslateRankerEnforcement}, {}); // Calculate the score using: a 50:50 accept/decline ratio; the one-hot - // values for the src lang, dest lang, locale and counry; and, the bias. + // values for the src lang, dest lang, and country; and, the bias. double expected_score = Sigmoid(50.0 * 0.13f + // accept count * weight 50.0 * -0.14f + // decline count * weight @@ -239,90 +188,94 @@ 1.0 * 0.04f + // one-hot src-language "en" * weight 1.0 * 0.00f + // one-hot dst-language "fr" * weight 1.0 * 0.07f + // one-hot country "de" * weight - 1.0 * 0.12f + // one-hot locale "zh-CN" * weight 0.5f); // bias - TranslateRankerFeatures features(50, 50, 0, "en", "fr", "de", "zh-CN"); + metrics::TranslateEventProto translate_event = CreateDefaultTranslateEvent(); const float epsilon = 0.001f; auto ranker = GetRankerForTest(expected_score + epsilon); - EXPECT_FALSE(ranker->GetModelDecision(features)); + EXPECT_FALSE(ranker->GetModelDecision(translate_event)); ranker = GetRankerForTest(expected_score - epsilon); - EXPECT_TRUE(ranker->GetModelDecision(features)); + EXPECT_TRUE(ranker->GetModelDecision(translate_event)); ranker = GetRankerForTest(0.0); - EXPECT_EQ(expected_score >= 0.5, ranker->GetModelDecision(features)); + EXPECT_EQ(expected_score >= 0.5, ranker->GetModelDecision(translate_event)); } TEST_F(TranslateRankerImplTest, ShouldOfferTranslation_AllEnabled) { InitFeatures({kTranslateRankerQuery, kTranslateRankerEnforcement, kTranslateRankerDecisionOverride}, {}); - metrics::TranslateEventProto tep; + metrics::TranslateEventProto translate_event = CreateDefaultTranslateEvent(); // With a threshold of 0.99, en->fr is not over the threshold. - EXPECT_FALSE(GetRankerForTest(0.99f)->ShouldOfferTranslation( - *translate_prefs_, "en", "fr", &tep)); - EXPECT_NE(0U, tep.ranker_request_timestamp_sec()); - EXPECT_EQ(kModelVersion, tep.ranker_version()); - EXPECT_EQ(metrics::TranslateEventProto::DONT_SHOW, tep.ranker_response()); + EXPECT_FALSE( + GetRankerForTest(0.99f)->ShouldOfferTranslation(&translate_event)); + EXPECT_NE(0U, translate_event.ranker_request_timestamp_sec()); + EXPECT_EQ(kModelVersion, translate_event.ranker_version()); + EXPECT_EQ(metrics::TranslateEventProto::DONT_SHOW, + translate_event.ranker_response()); // With a threshold of 0.01, en-fr is over the threshold. - tep.Clear(); - EXPECT_TRUE(GetRankerForTest(0.01f)->ShouldOfferTranslation( - *translate_prefs_, "en", "fr", &tep)); - EXPECT_EQ(metrics::TranslateEventProto::SHOW, tep.ranker_response()); + translate_event.Clear(); + EXPECT_TRUE( + GetRankerForTest(0.01f)->ShouldOfferTranslation(&translate_event)); + EXPECT_EQ(metrics::TranslateEventProto::SHOW, + translate_event.ranker_response()); } TEST_F(TranslateRankerImplTest, ShouldOfferTranslation_AllDisabled) { InitFeatures({}, {kTranslateRankerQuery, kTranslateRankerEnforcement, kTranslateRankerDecisionOverride}); - metrics::TranslateEventProto tep; + metrics::TranslateEventProto translate_event = CreateDefaultTranslateEvent(); // If query and other flags are turned off, returns true and do not query the // ranker. - EXPECT_TRUE(GetRankerForTest(0.5f)->ShouldOfferTranslation(*translate_prefs_, - "en", "fr", &tep)); - EXPECT_NE(0U, tep.ranker_request_timestamp_sec()); - EXPECT_EQ(kModelVersion, tep.ranker_version()); - EXPECT_EQ(metrics::TranslateEventProto::NOT_QUERIED, tep.ranker_response()); + EXPECT_TRUE(GetRankerForTest(0.5f)->ShouldOfferTranslation(&translate_event)); + EXPECT_NE(0U, translate_event.ranker_request_timestamp_sec()); + EXPECT_EQ(kModelVersion, translate_event.ranker_version()); + EXPECT_EQ(metrics::TranslateEventProto::NOT_QUERIED, + translate_event.ranker_response()); } TEST_F(TranslateRankerImplTest, ShouldOfferTranslation_QueryOnly) { InitFeatures({kTranslateRankerQuery}, {kTranslateRankerEnforcement, kTranslateRankerDecisionOverride}); - metrics::TranslateEventProto tep; + metrics::TranslateEventProto translate_event = CreateDefaultTranslateEvent(); // If enforcement is turned off, returns true even if the decision // is not to show. - EXPECT_TRUE(GetRankerForTest(0.99f)->ShouldOfferTranslation( - *translate_prefs_, "en", "fr", &tep)); - EXPECT_NE(0U, tep.ranker_request_timestamp_sec()); - EXPECT_EQ(kModelVersion, tep.ranker_version()); - EXPECT_EQ(metrics::TranslateEventProto::DONT_SHOW, tep.ranker_response()); + EXPECT_TRUE( + GetRankerForTest(0.99f)->ShouldOfferTranslation(&translate_event)); + EXPECT_NE(0U, translate_event.ranker_request_timestamp_sec()); + EXPECT_EQ(kModelVersion, translate_event.ranker_version()); + EXPECT_EQ(metrics::TranslateEventProto::DONT_SHOW, + translate_event.ranker_response()); } TEST_F(TranslateRankerImplTest, ShouldOfferTranslation_EnforcementOnly) { InitFeatures({kTranslateRankerEnforcement}, {kTranslateRankerQuery, kTranslateRankerDecisionOverride}); - metrics::TranslateEventProto tep; + metrics::TranslateEventProto translate_event = CreateDefaultTranslateEvent(); // If either enforcement or decision override are turned on, returns the // ranker decision. - EXPECT_FALSE(GetRankerForTest(0.99f)->ShouldOfferTranslation( - *translate_prefs_, "en", "fr", &tep)); - EXPECT_NE(0U, tep.ranker_request_timestamp_sec()); - EXPECT_EQ(kModelVersion, tep.ranker_version()); - EXPECT_EQ(metrics::TranslateEventProto::DONT_SHOW, tep.ranker_response()); + EXPECT_FALSE( + GetRankerForTest(0.99f)->ShouldOfferTranslation(&translate_event)); + EXPECT_NE(0U, translate_event.ranker_request_timestamp_sec()); + EXPECT_EQ(kModelVersion, translate_event.ranker_version()); + EXPECT_EQ(metrics::TranslateEventProto::DONT_SHOW, + translate_event.ranker_response()); } TEST_F(TranslateRankerImplTest, ShouldOfferTranslation_OverrideOnly) { InitFeatures({kTranslateRankerDecisionOverride}, {kTranslateRankerQuery, kTranslateRankerEnforcement}); - metrics::TranslateEventProto tep; + metrics::TranslateEventProto translate_event = CreateDefaultTranslateEvent(); // If either enforcement or decision override are turned on, returns the // ranker decision. - EXPECT_FALSE(GetRankerForTest(0.99f)->ShouldOfferTranslation( - *translate_prefs_, "en", "fr", &tep)); - EXPECT_NE(0U, tep.ranker_request_timestamp_sec()); - EXPECT_EQ(kModelVersion, tep.ranker_version()); - EXPECT_EQ(metrics::TranslateEventProto::DONT_SHOW, tep.ranker_response()); + EXPECT_FALSE( + GetRankerForTest(0.99f)->ShouldOfferTranslation(&translate_event)); + EXPECT_NE(0U, translate_event.ranker_request_timestamp_sec()); + EXPECT_EQ(kModelVersion, translate_event.ranker_version()); + EXPECT_EQ(metrics::TranslateEventProto::DONT_SHOW, + translate_event.ranker_response()); } TEST_F(TranslateRankerImplTest, ShouldOfferTranslation_NoModel) { @@ -331,13 +284,13 @@ InitFeatures({kTranslateRankerDecisionOverride, kTranslateRankerQuery, kTranslateRankerEnforcement}, {}); - metrics::TranslateEventProto tep; + metrics::TranslateEventProto translate_event = CreateDefaultTranslateEvent(); // If we don't have a model, returns true. - EXPECT_TRUE( - ranker->ShouldOfferTranslation(*translate_prefs_, "en", "fr", &tep)); - EXPECT_NE(0U, tep.ranker_request_timestamp_sec()); - EXPECT_EQ(0U, tep.ranker_version()); - EXPECT_EQ(metrics::TranslateEventProto::NOT_QUERIED, tep.ranker_response()); + EXPECT_TRUE(ranker->ShouldOfferTranslation(&translate_event)); + EXPECT_NE(0U, translate_event.ranker_request_timestamp_sec()); + EXPECT_EQ(0U, translate_event.ranker_version()); + EXPECT_EQ(metrics::TranslateEventProto::NOT_QUERIED, + translate_event.ranker_response()); } TEST_F(TranslateRankerImplTest, RecordAndFlushEvents) { @@ -351,18 +304,21 @@ ranker->FlushTranslateEvents(&flushed_events); EXPECT_EQ(0U, flushed_events.size()); - ranker->RecordTranslateEvent(0, url0, &tep1_); - ranker->RecordTranslateEvent(1, GURL(), &tep2_); - ranker->RecordTranslateEvent(2, url1, &tep3_); + ranker->RecordTranslateEvent(0, url0, &translate_event1_); + ranker->RecordTranslateEvent(1, GURL(), &translate_event2_); + ranker->RecordTranslateEvent(2, url1, &translate_event3_); // Capture the data and verify that it is as expected. ranker->FlushTranslateEvents(&flushed_events); EXPECT_EQ(3U, flushed_events.size()); - ASSERT_EQ(tep1_.source_language(), flushed_events[0].source_language()); + ASSERT_EQ(translate_event1_.source_language(), + flushed_events[0].source_language()); ASSERT_EQ(0, flushed_events[0].event_type()); - ASSERT_EQ(tep2_.source_language(), flushed_events[1].source_language()); + ASSERT_EQ(translate_event2_.source_language(), + flushed_events[1].source_language()); ASSERT_EQ(1, flushed_events[1].event_type()); - ASSERT_EQ(tep3_.source_language(), flushed_events[2].source_language()); + ASSERT_EQ(translate_event3_.source_language(), + flushed_events[2].source_language()); ASSERT_EQ(2, flushed_events[2].event_type()); // Check that the cache has been cleared. @@ -386,9 +342,9 @@ ranker->FlushTranslateEvents(&flushed_events); EXPECT_EQ(0U, flushed_events.size()); - ranker->RecordTranslateEvent(0, GURL(), &tep1_); - ranker->RecordTranslateEvent(1, GURL(), &tep2_); - ranker->RecordTranslateEvent(2, GURL(), &tep3_); + ranker->RecordTranslateEvent(0, GURL(), &translate_event1_); + ranker->RecordTranslateEvent(1, GURL(), &translate_event2_); + ranker->RecordTranslateEvent(2, GURL(), &translate_event3_); // Logging is enabled by default, so events should be cached. ranker->FlushTranslateEvents(&flushed_events); @@ -397,9 +353,9 @@ // Override the feature setting to disable logging. ranker->EnableLogging(false); - ranker->RecordTranslateEvent(0, GURL(), &tep1_); - ranker->RecordTranslateEvent(1, GURL(), &tep2_); - ranker->RecordTranslateEvent(2, GURL(), &tep3_); + ranker->RecordTranslateEvent(0, GURL(), &translate_event1_); + ranker->RecordTranslateEvent(1, GURL(), &translate_event2_); + ranker->RecordTranslateEvent(2, GURL(), &translate_event3_); // Logging is disabled, so no events should be cached. ranker->FlushTranslateEvents(&flushed_events); @@ -411,14 +367,16 @@ std::unique_ptr<translate::TranslateRankerImpl> ranker = GetRankerForTest(0.0f); const int kEventType = 12; - metrics::TranslateEventProto tep = CreateTranslateEvent("fr", "en", 1, 0, 3); + metrics::TranslateEventProto translate_event = CreateDefaultTranslateEvent(); - EXPECT_FALSE(ranker->ShouldOverrideDecision(kEventType, GURL(), &tep)); + EXPECT_FALSE( + ranker->ShouldOverrideDecision(kEventType, GURL(), &translate_event)); std::vector<metrics::TranslateEventProto> flushed_events; ranker->FlushTranslateEvents(&flushed_events); EXPECT_EQ(1U, flushed_events.size()); - ASSERT_EQ(tep.source_language(), flushed_events[0].source_language()); + ASSERT_EQ(translate_event.source_language(), + flushed_events[0].source_language()); ASSERT_EQ(kEventType, flushed_events[0].event_type()); } @@ -426,16 +384,16 @@ InitFeatures({kTranslateRankerDecisionOverride}, {}); std::unique_ptr<translate::TranslateRankerImpl> ranker = GetRankerForTest(0.0f); - metrics::TranslateEventProto tep = CreateTranslateEvent("fr", "en", 1, 0, 3); + metrics::TranslateEventProto translate_event = CreateDefaultTranslateEvent(); - EXPECT_TRUE(ranker->ShouldOverrideDecision(1, GURL(), &tep)); - EXPECT_TRUE(ranker->ShouldOverrideDecision(2, GURL(), &tep)); + EXPECT_TRUE(ranker->ShouldOverrideDecision(1, GURL(), &translate_event)); + EXPECT_TRUE(ranker->ShouldOverrideDecision(2, GURL(), &translate_event)); std::vector<metrics::TranslateEventProto> flushed_events; ranker->FlushTranslateEvents(&flushed_events); EXPECT_EQ(0U, flushed_events.size()); - ASSERT_EQ(2, tep.decision_overrides_size()); - ASSERT_EQ(1, tep.decision_overrides(0)); - ASSERT_EQ(2, tep.decision_overrides(1)); - ASSERT_EQ(0, tep.event_type()); + ASSERT_EQ(2, translate_event.decision_overrides_size()); + ASSERT_EQ(1, translate_event.decision_overrides(0)); + ASSERT_EQ(2, translate_event.decision_overrides(1)); + ASSERT_EQ(0, translate_event.event_type()); }
diff --git a/components/viz/frame_sinks/mojo_frame_sink_manager.cc b/components/viz/frame_sinks/mojo_frame_sink_manager.cc index a41c1a4..3e7f681 100644 --- a/components/viz/frame_sinks/mojo_frame_sink_manager.cc +++ b/components/viz/frame_sinks/mojo_frame_sink_manager.cc
@@ -129,6 +129,9 @@ void MojoFrameSinkManager::OnSurfaceDamaged(const cc::SurfaceId& surface_id, bool* changed) {} +void MojoFrameSinkManager::OnSurfaceDiscarded(const cc::SurfaceId& surface_id) { +} + void MojoFrameSinkManager::OnClientConnectionLost( const cc::FrameSinkId& frame_sink_id, bool destroy_compositor_frame_sink) {
diff --git a/components/viz/frame_sinks/mojo_frame_sink_manager.h b/components/viz/frame_sinks/mojo_frame_sink_manager.h index 2539862..8495617 100644 --- a/components/viz/frame_sinks/mojo_frame_sink_manager.h +++ b/components/viz/frame_sinks/mojo_frame_sink_manager.h
@@ -82,6 +82,7 @@ void OnSurfaceCreated(const cc::SurfaceInfo& surface_info) override; void OnSurfaceDamaged(const cc::SurfaceId& surface_id, bool* changed) override; + void OnSurfaceDiscarded(const cc::SurfaceId& surface_id) override; // GpuCompositorFrameSinkDelegate implementation. void OnClientConnectionLost(const cc::FrameSinkId& frame_sink_id,
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index e6dc149..e81b07b 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -11,12 +11,6 @@ import("//third_party/WebKit/public/public_features.gni") import("//tools/ipc_fuzzer/ipc_fuzzer.gni") -declare_args() { - # Include code in the build that is only needed when using the video - # capture Mojo service, which is currently experimental. - enable_mojo_video_capture = false -} - source_set("browser") { # Only the public target should depend on this. All other targets (even # internal content ones) should depend on the public one. @@ -131,6 +125,8 @@ "//services/shape_detection/public/interfaces", "//services/ui/gpu/interfaces", "//services/ui/public/cpp/gpu", + "//services/video_capture/public/cpp", + "//services/video_capture/public/interfaces:constants", "//skia", "//sql", "//storage/browser", @@ -1233,6 +1229,12 @@ "renderer_host/media/renderer_audio_output_stream_factory_context.h", "renderer_host/media/renderer_audio_output_stream_factory_context_impl.cc", "renderer_host/media/renderer_audio_output_stream_factory_context_impl.h", + "renderer_host/media/service_launched_video_capture_device.cc", + "renderer_host/media/service_launched_video_capture_device.h", + "renderer_host/media/service_video_capture_device_launcher.cc", + "renderer_host/media/service_video_capture_device_launcher.h", + "renderer_host/media/service_video_capture_provider.cc", + "renderer_host/media/service_video_capture_provider.h", "renderer_host/media/video_capture_controller.cc", "renderer_host/media/video_capture_controller.h", "renderer_host/media/video_capture_controller_event_handler.h", @@ -1244,6 +1246,8 @@ "renderer_host/media/video_capture_manager.cc", "renderer_host/media/video_capture_manager.h", "renderer_host/media/video_capture_provider.h", + "renderer_host/media/video_capture_provider_switcher.cc", + "renderer_host/media/video_capture_provider_switcher.h", "renderer_host/native_web_keyboard_event_aura.cc", "renderer_host/native_web_keyboard_event_mac.mm", "renderer_host/offscreen_canvas_provider_impl.cc", @@ -1629,22 +1633,6 @@ ] } - if (enable_mojo_video_capture) { - sources += [ - "renderer_host/media/service_launched_video_capture_device.cc", - "renderer_host/media/service_launched_video_capture_device.h", - "renderer_host/media/service_video_capture_device_launcher.cc", - "renderer_host/media/service_video_capture_device_launcher.h", - "renderer_host/media/service_video_capture_provider.cc", - "renderer_host/media/service_video_capture_provider.h", - ] - - deps += [ - "//services/video_capture/public/cpp", - "//services/video_capture/public/interfaces:constants", - ] - } - # Desktop screen capture implementations, conditionally built depending on # the available implementations for each platform. if (is_linux || is_mac || is_win) {
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc index 5542a6a..3257869 100644 --- a/content/browser/accessibility/browser_accessibility_com_win.cc +++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -5132,9 +5132,6 @@ if (owner()->HasState(ui::AX_STATE_EDITABLE)) ia2_state |= IA2_STATE_EDITABLE; - if (owner()->HasAction(ui::AX_ACTION_SET_VALUE)) - ia2_state |= IA2_STATE_EDITABLE; - if (!owner()->GetStringAttribute(ui::AX_ATTR_AUTO_COMPLETE).empty()) ia2_state |= IA2_STATE_SUPPORTS_AUTOCOMPLETION;
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc index 264a86b..6a197ca 100644 --- a/content/browser/accessibility/browser_accessibility_manager.cc +++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -389,8 +389,11 @@ // Fire any events related to changes to the tree. for (auto& event : tree_events_) { + BrowserAccessibility* event_target = GetFromID(event.second); + if (!event_target) + continue; NotifyAccessibilityEvent(BrowserAccessibilityEvent::FromTreeChange, - event.first, event.second); + event.first, event_target); } tree_events_.clear(); @@ -1190,11 +1193,12 @@ DCHECK(created_node); BrowserAccessibility* object = GetFromAXNode(created_node); if (object && object->HasStringAttribute(ui::AX_ATTR_LIVE_STATUS)) { + int32_t id = object->GetId(); if (object->GetRole() == ui::AX_ROLE_ALERT) { - tree_events_.push_back(std::make_pair(ui::AX_EVENT_ALERT, object)); + tree_events_.push_back(std::make_pair(ui::AX_EVENT_ALERT, id)); } else { tree_events_.push_back( - std::make_pair(ui::AX_EVENT_LIVE_REGION_CREATED, object)); + std::make_pair(ui::AX_EVENT_LIVE_REGION_CREATED, id)); } } }
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h index 6bd0d1b..3f7c5ca 100644 --- a/content/browser/accessibility/browser_accessibility_manager.h +++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -441,10 +441,9 @@ // A mapping from a node id to its wrapper of type BrowserAccessibility. base::hash_map<int32_t, BrowserAccessibility*> id_wrapper_map_; - // A list of accessibility events to fire based on changes to the - // accessibility tree. Only used within the scope of one call to - // OnAccessibilityEvents, so it's safe to store raw pointers. - std::vector<std::pair<ui::AXEvent, BrowserAccessibility*>> tree_events_; + // A queue of accessibility events to fire based on changes to the + // accessibility tree. Each one is an event and a node id. + std::vector<std::pair<ui::AXEvent, int32_t>> tree_events_; // True if the user has initiated a navigation to another page. bool user_is_navigating_away_;
diff --git a/content/browser/renderer_host/input/synthetic_gesture_controller.cc b/content/browser/renderer_host/input/synthetic_gesture_controller.cc index 1ab65e7..f6503e8 100644 --- a/content/browser/renderer_host/input/synthetic_gesture_controller.cc +++ b/content/browser/renderer_host/input/synthetic_gesture_controller.cc
@@ -41,18 +41,41 @@ } void SyntheticGestureController::RequestBeginFrame() { + DCHECK(!dispatch_timer_.IsRunning()); delegate_->RequestBeginFrameForSynthesizedInput( base::BindOnce(&SyntheticGestureController::OnBeginFrame, weak_ptr_factory_.GetWeakPtr())); } void SyntheticGestureController::OnBeginFrame() { - // TODO(sad): Instead of dispatching the events immediately, dispatch after an - // offset. - DispatchNextEvent(); + // In order to make sure we get consistent results across runs, we attempt to + // start the timer at a fixed offset from the vsync. Starting the timer + // shortly after a begin-frame is likely to produce latency close to the worst + // cases. We feel 2 milliseconds is a good offset for this. + constexpr base::TimeDelta kSynthesizedDispatchDelay = + base::TimeDelta::FromMilliseconds(2); + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&SyntheticGestureController::StartTimer, + weak_ptr_factory_.GetWeakPtr()), + kSynthesizedDispatchDelay); +} + +void SyntheticGestureController::StartTimer() { + // TODO(sad): Change the interval to allow sending multiple events per begin + // frame. + dispatch_timer_.Start( + FROM_HERE, base::TimeDelta::FromMicroseconds(16666), + base::BindRepeating( + [](base::WeakPtr<SyntheticGestureController> weak_ptr) { + if (weak_ptr) + weak_ptr->DispatchNextEvent(base::TimeTicks::Now()); + }, + weak_ptr_factory_.GetWeakPtr())); } bool SyntheticGestureController::DispatchNextEvent(base::TimeTicks timestamp) { + DCHECK(dispatch_timer_.IsRunning()); TRACE_EVENT0("input", "SyntheticGestureController::Flush"); if (pending_gesture_queue_.IsEmpty()) return false; @@ -63,23 +86,22 @@ timestamp, gesture_target_.get()); if (result == SyntheticGesture::GESTURE_RUNNING) { - RequestBeginFrame(); return true; } pending_gesture_queue_.mark_current_gesture_complete(result); } - if (!delegate_->HasGestureStopped()) { - RequestBeginFrame(); + if (!delegate_->HasGestureStopped()) return true; - } StopGesture(*pending_gesture_queue_.FrontGesture(), pending_gesture_queue_.FrontCallback(), pending_gesture_queue_.current_gesture_result()); pending_gesture_queue_.Pop(); - if (pending_gesture_queue_.IsEmpty()) + if (pending_gesture_queue_.IsEmpty()) { + dispatch_timer_.Stop(); return false; + } StartGesture(*pending_gesture_queue_.FrontGesture()); return true; } @@ -88,7 +110,8 @@ TRACE_EVENT_ASYNC_BEGIN0("input,benchmark", "SyntheticGestureController::running", &gesture); - RequestBeginFrame(); + if (!dispatch_timer_.IsRunning()) + RequestBeginFrame(); } void SyntheticGestureController::StopGesture(
diff --git a/content/browser/renderer_host/input/synthetic_gesture_controller.h b/content/browser/renderer_host/input/synthetic_gesture_controller.h index ed11a5ad..1762300 100644 --- a/content/browser/renderer_host/input/synthetic_gesture_controller.h +++ b/content/browser/renderer_host/input/synthetic_gesture_controller.h
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" +#include "base/timer/timer.h" #include "content/browser/renderer_host/input/synthetic_gesture.h" #include "content/common/content_export.h" #include "content/common/input/synthetic_gesture_params.h" @@ -54,8 +55,11 @@ bool DispatchNextEvent(base::TimeTicks = base::TimeTicks::Now()); private: + friend class SyntheticGestureControllerTestBase; + void RequestBeginFrame(); void OnBeginFrame(); + void StartTimer(); void StartGesture(const SyntheticGesture& gesture); void StopGesture(const SyntheticGesture& gesture, @@ -111,6 +115,7 @@ DISALLOW_COPY_AND_ASSIGN(GestureAndCallbackQueue); } pending_gesture_queue_; + base::RepeatingTimer dispatch_timer_; base::WeakPtrFactory<SyntheticGestureController> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(SyntheticGestureController);
diff --git a/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc b/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc index 3ebe916..4483b36 100644 --- a/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc +++ b/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc
@@ -11,6 +11,7 @@ #include <utility> #include "base/bind.h" +#include "base/test/scoped_task_environment.h" #include "base/time/time.h" #include "content/browser/renderer_host/input/synthetic_gesture.h" #include "content/browser/renderer_host/input/synthetic_gesture_target.h" @@ -675,6 +676,8 @@ DISALLOW_COPY_AND_ASSIGN(DummySyntheticGestureControllerDelegate); }; +} // namespace + class SyntheticGestureControllerTestBase { public: SyntheticGestureControllerTestBase() {} @@ -697,9 +700,15 @@ } void FlushInputUntilComplete() { + // Start and stop the timer explicitly here, since the test does not need to + // wait for begin-frame to start the timer. + controller_->dispatch_timer_.Start(FROM_HERE, + base::TimeDelta::FromSeconds(1), + base::Bind(&base::DoNothing)); do time_ += base::TimeDelta::FromMilliseconds(kFlushInputRateInMs); while (controller_->DispatchNextEvent(time_)); + controller_->dispatch_timer_.Stop(); } void OnSyntheticGestureCompleted(SyntheticGesture::Result result) { @@ -712,6 +721,7 @@ base::TimeDelta GetTotalTime() const { return time_ - start_time_; } + base::test::ScopedTaskEnvironment env_; MockSyntheticGestureTarget* target_; DummySyntheticGestureControllerDelegate delegate_; std::unique_ptr<SyntheticGestureController> controller_; @@ -845,9 +855,7 @@ QueueSyntheticGesture(std::move(gesture_1)); QueueSyntheticGesture(std::move(gesture_2)); - do { - time_ += base::TimeDelta::FromMilliseconds(kFlushInputRateInMs); - } while (controller_->DispatchNextEvent(time_)); + FlushInputUntilComplete(); EXPECT_EQ(2, num_success_); } @@ -1761,6 +1769,4 @@ pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(param, 1)); } -} // namespace - } // namespace content
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc index b6011c3..71546d6 100644 --- a/content/browser/renderer_host/media/media_stream_manager.cc +++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -33,7 +33,9 @@ #include "content/browser/renderer_host/media/media_devices_manager.h" #include "content/browser/renderer_host/media/media_stream_requester.h" #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" +#include "content/browser/renderer_host/media/service_video_capture_provider.h" #include "content/browser/renderer_host/media/video_capture_manager.h" +#include "content/browser/renderer_host/media/video_capture_provider_switcher.h" #include "content/browser/renderer_host/render_process_host_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" @@ -52,6 +54,7 @@ #include "media/base/media_switches.h" #include "media/capture/video/video_capture_device_factory.h" #include "media/capture/video/video_capture_system_impl.h" +#include "services/video_capture/public/cpp/constants.h" #include "url/gurl.h" #include "url/origin.h" @@ -424,6 +427,11 @@ media::VideoCaptureDeviceFactory::CreateFactory( BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))), std::move(device_task_runner)); + if (base::FeatureList::IsEnabled(video_capture::kMojoVideoCapture)) { + video_capture_provider = base::MakeUnique<VideoCaptureProviderSwitcher>( + base::MakeUnique<ServiceVideoCaptureProvider>(), + std::move(video_capture_provider)); + } } InitializeMaybeAsync(std::move(video_capture_provider));
diff --git a/content/browser/renderer_host/media/service_video_capture_device_launcher.cc b/content/browser/renderer_host/media/service_video_capture_device_launcher.cc index b74cf52..4c86c44 100644 --- a/content/browser/renderer_host/media/service_video_capture_device_launcher.cc +++ b/content/browser/renderer_host/media/service_video_capture_device_launcher.cc
@@ -88,9 +88,12 @@ return; } video_capture::mojom::DevicePtr device; + // We need the temporary variable |device_request| in order to guarantee that + // mojo::MakeRequest(&device) happens before base::Passed(&device). + auto device_request = mojo::MakeRequest(&device); (*device_factory_) ->CreateDevice( - device_id, mojo::MakeRequest(&device), + device_id, std::move(device_request), base::Bind( // Use of Unretained |this| is safe, because |done_cb| guarantees // that |this| stays alive.
diff --git a/content/browser/renderer_host/media/video_capture_browsertest.cc b/content/browser/renderer_host/media/video_capture_browsertest.cc index 19ce4c6..e4c37d1 100644 --- a/content/browser/renderer_host/media/video_capture_browsertest.cc +++ b/content/browser/renderer_host/media/video_capture_browsertest.cc
@@ -14,16 +14,22 @@ #include "media/base/bind_to_current_loop.h" #include "media/base/media_switches.h" #include "media/capture/video_capture_types.h" +#include "services/video_capture/public/cpp/constants.h" #include "testing/gmock/include/gmock/gmock.h" using testing::_; using testing::AtLeast; +using testing::Bool; +using testing::Combine; using testing::Invoke; using testing::InvokeWithoutArgs; using testing::Values; namespace content { +static const char kFakeDeviceFactoryConfigString[] = "device-count=3"; +static const float kFrameRateToRequest = 15.0f; + class MockVideoCaptureControllerEventHandler : public VideoCaptureControllerEventHandler { public: @@ -59,13 +65,33 @@ MOCK_METHOD2(Aborted, void(MediaStreamType, int)); }; +using DeviceIndex = size_t; +using Resolution = gfx::Size; +using ExerciseAcceleratedJpegDecoding = bool; +using UseMojoService = bool; + +// For converting the std::tuple<> used as test parameters back to something +// human-readable. struct TestParams { - std::string fake_device_factory_config_string; + TestParams() : device_index_to_use(0u) {} + TestParams(const std::tuple<DeviceIndex, + Resolution, + ExerciseAcceleratedJpegDecoding, + UseMojoService>& params) + : device_index_to_use(std::get<0>(params)), + resolution_to_use(std::get<1>(params)), + exercise_accelerated_jpeg_decoding(std::get<2>(params)), + use_mojo_service(std::get<3>(params)) {} + + media::VideoPixelFormat GetPixelFormatToUse() { + return (device_index_to_use == 1u) ? media::PIXEL_FORMAT_Y16 + : media::PIXEL_FORMAT_I420; + } + size_t device_index_to_use; - media::VideoPixelFormat pixel_format_to_use; gfx::Size resolution_to_use; - float frame_rate_to_use; bool exercise_accelerated_jpeg_decoding; + bool use_mojo_service; }; struct FrameInfo { @@ -75,10 +101,17 @@ base::TimeDelta timestamp; }; -class VideoCaptureBrowserTest - : public ContentBrowserTest, - public ::testing::WithParamInterface<TestParams> { +// Integration test that exercises the VideoCaptureManager instance running in +// the Browser process. +class VideoCaptureBrowserTest : public ContentBrowserTest, + public ::testing::WithParamInterface< + std::tuple<DeviceIndex, + Resolution, + ExerciseAcceleratedJpegDecoding, + UseMojoService>> { public: + VideoCaptureBrowserTest() { params_ = TestParams(GetParam()); } + void SetUpAndStartCaptureDeviceOnIOThread(base::Closure continuation) { video_capture_manager_ = media_stream_manager_->video_capture_manager(); ASSERT_TRUE(video_capture_manager_); @@ -90,7 +123,7 @@ void TearDownCaptureDeviceOnIOThread(base::Closure continuation, bool post_to_end_of_message_queue) { - // StopCaptureForClient must not be called synchronously from either the + // DisconnectClient() must not be called synchronously from either the // |done_cb| passed to StartCaptureForClient() nor any callback made to a // VideoCaptureControllerEventHandler. To satisfy this, we have to post our // invocation to the end of the IO message queue. @@ -114,17 +147,20 @@ protected: void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitchASCII( - switches::kUseFakeDeviceForMediaStream, - GetParam().fake_device_factory_config_string); + command_line->AppendSwitchASCII(switches::kUseFakeDeviceForMediaStream, + kFakeDeviceFactoryConfigString); command_line->AppendSwitch(switches::kUseFakeUIForMediaStream); - if (GetParam().exercise_accelerated_jpeg_decoding) { + if (params_.exercise_accelerated_jpeg_decoding) { base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kUseFakeJpegDecodeAccelerator); } else { base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kDisableAcceleratedMjpegDecode); } + if (params_.use_mojo_service) { + base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( + switches::kEnableFeatures, video_capture::kMojoVideoCapture.name); + } } // This cannot be part of an override of SetUp(), because at the time when @@ -139,16 +175,16 @@ void OnDeviceDescriptorsReceived( base::Closure continuation, const media::VideoCaptureDeviceDescriptors& descriptors) { - ASSERT_TRUE(GetParam().device_index_to_use < descriptors.size()); - const auto& descriptor = descriptors[GetParam().device_index_to_use]; + ASSERT_TRUE(params_.device_index_to_use < descriptors.size()); + const auto& descriptor = descriptors[params_.device_index_to_use]; MediaStreamDevice media_stream_device( MEDIA_DEVICE_VIDEO_CAPTURE, descriptor.device_id, descriptor.display_name, descriptor.facing); session_id_ = video_capture_manager_->Open(media_stream_device); media::VideoCaptureParams capture_params; capture_params.requested_format = media::VideoCaptureFormat( - GetParam().resolution_to_use, GetParam().frame_rate_to_use, - GetParam().pixel_format_to_use); + params_.resolution_to_use, kFrameRateToRequest, + params_.GetPixelFormatToUse()); video_capture_manager_->ConnectClient( session_id_, capture_params, stub_client_id_, &mock_controller_event_handler_, @@ -167,6 +203,7 @@ } protected: + TestParams params_; MediaStreamManager* media_stream_manager_ = nullptr; VideoCaptureManager* video_capture_manager_ = nullptr; int session_id_ = 0; @@ -177,6 +214,19 @@ }; IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest, StartAndImmediatelyStop) { +#if defined(OS_ANDROID) + // Mojo video capture is currently not supported on Android. + // TODO(chfremer): Remove this as soon as https://crbug.com/720500 is + // resolved. + if (params_.use_mojo_service) + return; +#endif + // Mojo video capture currently does not support accelerated jpeg decoding. + // TODO(chfremer): Remove this as soon as https://crbug.com/720604 is + // resolved. + if (params_.use_mojo_service && params_.exercise_accelerated_jpeg_decoding) + return; + SetUpRequiringBrowserMainLoopOnMainThread(); base::RunLoop run_loop; auto quit_run_loop_on_current_thread_cb = @@ -194,12 +244,32 @@ IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest, ReceiveFramesFromFakeCaptureDevice) { -// TODO(chfremer): This test case is flaky on Android. Find out cause of -// flakiness and then re-enable. See crbug.com/709039. #if defined(OS_ANDROID) - if (GetParam().exercise_accelerated_jpeg_decoding) + // TODO(chfremer): This test case is flaky on Android. Find out cause of + // flakiness and then re-enable. See https://crbug.com/709039. + if (params_.exercise_accelerated_jpeg_decoding) + return; + // Mojo video capture is currently not supported on Android + // TODO(chfremer): Remove this as soon as https://crbug.com/720500 is + // resolved. + if (params_.use_mojo_service) return; #endif + // Mojo video capture currently does not support accelerated jpeg decoding. + // TODO(chfremer): Remove this as soon as https://crbug.com/720604 is + // resolved. + if (params_.use_mojo_service && params_.exercise_accelerated_jpeg_decoding) + return; + // Only fake device with index 2 delivers MJPEG. + if (params_.exercise_accelerated_jpeg_decoding && + params_.device_index_to_use != 2) + return; + // There is an intermittent use-after-free in GpuChannelHost::Send() during + // Browser shutdown, which causes MSan tests to fail. + // TODO(chfremer): Remove this as soon as https://crbug.com/725271 is + // resolved. + if (params_.exercise_accelerated_jpeg_decoding) + return; SetUpRequiringBrowserMainLoopOnMainThread(); @@ -216,7 +286,7 @@ std::move(quit_run_loop_on_current_thread_cb), true); bool must_wait_for_gpu_decode_to_start = false; - if (GetParam().exercise_accelerated_jpeg_decoding) { + if (params_.exercise_accelerated_jpeg_decoding) { // Since the GPU jpeg decoder is created asynchronously while decoding // in software is ongoing, we have to keep pushing frames until a message // arrives that tells us that the GPU decoder is being used. Otherwise, @@ -266,9 +336,9 @@ base::TimeDelta previous_timestamp; bool first_frame = true; for (const auto& frame_info : received_frame_infos) { - EXPECT_EQ(GetParam().pixel_format_to_use, frame_info.pixel_format); + EXPECT_EQ(params_.GetPixelFormatToUse(), frame_info.pixel_format); EXPECT_EQ(media::PIXEL_STORAGE_CPU, frame_info.storage_type); - EXPECT_EQ(GetParam().resolution_to_use, frame_info.size); + EXPECT_EQ(params_.resolution_to_use, frame_info.size); // Timestamps are expected to increase if (!first_frame) EXPECT_GT(frame_info.timestamp, previous_timestamp); @@ -277,20 +347,12 @@ } } -INSTANTIATE_TEST_CASE_P( - , - VideoCaptureBrowserTest, - Values(TestParams{"fps=25,device-count=2", 0, media::PIXEL_FORMAT_I420, - gfx::Size(1280, 720), 25.0f, false}, - // The 2nd device outputs Y16 - TestParams{"fps=25,device-count=2", 1, media::PIXEL_FORMAT_Y16, - gfx::Size(1280, 720), 25.0f, false}, - TestParams{"fps=15,device-count=2", 1, media::PIXEL_FORMAT_Y16, - gfx::Size(640, 480), 15.0f, false}, - // The 3rd device outputs MJPEG, which is converted to I420. - TestParams{"fps=15,device-count=3", 2, media::PIXEL_FORMAT_I420, - gfx::Size(640, 480), 25.0f, false}, - TestParams{"fps=6,device-count=3", 2, media::PIXEL_FORMAT_I420, - gfx::Size(640, 480), 6.0f, true})); +INSTANTIATE_TEST_CASE_P(, + VideoCaptureBrowserTest, + Combine(Values(0, 1, 2), // DeviceIndex + Values(gfx::Size(640, 480), // Resolution + gfx::Size(1280, 720)), + Bool(), // ExerciseAcceleratedJpegDecoding + Bool())); // UseMojoService } // namespace content
diff --git a/content/browser/renderer_host/media/video_capture_provider.h b/content/browser/renderer_host/media/video_capture_provider.h index f0b72bb..10135040 100644 --- a/content/browser/renderer_host/media/video_capture_provider.h +++ b/content/browser/renderer_host/media/video_capture_provider.h
@@ -68,8 +68,13 @@ base::OnceClosure done_cb) = 0; }; +// Note: GetDeviceInfosAsync is only relevant for devices with +// MediaStreamType == MEDIA_DEVICE_VIDEO_CAPTURE, i.e. camera devices. class CONTENT_EXPORT VideoCaptureProvider { public: + using GetDeviceInfosCallback = + base::Callback<void(const std::vector<media::VideoCaptureDeviceInfo>&)>; + virtual ~VideoCaptureProvider() {} virtual void Uninitialize() = 0; @@ -77,9 +82,7 @@ // The passed-in |result_callback| must guarantee that the called // instance stays alive until |result_callback| is invoked. virtual void GetDeviceInfosAsync( - const base::Callback< - void(const std::vector<media::VideoCaptureDeviceInfo>&)>& - result_callback) = 0; + const GetDeviceInfosCallback& result_callback) = 0; virtual std::unique_ptr<VideoCaptureDeviceLauncher> CreateDeviceLauncher() = 0;
diff --git a/content/browser/renderer_host/media/video_capture_provider_switcher.cc b/content/browser/renderer_host/media/video_capture_provider_switcher.cc new file mode 100644 index 0000000..eaeb799 --- /dev/null +++ b/content/browser/renderer_host/media/video_capture_provider_switcher.cc
@@ -0,0 +1,88 @@ +// 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 "content/browser/renderer_host/media/video_capture_provider_switcher.h" + +#include "base/callback_helpers.h" + +namespace content { + +namespace { + +class VideoCaptureDeviceLauncherSwitcher : public VideoCaptureDeviceLauncher { + public: + VideoCaptureDeviceLauncherSwitcher( + std::unique_ptr<VideoCaptureDeviceLauncher> media_device_launcher, + std::unique_ptr<VideoCaptureDeviceLauncher> other_types_launcher) + : media_device_launcher_(std::move(media_device_launcher)), + other_types_launcher_(std::move(other_types_launcher)) {} + + ~VideoCaptureDeviceLauncherSwitcher() override {} + + void LaunchDeviceAsync(const std::string& device_id, + MediaStreamType stream_type, + const media::VideoCaptureParams& params, + base::WeakPtr<media::VideoFrameReceiver> receiver, + Callbacks* callbacks, + base::OnceClosure done_cb) override { + if (stream_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) { + // Use of Unretained() is safe, because |media_device_launcher_| is owned + // by |this|. + abort_launch_cb_ = + base::Bind(&VideoCaptureDeviceLauncher::AbortLaunch, + base::Unretained(media_device_launcher_.get())); + return media_device_launcher_->LaunchDeviceAsync( + device_id, stream_type, params, std::move(receiver), callbacks, + std::move(done_cb)); + } + // Use of Unretained() is safe, because |other_types_launcher_| is owned by + // |this|. + abort_launch_cb_ = + base::Bind(&VideoCaptureDeviceLauncher::AbortLaunch, + base::Unretained(other_types_launcher_.get())); + return other_types_launcher_->LaunchDeviceAsync( + device_id, stream_type, params, std::move(receiver), callbacks, + std::move(done_cb)); + } + + void AbortLaunch() override { + if (abort_launch_cb_.is_null()) + return; + base::ResetAndReturn(&abort_launch_cb_).Run(); + } + + private: + const std::unique_ptr<VideoCaptureDeviceLauncher> media_device_launcher_; + const std::unique_ptr<VideoCaptureDeviceLauncher> other_types_launcher_; + base::OnceClosure abort_launch_cb_; +}; + +} // anonymous namespace + +VideoCaptureProviderSwitcher::VideoCaptureProviderSwitcher( + std::unique_ptr<VideoCaptureProvider> media_device_capture_provider, + std::unique_ptr<VideoCaptureProvider> other_types_capture_provider) + : media_device_capture_provider_(std::move(media_device_capture_provider)), + other_types_capture_provider_(std::move(other_types_capture_provider)) {} + +VideoCaptureProviderSwitcher::~VideoCaptureProviderSwitcher() = default; + +void VideoCaptureProviderSwitcher::Uninitialize() { + media_device_capture_provider_->Uninitialize(); + other_types_capture_provider_->Uninitialize(); +} + +void VideoCaptureProviderSwitcher::GetDeviceInfosAsync( + const GetDeviceInfosCallback& result_callback) { + media_device_capture_provider_->GetDeviceInfosAsync(result_callback); +} + +std::unique_ptr<VideoCaptureDeviceLauncher> +VideoCaptureProviderSwitcher::CreateDeviceLauncher() { + return base::MakeUnique<VideoCaptureDeviceLauncherSwitcher>( + media_device_capture_provider_->CreateDeviceLauncher(), + other_types_capture_provider_->CreateDeviceLauncher()); +} + +} // namespace content
diff --git a/content/browser/renderer_host/media/video_capture_provider_switcher.h b/content/browser/renderer_host/media/video_capture_provider_switcher.h new file mode 100644 index 0000000..c3207597 --- /dev/null +++ b/content/browser/renderer_host/media/video_capture_provider_switcher.h
@@ -0,0 +1,38 @@ +// 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 CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_PROVIDER_SWITCHER_H_ +#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_PROVIDER_SWITCHER_H_ + +#include "content/browser/renderer_host/media/video_capture_provider.h" +#include "services/video_capture/public/interfaces/device_factory.mojom.h" + +namespace content { + +// Routes requests for media devices, e.g. cameras, to +// |media_device_capture_provider| and for all other types of capture, e.g. +// screen or tab capture, to the given |other_types_capture_provider|. +class CONTENT_EXPORT VideoCaptureProviderSwitcher + : public VideoCaptureProvider { + public: + VideoCaptureProviderSwitcher( + std::unique_ptr<VideoCaptureProvider> media_device_capture_provider, + std::unique_ptr<VideoCaptureProvider> other_types_capture_provider); + ~VideoCaptureProviderSwitcher() override; + + void Uninitialize() override; + + void GetDeviceInfosAsync( + const GetDeviceInfosCallback& result_callback) override; + + std::unique_ptr<VideoCaptureDeviceLauncher> CreateDeviceLauncher() override; + + private: + const std::unique_ptr<VideoCaptureProvider> media_device_capture_provider_; + const std::unique_ptr<VideoCaptureProvider> other_types_capture_provider_; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_PROVIDER_SWITCHER_H_
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index 73b9c15..466629c 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -290,6 +290,8 @@ void OnSurfaceDamaged(const cc::SurfaceId& id, bool* changed) override { *changed = true; } + + void OnSurfaceDiscarded(const cc::SurfaceId& id) override {} }; class FakeFrameSubscriber : public RenderWidgetHostViewFrameSubscriber {
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc index 19a1c5d..cc351b63 100644 --- a/content/browser/service_manager/service_manager_context.cc +++ b/content/browser/service_manager/service_manager_context.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/command_line.h" +#include "base/feature_list.h" #include "base/json/json_reader.h" #include "base/lazy_instance.h" #include "base/macros.h" @@ -52,6 +53,8 @@ #include "services/service_manager/runner/common/client_util.h" #include "services/service_manager/service_manager.h" #include "services/shape_detection/public/interfaces/constants.mojom.h" +#include "services/video_capture/public/cpp/constants.h" +#include "services/video_capture/public/interfaces/constants.mojom.h" #if defined(OS_ANDROID) #include "base/android/jni_android.h" @@ -364,6 +367,11 @@ std::make_pair(content::mojom::kNetworkServiceName, base::ASCIIToUTF16("Network Service"))); } + if (base::FeatureList::IsEnabled(video_capture::kMojoVideoCapture)) { + unsandboxed_services.insert( + std::make_pair(video_capture::mojom::kServiceName, + base::ASCIIToUTF16("Video Capture Service"))); + } for (const auto& service : unsandboxed_services) { packaged_services_connection_->AddServiceRequestHandler(
diff --git a/content/browser/utility_process_host_impl.cc b/content/browser/utility_process_host_impl.cc index e8a49ca..baafcde 100644 --- a/content/browser/utility_process_host_impl.cc +++ b/content/browser/utility_process_host_impl.cc
@@ -39,6 +39,7 @@ #include "content/public/common/sandboxed_process_launcher_delegate.h" #include "content/public/common/service_manager_connection.h" #include "content/public/common/service_names.mojom.h" +#include "media/base/media_switches.h" #include "mojo/edk/embedder/embedder.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "ui/base/ui_base_switches.h" @@ -312,6 +313,8 @@ #if defined(OS_MACOSX) switches::kEnableSandboxLogging, #endif + switches::kUseFakeDeviceForMediaStream, + switches::kUseFileForFakeVideoCapture, }; cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames, arraysize(kSwitchNames));
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java index 318f220..8799488 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
@@ -819,6 +819,7 @@ @Test @SmallTest + @DisabledTest(message = "crbug.com/725532") @Feature({"TextInput", "Main"}) public void testFinishComposingText() throws Throwable { mRule.focusElementAndWaitForStateUpdate("textarea"); @@ -1155,6 +1156,7 @@ @Test @SmallTest + @DisabledTest(message = "crbug.com/725532") @Feature({"TextInput", "Main"}) public void testNavigateTextWithDpadKeyCodes() throws Throwable { mRule.focusElementAndWaitForStateUpdate("textarea");
diff --git a/content/public/app/BUILD.gn b/content/public/app/BUILD.gn index c6a5990..9c9aba4 100644 --- a/content/public/app/BUILD.gn +++ b/content/public/app/BUILD.gn
@@ -187,6 +187,7 @@ "//services/device:manifest", "//services/resource_coordinator:manifest", "//services/shape_detection:manifest", + "//services/video_capture:manifest", ] }
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json index 6f051c5..198a8e38 100644 --- a/content/public/app/mojo/content_browser_manifest.json +++ b/content/public/app/mojo/content_browser_manifest.json
@@ -84,7 +84,8 @@ "text_detection" ], - "resource_coordinator": [ "coordination_unit" ] + "resource_coordinator": [ "coordination_unit" ], + "video_capture": [ "capture" ] } }, "navigation:frame": {
diff --git a/content/public/browser/download_manager_delegate.h b/content/public/browser/download_manager_delegate.h index 8a26132..dc33ded 100644 --- a/content/public/browser/download_manager_delegate.h +++ b/content/public/browser/download_manager_delegate.h
@@ -64,7 +64,7 @@ using DownloadOpenDelayedCallback = base::Callback<void(bool)>; // Called with the result of CheckForFileExistence(). -using CheckForFileExistenceCallback = base::Callback<void(bool result)>; +using CheckForFileExistenceCallback = base::OnceCallback<void(bool result)>; using DownloadIdCallback = base::Callback<void(uint32_t)>; @@ -152,9 +152,8 @@ virtual void ShowDownloadInShell(DownloadItem* download) {} // Checks whether a downloaded file still exists. - virtual void CheckForFileExistence( - DownloadItem* download, - const CheckForFileExistenceCallback& callback) {} + virtual void CheckForFileExistence(DownloadItem* download, + CheckForFileExistenceCallback callback) {} // Return a GUID string used for identifying the application to the system AV // function for scanning downloaded files. If no GUID is provided or if the
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 10426faf..58726bd 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -785,6 +785,7 @@ "//services/service_manager/public/cpp", "//services/ui/gpu/interfaces", "//services/ui/public/cpp/gpu", + "//services/video_capture/public/cpp", "//storage/browser", "//testing/gmock", "//testing/gtest",
diff --git a/content/utility/BUILD.gn b/content/utility/BUILD.gn index 0de44b4..c5d9450 100644 --- a/content/utility/BUILD.gn +++ b/content/utility/BUILD.gn
@@ -46,6 +46,8 @@ "//services/service_manager/public/interfaces", "//services/shape_detection:lib", "//services/shape_detection/public/interfaces", + "//services/video_capture:lib", + "//services/video_capture/public/interfaces:constants", "//third_party/WebKit/public:blink_headers", "//third_party/WebKit/public:mojo_bindings", "//url",
diff --git a/content/utility/DEPS b/content/utility/DEPS index 95eef3e..1e371033 100644 --- a/content/utility/DEPS +++ b/content/utility/DEPS
@@ -6,5 +6,6 @@ "+services/data_decoder", "+services/service_manager", "+services/shape_detection", + "+services/video_capture", "+sandbox/win/src", ]
diff --git a/content/utility/utility_service_factory.cc b/content/utility/utility_service_factory.cc index 2420c557..2f95ab6 100644 --- a/content/utility/utility_service_factory.cc +++ b/content/utility/utility_service_factory.cc
@@ -19,11 +19,21 @@ #include "services/data_decoder/public/interfaces/constants.mojom.h" #include "services/shape_detection/public/interfaces/constants.mojom.h" #include "services/shape_detection/shape_detection_service.h" +#include "services/video_capture/public/interfaces/constants.mojom.h" +#include "services/video_capture/service_impl.h" #if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_UTILITY_PROCESS) #include "media/mojo/services/media_service_factory.h" // nogncheck #endif +namespace { + +std::unique_ptr<service_manager::Service> CreateVideoCaptureService() { + return base::MakeUnique<video_capture::ServiceImpl>(); +} + +} // anonymous namespace + namespace content { namespace { @@ -43,6 +53,11 @@ void UtilityServiceFactory::RegisterServices(ServiceMap* services) { GetContentClient()->utility()->RegisterServices(services); + ServiceInfo video_capture_info; + video_capture_info.factory = base::Bind(&CreateVideoCaptureService); + services->insert( + std::make_pair(video_capture::mojom::kServiceName, video_capture_info)); + #if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_UTILITY_PROCESS) ServiceInfo info; info.factory = base::Bind(&media::CreateMediaService);
diff --git a/device/bluetooth/bluetooth_adapter_mac.mm b/device/bluetooth/bluetooth_adapter_mac.mm index c289ae4..e7ffdbf 100644 --- a/device/bluetooth/bluetooth_adapter_mac.mm +++ b/device/bluetooth/bluetooth_adapter_mac.mm
@@ -587,10 +587,27 @@ } } -// TODO(krstnmnlsn): Implement. crbug.com/511025 +// TODO(crbug.com/511025): Handle state < CBCentralManagerStatePoweredOff. void BluetoothAdapterMac::LowEnergyCentralManagerUpdatedState() { VLOG(1) << "Central manager state updated: " << [low_energy_central_manager_ state]; + // A state with a value lower than CBCentralManagerStatePoweredOn implies that + // scanning has stopped and that any connected peripherals have been + // disconnected. Call DidDisconnectPeripheral manually to update the devices' + // states since macOS doesn't call it. + // See + // https://developer.apple.com/reference/corebluetooth/cbcentralmanagerdelegate/1518888-centralmanagerdidupdatestate?language=objc + if ([low_energy_central_manager_ state] < CBCentralManagerStatePoweredOn) { + VLOG(1) + << "Central no longer powered on. Notifying of device disconnection."; + for (BluetoothDevice* device : GetDevices()) { + BluetoothLowEnergyDeviceMac* device_mac = + static_cast<BluetoothLowEnergyDeviceMac*>(device); + if (device_mac->IsGattConnected()) { + device_mac->DidDisconnectPeripheral(nullptr); + } + } + } } void BluetoothAdapterMac::AddPairedDevices() {
diff --git a/device/bluetooth/bluetooth_adapter_unittest.cc b/device/bluetooth/bluetooth_adapter_unittest.cc index 0e60fd9..264cc4c 100644 --- a/device/bluetooth/bluetooth_adapter_unittest.cc +++ b/device/bluetooth/bluetooth_adapter_unittest.cc
@@ -741,6 +741,36 @@ } #endif // defined(OS_ANDROID) +#if defined(OS_MACOSX) +// TODO(crbug.com/725270): Enable on relevant platforms. +TEST_F(BluetoothTest, TurnOffAdapterWithConnectedDevice) { + if (!PlatformSupportsLowEnergy()) { + LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; + return; + } + + InitWithFakeAdapter(); + TestBluetoothAdapterObserver observer(adapter_); + + StartLowEnergyDiscoverySession(); + BluetoothDevice* device = SimulateLowEnergyDevice(3); + + device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED), + GetConnectErrorCallback(Call::NOT_EXPECTED)); + SimulateGattConnection(device); + base::RunLoop().RunUntilIdle(); + + ASSERT_TRUE(device->IsGattConnected()); + + ResetEventCounts(); + SimulateAdapterPoweredOff(); + + EXPECT_EQ(2, observer.device_changed_count()); + EXPECT_FALSE(device->IsConnected()); + EXPECT_FALSE(device->IsGattConnected()); +} +#endif // defined(OS_MACOSX) + #if defined(OS_CHROMEOS) || defined(OS_LINUX) TEST_F(BluetoothTest, RegisterLocalGattServices) { InitWithFakeAdapter();
diff --git a/device/bluetooth/test/bluetooth_test.h b/device/bluetooth/test/bluetooth_test.h index 0888acb..115d73b 100644 --- a/device/bluetooth/test/bluetooth_test.h +++ b/device/bluetooth/test/bluetooth_test.h
@@ -142,6 +142,9 @@ // devices. Returns false if the current platform always has permission. virtual bool DenyPermission(); + // Simulates the Adapter being switched off. + virtual void SimulateAdapterPoweredOff() {} + // Create a fake Low Energy device and discover it. // |device_ordinal| with the same device address stands for the same fake // device with different properties.
diff --git a/device/bluetooth/test/bluetooth_test_mac.h b/device/bluetooth/test/bluetooth_test_mac.h index 2b97132d..5784ce4 100644 --- a/device/bluetooth/test/bluetooth_test_mac.h +++ b/device/bluetooth/test/bluetooth_test_mac.h
@@ -42,6 +42,7 @@ void InitWithoutDefaultAdapter() override; void InitWithFakeAdapter() override; void ResetEventCounts() override; + void SimulateAdapterPoweredOff() override; BluetoothDevice* SimulateLowEnergyDevice(int device_ordinal) override; void SimulateConnectedLowEnergyDevice( ConnectedDeviceType device_ordinal) override;
diff --git a/device/bluetooth/test/bluetooth_test_mac.mm b/device/bluetooth/test/bluetooth_test_mac.mm index 8bd2b5e0f..3c5e8000 100644 --- a/device/bluetooth/test/bluetooth_test_mac.mm +++ b/device/bluetooth/test/bluetooth_test_mac.mm
@@ -140,6 +140,20 @@ last_notify_value_ = false; } +void BluetoothTestMac::SimulateAdapterPoweredOff() { + [mock_central_manager_->get() setState:CBCentralManagerStatePoweredOff]; + + for (BluetoothDevice* device : adapter_->GetDevices()) { + MockCBPeripheral* peripheral_mock = GetMockCBPeripheral(device); + [peripheral_mock setState:CBPeripheralStateDisconnected]; + } + + BluetoothLowEnergyCentralManagerDelegate* central_manager_delegate = + adapter_mac_->low_energy_central_manager_delegate_; + CBCentralManager* central_manager = adapter_mac_->low_energy_central_manager_; + [central_manager_delegate centralManagerDidUpdateState:central_manager]; +} + BluetoothDevice* BluetoothTestMac::SimulateLowEnergyDevice(int device_ordinal) { TestBluetoothAdapterObserver observer(adapter_); CBCentralManager* central_manager = adapter_mac_->low_energy_central_manager_;
diff --git a/extensions/browser/guest_view/web_view/web_view_apitest.cc b/extensions/browser/guest_view/web_view/web_view_apitest.cc index d9815eb..eac3214 100644 --- a/extensions/browser/guest_view/web_view/web_view_apitest.cc +++ b/extensions/browser/guest_view/web_view/web_view_apitest.cc
@@ -50,9 +50,7 @@ const char kRedirectResponsePath[] = "/server-redirect"; const char kRedirectResponseFullPath[] = "/guest_redirect.html"; const char kUserAgentRedirectResponsePath[] = "/detect-user-agent"; -const char kTestDataDirectory[] = "testDataDirectory"; const char kTestServerPort[] = "testServer.port"; -const char kTestWebSocketPort[] = "testWebSocketPort"; // Handles |request| by serving a redirect response if the |User-Agent| is // foobar. @@ -143,9 +141,6 @@ PathService::Get(DIR_TEST_DATA, &test_data_dir); test_data_dir = test_data_dir.AppendASCII(app_location.c_str()); - test_config_.SetString(kTestDataDirectory, - net::FilePathToFileURL(test_data_dir).spec()); - const Extension* extension = extension_system_->LoadApp(test_data_dir); ASSERT_TRUE(extension); extension_system_->LaunchApp(extension->id()); @@ -186,8 +181,6 @@ AppShellTest::SetUpOnMainThread(); TestGetConfigFunction::set_test_config_state(&test_config_); - base::FilePath test_data_dir; - test_config_.SetInteger(kTestWebSocketPort, 0); } void WebViewAPITest::StartTestServer(const std::string& app_location) {
diff --git a/extensions/common/api/test.json b/extensions/common/api/test.json index bd4402c..97dff284 100644 --- a/extensions/common/api/test.json +++ b/extensions/common/api/test.json
@@ -51,10 +51,12 @@ }, "testDataDirectory": { "type": "string", + "optional": true, "description": "file:/// URL for the API test data directory." }, "testWebSocketPort": { "type": "integer", + "optional": true, "description": "The port on which the test WebSocket server is listening.", "minimum": 0, "maximum": 65535
diff --git a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.cc b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.cc index e0609fe..bfc489b 100644 --- a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.cc +++ b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.cc
@@ -15,14 +15,12 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/time/default_clock.h" #include "base/values.h" -#include "components/bookmarks/browser/bookmark_model.h" #include "components/image_fetcher/core/image_decoder.h" #include "components/image_fetcher/core/image_fetcher.h" #include "components/image_fetcher/core/image_fetcher_impl.h" #include "components/image_fetcher/ios/ios_image_decoder_impl.h" #include "components/keyed_service/core/service_access_type.h" #include "components/keyed_service/ios/browser_state_dependency_manager.h" -#include "components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h" #include "components/ntp_snippets/category_rankers/category_ranker.h" #include "components/ntp_snippets/category_rankers/click_based_category_ranker.h" #include "components/ntp_snippets/category_rankers/constant_category_ranker.h" @@ -42,7 +40,6 @@ #include "components/version_info/version_info.h" #include "google_apis/google_api_keys.h" #include "ios/chrome/browser/application_context.h" -#include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h" #include "ios/chrome/browser/history/history_service_factory.h" @@ -54,12 +51,9 @@ #include "ios/web/public/web_thread.h" #include "net/url_request/url_request_context_getter.h" -using bookmarks::BookmarkModel; using history::HistoryService; using image_fetcher::CreateIOSImageDecoder; using image_fetcher::ImageFetcherImpl; -using ios::BookmarkModelFactory; -using ntp_snippets::BookmarkSuggestionsProvider; using ntp_snippets::ContentSuggestionsService; using ntp_snippets::GetFetchEndpoint; using ntp_snippets::PersistentScheduler; @@ -108,7 +102,6 @@ : BrowserStateKeyedServiceFactory( "ContentSuggestionsService", BrowserStateDependencyManager::GetInstance()) { - DependsOn(BookmarkModelFactory::GetInstance()); DependsOn(ios::HistoryServiceFactory::GetInstance()); DependsOn(IOSChromeLargeIconServiceFactory::GetInstance()); DependsOn(OAuth2TokenServiceFactory::GetInstance());
diff --git a/ios/chrome/browser/payments/BUILD.gn b/ios/chrome/browser/payments/BUILD.gn index 836535a..b0521bc 100644 --- a/ios/chrome/browser/payments/BUILD.gn +++ b/ios/chrome/browser/payments/BUILD.gn
@@ -50,10 +50,13 @@ sources = [ "payment_request_test_util.h", "payment_request_test_util.mm", + "test_payment_request.h", + "test_payment_request.mm", ] deps = [ ":payments", "//base", + "//components/autofill/core/browser", "//components/payments/core", "//ios/web", ]
diff --git a/ios/chrome/browser/payments/payment_request.h b/ios/chrome/browser/payments/payment_request.h index ca271f36..19f8dca 100644 --- a/ios/chrome/browser/payments/payment_request.h +++ b/ios/chrome/browser/payments/payment_request.h
@@ -70,7 +70,7 @@ payments::CurrencyFormatter* GetOrCreateCurrencyFormatter(); // Returns the autofill::RegionDataLoader instance for this PaymentRequest. - autofill::RegionDataLoader* GetRegionDataLoader(); + virtual autofill::RegionDataLoader* GetRegionDataLoader(); // Returns the available autofill profiles for this user to be used as // shipping profiles.
diff --git a/ios/chrome/browser/payments/payment_request.mm b/ios/chrome/browser/payments/payment_request.mm index da4ec76..5e9683f 100644 --- a/ios/chrome/browser/payments/payment_request.mm +++ b/ios/chrome/browser/payments/payment_request.mm
@@ -128,29 +128,29 @@ return; profile_cache_.reserve(profiles_to_suggest.size()); + + std::vector<autofill::AutofillProfile*> raw_profiles_for_filtering; + raw_profiles_for_filtering.reserve(profiles_to_suggest.size()); + for (const auto* profile : profiles_to_suggest) { profile_cache_.push_back(*profile); - shipping_profiles_.push_back(&profile_cache_.back()); - } - - // If the merchant provided a shipping option, select a suitable default - // shipping profile. We pick the profile that is most complete, going down - // the list in Frecency order. - // TODO(crbug.com/719652): Have a proper ordering of shipping addresses by - // completeness. - if (selected_shipping_option_) { - selected_shipping_profile_ = shipping_profiles_[0]; - for (autofill::AutofillProfile* profile : shipping_profiles_) { - if (profile_comparator_.IsShippingComplete(profile)) { - selected_shipping_profile_ = profile; - break; - } - } + raw_profiles_for_filtering.push_back(&profile_cache_.back()); } // Contact profiles are deduped and ordered in completeness. contact_profiles_ = - profile_comparator_.FilterProfilesForContact(shipping_profiles_); + profile_comparator_.FilterProfilesForContact(raw_profiles_for_filtering); + + // Shipping profiles are ordered by completeness. + shipping_profiles_ = + profile_comparator_.FilterProfilesForShipping(raw_profiles_for_filtering); + + // If the merchant provided a shipping option, and the highest-ranking + // shipping profile is usable, select it. + if (selected_shipping_option_ && !shipping_profiles_.empty() && + profile_comparator_.IsShippingComplete(shipping_profiles_[0])) { + selected_shipping_profile_ = shipping_profiles_[0]; + } // If the highest-ranking contact profile is usable, select it. Otherwise, // select none.
diff --git a/ios/chrome/browser/payments/test_payment_request.h b/ios/chrome/browser/payments/test_payment_request.h new file mode 100644 index 0000000..025d38eb --- /dev/null +++ b/ios/chrome/browser/payments/test_payment_request.h
@@ -0,0 +1,44 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_PAYMENTS_TEST_PAYMENT_REQUEST_H_ +#define IOS_CHROME_BROWSER_PAYMENTS_TEST_PAYMENT_REQUEST_H_ + +#include "base/macros.h" +#include "ios/chrome/browser/payments/payment_request.h" + +namespace autofill { +class PersonalDataManager; +class RegionDataLoader; +} // namespace autofill + +namespace web { +class PaymentRequest; +} // namespace web + +// PaymentRequest for use in tests. +class TestPaymentRequest : public PaymentRequest { + public: + // |personal_data_manager| should not be null and should outlive this object. + TestPaymentRequest(const web::PaymentRequest& web_payment_request, + autofill::PersonalDataManager* personal_data_manager) + : PaymentRequest(web_payment_request, personal_data_manager) {} + + ~TestPaymentRequest() override{}; + + void SetRegionDataLoader(autofill::RegionDataLoader* region_data_loader) { + region_data_loader_ = region_data_loader; + } + + // PaymentRequest + autofill::RegionDataLoader* GetRegionDataLoader() override; + + private: + // Not owned and must outlive this object. + autofill::RegionDataLoader* region_data_loader_; + + DISALLOW_COPY_AND_ASSIGN(TestPaymentRequest); +}; + +#endif // IOS_CHROME_BROWSER_PAYMENTS_TEST_PAYMENT_REQUEST_H_
diff --git a/ios/chrome/browser/payments/test_payment_request.mm b/ios/chrome/browser/payments/test_payment_request.mm new file mode 100644 index 0000000..37f20d9 --- /dev/null +++ b/ios/chrome/browser/payments/test_payment_request.mm
@@ -0,0 +1,17 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/payments/test_payment_request.h" + +#include "components/autofill/core/browser/personal_data_manager.h" +#include "components/autofill/core/browser/region_data_loader.h" +#include "ios/web/public/payments/payment_request.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +autofill::RegionDataLoader* TestPaymentRequest::GetRegionDataLoader() { + return region_data_loader_; +}
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm index 568823b..5a50138d 100644 --- a/ios/chrome/browser/prefs/browser_prefs.mm +++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -13,7 +13,6 @@ #import "components/handoff/handoff_manager.h" #include "components/metrics/metrics_pref_names.h" #include "components/network_time/network_time_tracker.h" -#include "components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h" #include "components/ntp_snippets/category_rankers/click_based_category_ranker.h" #include "components/ntp_snippets/content_suggestions_service.h" #include "components/ntp_snippets/remote/remote_suggestions_provider_impl.h" @@ -97,7 +96,6 @@ gcm::GCMChannelStatusSyncer::RegisterProfilePrefs(registry); HostContentSettingsMap::RegisterProfilePrefs(registry); HttpServerPropertiesManagerFactory::RegisterProfilePrefs(registry); - ntp_snippets::BookmarkSuggestionsProvider::RegisterProfilePrefs(registry); ntp_snippets::ClickBasedCategoryRanker::RegisterProfilePrefs(registry); ntp_snippets::ContentSuggestionsService::RegisterProfilePrefs(registry); ntp_snippets::RemoteSuggestionsProviderImpl::RegisterProfilePrefs(registry);
diff --git a/ios/chrome/browser/tabs/BUILD.gn b/ios/chrome/browser/tabs/BUILD.gn index bc1da78..51a1278 100644 --- a/ios/chrome/browser/tabs/BUILD.gn +++ b/ios/chrome/browser/tabs/BUILD.gn
@@ -31,6 +31,7 @@ "//ui/base", ] libs = [ "UIKit.framework" ] + configs += [ "//build/config/compiler:enable_arc" ] } source_set("tabs_internal") {
diff --git a/ios/chrome/browser/tabs/tab_unittest.mm b/ios/chrome/browser/tabs/tab_unittest.mm index c63a9d7..69a4d76f 100644 --- a/ios/chrome/browser/tabs/tab_unittest.mm +++ b/ios/chrome/browser/tabs/tab_unittest.mm
@@ -234,7 +234,8 @@ [tab_ webWillAddPendingURL:userUrl transition:ui::PAGE_TRANSITION_TYPED]; std::unique_ptr<web::NavigationContext> context1 = web::NavigationContextImpl::CreateNavigationContext( - web_state_impl_.get(), userUrl); + web_state_impl_.get(), userUrl, + ui::PageTransition::PAGE_TRANSITION_TYPED); web_state_impl_->OnNavigationStarted(context1.get()); [tab_ webWillAddPendingURL:redirectUrl transition:ui::PAGE_TRANSITION_CLIENT_REDIRECT]; @@ -247,7 +248,8 @@ std::unique_ptr<web::NavigationContext> context2 = web::NavigationContextImpl::CreateNavigationContext( - web_state_impl_.get(), redirectUrl); + web_state_impl_.get(), redirectUrl, + ui::PageTransition::PAGE_TRANSITION_TYPED); web_state_impl_->OnNavigationStarted(context2.get()); [[tab_ navigationManagerImpl]->GetSessionController() commitPendingItem]; web_state_impl_->UpdateHttpResponseHeaders(redirectUrl);
diff --git a/ios/chrome/browser/ui/autofill/autofill_ui_type.h b/ios/chrome/browser/ui/autofill/autofill_ui_type.h index 82a0de3..9a408bb 100644 --- a/ios/chrome/browser/ui/autofill/autofill_ui_type.h +++ b/ios/chrome/browser/ui/autofill/autofill_ui_type.h
@@ -17,11 +17,14 @@ AutofillUITypeCreditCardBillingAddress, AutofillUITypeProfileFullName, AutofillUITypeProfileCompanyName, + AutofillUITypeProfileHomeAddressStreet, AutofillUITypeProfileHomeAddressLine1, AutofillUITypeProfileHomeAddressLine2, + AutofillUITypeProfileHomeAddressDependentLocality, AutofillUITypeProfileHomeAddressCity, AutofillUITypeProfileHomeAddressState, AutofillUITypeProfileHomeAddressZip, + AutofillUITypeProfileHomeAddressSortingCode, AutofillUITypeProfileHomeAddressCountry, AutofillUITypeProfileHomePhoneWholeNumber, AutofillUITypeProfileEmailAddress,
diff --git a/ios/chrome/browser/ui/autofill/autofill_ui_type_util.mm b/ios/chrome/browser/ui/autofill/autofill_ui_type_util.mm index e9e0ed6..db2192e 100644 --- a/ios/chrome/browser/ui/autofill/autofill_ui_type_util.mm +++ b/ios/chrome/browser/ui/autofill/autofill_ui_type_util.mm
@@ -26,16 +26,22 @@ return AutofillUITypeProfileFullName; case autofill::COMPANY_NAME: return AutofillUITypeProfileCompanyName; + case autofill::ADDRESS_HOME_STREET_ADDRESS: + return AutofillUITypeProfileHomeAddressStreet; case autofill::ADDRESS_HOME_LINE1: return AutofillUITypeProfileHomeAddressLine1; case autofill::ADDRESS_HOME_LINE2: return AutofillUITypeProfileHomeAddressLine2; + case autofill::ADDRESS_HOME_DEPENDENT_LOCALITY: + return AutofillUITypeProfileHomeAddressDependentLocality; case autofill::ADDRESS_HOME_CITY: return AutofillUITypeProfileHomeAddressCity; case autofill::ADDRESS_HOME_STATE: return AutofillUITypeProfileHomeAddressState; case autofill::ADDRESS_HOME_ZIP: return AutofillUITypeProfileHomeAddressZip; + case autofill::ADDRESS_HOME_SORTING_CODE: + return AutofillUITypeProfileHomeAddressSortingCode; case autofill::ADDRESS_HOME_COUNTRY: return AutofillUITypeProfileHomeAddressCountry; case autofill::PHONE_HOME_WHOLE_NUMBER: @@ -64,16 +70,22 @@ return autofill::NAME_FULL; case AutofillUITypeProfileCompanyName: return autofill::COMPANY_NAME; + case AutofillUITypeProfileHomeAddressStreet: + return autofill::ADDRESS_HOME_STREET_ADDRESS; case AutofillUITypeProfileHomeAddressLine1: return autofill::ADDRESS_HOME_LINE1; case AutofillUITypeProfileHomeAddressLine2: return autofill::ADDRESS_HOME_LINE2; + case AutofillUITypeProfileHomeAddressDependentLocality: + return autofill::ADDRESS_HOME_DEPENDENT_LOCALITY; case AutofillUITypeProfileHomeAddressCity: return autofill::ADDRESS_HOME_CITY; case AutofillUITypeProfileHomeAddressState: return autofill::ADDRESS_HOME_STATE; case AutofillUITypeProfileHomeAddressZip: return autofill::ADDRESS_HOME_ZIP; + case AutofillUITypeProfileHomeAddressSortingCode: + return autofill::ADDRESS_BILLING_SORTING_CODE; case AutofillUITypeProfileHomeAddressCountry: return autofill::ADDRESS_HOME_COUNTRY; case AutofillUITypeProfileHomePhoneWholeNumber:
diff --git a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h b/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h index 31c3eab5..7729ca2 100644 --- a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h +++ b/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h
@@ -24,6 +24,9 @@ // An image corresponding to the type of the credit card, if any. @property(nonatomic, copy) UIImage* cardTypeIcon; +// The inputView for the text field, if any. +@property(nonatomic, strong) UIPickerView* inputView; + // The field type this item is describing. @property(nonatomic, assign) AutofillUIType autofillUIType;
diff --git a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.mm b/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.mm index f4d9655e..406a69e 100644 --- a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.mm +++ b/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.mm
@@ -29,6 +29,7 @@ @synthesize textFieldName = _textFieldName; @synthesize textFieldValue = _textFieldValue; @synthesize cardTypeIcon = _cardTypeIcon; +@synthesize inputView = _inputView; @synthesize textFieldEnabled = _textFieldEnabled; @synthesize autofillUIType = _autofillUIType; @synthesize required = _required; @@ -60,6 +61,7 @@ [cell.textField addTarget:self action:@selector(textFieldChanged:) forControlEvents:UIControlEventEditingChanged]; + cell.textField.inputView = self.inputView; cell.cardTypeIconView.image = self.cardTypeIcon; }
diff --git a/ios/chrome/browser/ui/payments/BUILD.gn b/ios/chrome/browser/ui/payments/BUILD.gn index d06f1e8..c1fa194 100644 --- a/ios/chrome/browser/ui/payments/BUILD.gn +++ b/ios/chrome/browser/ui/payments/BUILD.gn
@@ -82,6 +82,7 @@ "//ios/third_party/material_roboto_font_loader_ios", "//ios/web", "//third_party/libaddressinput", + "//third_party/libaddressinput:strings_grit", "//ui/base", ] libs = [ "UIKit.framework" ] @@ -163,6 +164,7 @@ "//components/autofill/core/browser", "//components/autofill/core/browser:test_support", "//components/payments/core", + "//components/prefs:prefs", "//components/strings", "//ios/chrome/app/strings", "//ios/chrome/browser",
diff --git a/ios/chrome/browser/ui/payments/address_edit_coordinator.h b/ios/chrome/browser/ui/payments/address_edit_coordinator.h index e207f94..799fb224 100644 --- a/ios/chrome/browser/ui/payments/address_edit_coordinator.h +++ b/ios/chrome/browser/ui/payments/address_edit_coordinator.h
@@ -7,6 +7,7 @@ #import "ios/chrome/browser/chrome_coordinator.h" #import "ios/chrome/browser/ui/payments/address_edit_view_controller.h" +#import "ios/chrome/browser/ui/payments/country_selection_coordinator.h" #import "ios/chrome/browser/ui/payments/payment_request_edit_view_controller.h" namespace autofill { @@ -38,7 +39,8 @@ // provided in the initializer. @interface AddressEditCoordinator : ChromeCoordinator<AddressEditViewControllerDelegate, - PaymentRequestEditViewControllerValidator> + PaymentRequestEditViewControllerValidator, + CountrySelectionCoordinatorDelegate> // The address to be edited, if any. This pointer is not owned by this class // and should outlive it.
diff --git a/ios/chrome/browser/ui/payments/address_edit_coordinator.mm b/ios/chrome/browser/ui/payments/address_edit_coordinator.mm index 2adcfab2..b660f86 100644 --- a/ios/chrome/browser/ui/payments/address_edit_coordinator.mm +++ b/ios/chrome/browser/ui/payments/address_edit_coordinator.mm
@@ -23,6 +23,9 @@ @interface AddressEditCoordinator () +@property(nonatomic, strong) + CountrySelectionCoordinator* countrySelectionCoordinator; + @property(nonatomic, strong) AddressEditViewController* viewController; @property(nonatomic, strong) AddressEditMediator* mediator; @@ -34,6 +37,7 @@ @synthesize address = _address; @synthesize paymentRequest = _paymentRequest; @synthesize delegate = _delegate; +@synthesize countrySelectionCoordinator = _countrySelectionCoordinator; @synthesize viewController = _viewController; @synthesize mediator = _mediator; @@ -50,6 +54,7 @@ self.mediator = [[AddressEditMediator alloc] initWithPaymentRequest:self.paymentRequest address:self.address]; + [self.mediator setConsumer:self.viewController]; [self.viewController setDataSource:self.mediator]; [self.viewController loadModel]; @@ -61,6 +66,8 @@ - (void)stop { [self.viewController.navigationController popViewControllerAnimated:YES]; + [self.countrySelectionCoordinator stop]; + self.countrySelectionCoordinator = nil; self.viewController = nil; } @@ -79,7 +86,13 @@ (PaymentRequestEditViewController*)controller didSelectField:(EditorField*)field { if (field.autofillUIType == AutofillUITypeProfileHomeAddressCountry) { - // TODO(crbug.com/602666): Change the fields according to the selection. + self.countrySelectionCoordinator = [[CountrySelectionCoordinator alloc] + initWithBaseViewController:self.viewController]; + [self.countrySelectionCoordinator setCountries:self.mediator.countries]; + [self.countrySelectionCoordinator + setSelectedCountryCode:self.mediator.selectedCountryCode]; + [self.countrySelectionCoordinator setDelegate:self]; + [self.countrySelectionCoordinator start]; } } @@ -95,4 +108,17 @@ [self.delegate addressEditCoordinatorDidCancel:self]; } +#pragma mark - CountrySelectionCoordinatorDelegate + +- (void)countrySelectionCoordinator:(CountrySelectionCoordinator*)coordinator + didSelectCountryWithCode:(NSString*)countryCode { + if (self.mediator.selectedCountryCode != countryCode) { + [self.mediator setSelectedCountryCode:countryCode]; + [self.viewController loadModel]; + [self.viewController.collectionView reloadData]; + } + [self.countrySelectionCoordinator stop]; + self.countrySelectionCoordinator = nil; +} + @end
diff --git a/ios/chrome/browser/ui/payments/address_edit_coordinator_unittest.mm b/ios/chrome/browser/ui/payments/address_edit_coordinator_unittest.mm index 9971899..c2f0904 100644 --- a/ios/chrome/browser/ui/payments/address_edit_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/payments/address_edit_coordinator_unittest.mm
@@ -9,9 +9,12 @@ #include "base/memory/ptr_util.h" #include "base/test/ios/wait_util.h" #include "components/autofill/core/browser/autofill_profile.h" +#include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/test_personal_data_manager.h" -#include "ios/chrome/browser/payments/payment_request.h" +#include "components/autofill/core/browser/test_region_data_loader.h" +#include "components/prefs/pref_service.h" #include "ios/chrome/browser/payments/payment_request_test_util.h" +#include "ios/chrome/browser/payments/test_payment_request.h" #import "ios/chrome/browser/ui/payments/address_edit_view_controller.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" @@ -24,14 +27,24 @@ class PaymentRequestAddressEditCoordinatorTest : public PlatformTest { protected: - PaymentRequestAddressEditCoordinatorTest() { - payment_request_ = base::MakeUnique<PaymentRequest>( + PaymentRequestAddressEditCoordinatorTest() + : pref_service_(autofill::test::PrefServiceForTesting()) { + personal_data_manager_.SetTestingPrefService(pref_service_.get()); + payment_request_ = base::MakeUnique<TestPaymentRequest>( payment_request_test_util::CreateTestWebPaymentRequest(), &personal_data_manager_); + test_region_data_loader_.set_synchronous_callback(true); + payment_request_->SetRegionDataLoader(&test_region_data_loader_); + } + + void TearDown() override { + personal_data_manager_.SetTestingPrefService(nullptr); } autofill::TestPersonalDataManager personal_data_manager_; - std::unique_ptr<PaymentRequest> payment_request_; + std::unique_ptr<PrefService> pref_service_; + std::unique_ptr<TestPaymentRequest> payment_request_; + autofill::TestRegionDataLoader test_region_data_loader_; }; // Tests that invoking start and stop on the coordinator presents and dismisses
diff --git a/ios/chrome/browser/ui/payments/address_edit_mediator.h b/ios/chrome/browser/ui/payments/address_edit_mediator.h index a2898fd3..cae2146 100644 --- a/ios/chrome/browser/ui/payments/address_edit_mediator.h +++ b/ios/chrome/browser/ui/payments/address_edit_mediator.h
@@ -6,6 +6,7 @@ #define IOS_CHROME_BROWSER_UI_PAYMENTS_ADDRESS_EDIT_MEDIATOR_H_ #import "ios/chrome/browser/ui/payments/payment_request_edit_view_controller_data_source.h" +#import "ios/chrome/browser/ui/payments/region_data_loader.h" class PaymentRequest; @protocol PaymentRequestEditConsumer; @@ -16,12 +17,22 @@ // Serves as data source for AddressEditViewController. @interface AddressEditMediator - : NSObject<PaymentRequestEditViewControllerDataSource> + : NSObject<PaymentRequestEditViewControllerDataSource, + RegionDataLoaderConsumer> // The consumer for this object. This can change during the lifetime of this // object and may be nil. @property(nonatomic, weak) id<PaymentRequestEditConsumer> consumer; +// The map of country codes to country names. +@property(nonatomic, strong) NSDictionary<NSString*, NSString*>* countries; + +// The country code for the currently selected country, if any. +@property(nonatomic, strong) NSString* selectedCountryCode; + +// The list of region names used for the autofill::ADDRESS_HOME_STATE field. +@property(nonatomic, strong) NSArray<NSString*>* regions; + // Initializes this object with an instance of PaymentRequest which has a copy // of web::PaymentRequest as provided by the page invoking the Payment Request // API as well as |address| which is the address to be edited, if any.
diff --git a/ios/chrome/browser/ui/payments/address_edit_mediator.mm b/ios/chrome/browser/ui/payments/address_edit_mediator.mm index cbb1291..33be5424 100644 --- a/ios/chrome/browser/ui/payments/address_edit_mediator.mm +++ b/ios/chrome/browser/ui/payments/address_edit_mediator.mm
@@ -4,15 +4,39 @@ #import "ios/chrome/browser/ui/payments/address_edit_mediator.h" +#include <map> +#include <memory> +#include <string> +#include <utility> + +#include "base/callback.h" +#include "base/memory/ptr_util.h" +#include "base/strings/sys_string_conversions.h" +#include "base/values.h" +#include "components/autofill/core/browser/autofill_address_util.h" +#include "components/autofill/core/browser/autofill_country.h" #include "components/autofill/core/browser/autofill_profile.h" +#include "components/autofill/core/browser/country_combobox_model.h" +#include "components/autofill/core/browser/field_types.h" +#include "components/autofill/core/browser/personal_data_manager.h" +#include "components/strings/grit/components_strings.h" +#include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/payments/payment_request.h" +#import "ios/chrome/browser/ui/autofill/autofill_ui_type.h" +#import "ios/chrome/browser/ui/autofill/autofill_ui_type_util.h" #import "ios/chrome/browser/ui/payments/payment_request_edit_consumer.h" +#import "ios/chrome/browser/ui/payments/payment_request_editor_field.h" +#include "ios/chrome/grit/ios_strings.h" +#include "third_party/libaddressinput/messages.h" +#include "ui/base/l10n/l10n_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif -@interface AddressEditMediator () +@interface AddressEditMediator () { + std::unique_ptr<RegionDataLoader> _regionDataLoader; +} // The PaymentRequest object owning an instance of web::PaymentRequest as // provided by the page invoking the Payment Request API. This is a weak @@ -23,14 +47,32 @@ // should outlive it. @property(nonatomic, assign) autofill::AutofillProfile* address; +// The map of autofill types to the cached editor fields. Helps reuse the editor +// fields and therefore maintain their existing values when the selected country +// changes and the editor fields get updated. +@property(nonatomic, strong) + NSMutableDictionary<NSNumber*, EditorField*>* fieldsMap; + +// The list of current editor fields. +@property(nonatomic, strong) NSMutableArray<EditorField*>* fields; + +// The reference to the autofill::ADDRESS_HOME_STATE field, if any. +@property(nonatomic, strong) EditorField* regionField; + @end @implementation AddressEditMediator @synthesize state = _state; @synthesize consumer = _consumer; +@synthesize countries = _countries; +@synthesize selectedCountryCode = _selectedCountryCode; +@synthesize regions = _regions; @synthesize paymentRequest = _paymentRequest; @synthesize address = _address; +@synthesize fieldsMap = _fieldsMap; +@synthesize fields = _fields; +@synthesize regionField = _regionField; - (instancetype)initWithPaymentRequest:(PaymentRequest*)paymentRequest address:(autofill::AutofillProfile*)address { @@ -40,6 +82,8 @@ _address = address; _state = _address ? EditViewControllerStateEdit : EditViewControllerStateCreate; + _fieldsMap = [[NSMutableDictionary alloc] init]; + [self loadCountries]; } return self; } @@ -48,7 +92,20 @@ - (void)setConsumer:(id<PaymentRequestEditConsumer>)consumer { _consumer = consumer; + [self.consumer setEditorFields:[self createEditorFields]]; + if (self.regionField) + [self loadRegions]; +} + +- (void)setSelectedCountryCode:(NSString*)selectedCountryCode { + if (_selectedCountryCode == selectedCountryCode) + return; + _selectedCountryCode = selectedCountryCode; + + [self.consumer setEditorFields:[self createEditorFields]]; + if (self.regionField) + [self loadRegions]; } #pragma mark - CreditCardEditViewControllerDataSource @@ -61,10 +118,159 @@ return NO; } +#pragma mark - RegionDataLoaderConsumer + +- (void)regionDataLoaderDidSucceedWithRegions: + (NSMutableArray<NSString*>*)regions { + self.regions = regions; + // Notify the view controller asynchronously to allow for the view to update. + __weak AddressEditMediator* weakSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf.consumer setOptions:weakSelf.regions + forEditorField:weakSelf.regionField]; + }); +} + #pragma mark - Helper methods +// Loads the country codes and names and sets the default selected country code. +- (void)loadCountries { + autofill::CountryComboboxModel countryModel; + countryModel.SetCountries(*_paymentRequest->GetPersonalDataManager(), + base::Callback<bool(const std::string&)>(), + GetApplicationContext()->GetApplicationLocale()); + const autofill::CountryComboboxModel::CountryVector& countriesVector = + countryModel.countries(); + + NSMutableDictionary<NSString*, NSString*>* countries = + [[NSMutableDictionary alloc] + initWithCapacity:static_cast<NSUInteger>(countriesVector.size())]; + for (size_t i = 0; i < countriesVector.size(); ++i) { + if (countriesVector[i].get()) { + [countries setObject:base::SysUTF16ToNSString(countriesVector[i]->name()) + forKey:base::SysUTF8ToNSString( + countriesVector[i]->country_code())]; + } + } + _countries = countries; + _selectedCountryCode = + base::SysUTF8ToNSString(countryModel.GetDefaultCountryCode()); +} + +// Queries the region names based on the selected country code. +- (void)loadRegions { + _regionDataLoader = base::MakeUnique<RegionDataLoader>(self); + _regionDataLoader->LoadRegionData( + base::SysNSStringToUTF8(self.selectedCountryCode), + _paymentRequest->GetRegionDataLoader()); +} + +// Returns an array of editor fields based on the selected country code. Caches +// the fields to be reused when the selected country code changes. - (NSArray<EditorField*>*)createEditorFields { - return @[]; + self.fields = [[NSMutableArray alloc] init]; + + self.regionField = nil; + + base::ListValue addressComponents; + std::string unused; + autofill::GetAddressComponents( + base::SysNSStringToUTF8(self.selectedCountryCode), + GetApplicationContext()->GetApplicationLocale(), &addressComponents, + &unused); + + for (size_t lineIndex = 0; lineIndex < addressComponents.GetSize(); + ++lineIndex) { + const base::ListValue* line = nullptr; + if (!addressComponents.GetList(lineIndex, &line)) { + NOTREACHED(); + return @[]; + } + for (size_t componentIndex = 0; componentIndex < line->GetSize(); + ++componentIndex) { + const base::DictionaryValue* component = nullptr; + if (!line->GetDictionary(componentIndex, &component)) { + NOTREACHED(); + return @[]; + } + + std::string autofillType; + if (!component->GetString(autofill::kFieldTypeKey, &autofillType)) { + NOTREACHED(); + return @[]; + } + AutofillUIType autofillUIType = AutofillUITypeFromAutofillType( + autofill::GetFieldTypeFromString(autofillType)); + + NSNumber* fieldKey = [NSNumber numberWithInt:autofillUIType]; + EditorField* field = self.fieldsMap[fieldKey]; + if (!field) { + BOOL required = autofillUIType != AutofillUITypeProfileCompanyName; + field = + [[EditorField alloc] initWithAutofillUIType:autofillUIType + fieldType:EditorFieldTypeTextField + label:nil + value:nil + required:required]; + [self.fieldsMap setObject:field forKey:fieldKey]; + } + + std::string fieldLabel; + if (!component->GetString(autofill::kFieldNameKey, &fieldLabel)) { + NOTREACHED(); + return @[]; + } + field.label = base::SysUTF8ToNSString(fieldLabel); + + // Keep a reference to the field for the autofill::ADDRESS_HOME_STATE. Set + // its value to "Loading..." and disable it until the regions are loaded. + if (autofillUIType == AutofillUITypeProfileHomeAddressState) { + self.regionField = field; + field.value = l10n_util::GetNSString(IDS_AUTOFILL_LOADING_REGIONS); + field.enabled = NO; + } + + [self.fields addObject:field]; + + // Insert the country field right after the full name field. + if (autofillUIType == AutofillUITypeProfileFullName) { + NSNumber* countryFieldKey = + [NSNumber numberWithInt:AutofillUITypeProfileHomeAddressCountry]; + EditorField* field = self.fieldsMap[countryFieldKey]; + if (!field) { + NSString* label = l10n_util::GetNSString( + IDS_LIBADDRESSINPUT_COUNTRY_OR_REGION_LABEL); + field = [[EditorField alloc] + initWithAutofillUIType:AutofillUITypeProfileHomeAddressCountry + fieldType:EditorFieldTypeSelector + label:label + value:nil + required:YES]; + [self.fieldsMap setObject:field forKey:countryFieldKey]; + } + field.value = self.selectedCountryCode; + field.displayValue = self.countries[self.selectedCountryCode]; + [self.fields addObject:field]; + } + } + } + + // Always add phone number field at the end. + NSNumber* phoneNumberFieldKey = + [NSNumber numberWithInt:AutofillUITypeProfileHomePhoneWholeNumber]; + EditorField* field = self.fieldsMap[phoneNumberFieldKey]; + if (!field) { + field = [[EditorField alloc] + initWithAutofillUIType:AutofillUITypeProfileHomePhoneWholeNumber + fieldType:EditorFieldTypeTextField + label:l10n_util::GetNSString(IDS_IOS_AUTOFILL_PHONE) + value:nil + required:YES]; + [self.fieldsMap setObject:field forKey:phoneNumberFieldKey]; + } + [self.fields addObject:field]; + + return self.fields; } @end
diff --git a/ios/chrome/browser/ui/payments/payment_request_edit_consumer.h b/ios/chrome/browser/ui/payments/payment_request_edit_consumer.h index dd2dbf7f..3d07516 100644 --- a/ios/chrome/browser/ui/payments/payment_request_edit_consumer.h +++ b/ios/chrome/browser/ui/payments/payment_request_edit_consumer.h
@@ -15,6 +15,10 @@ // Sets the list of field definitions for the editor. - (void)setEditorFields:(NSArray<EditorField*>*)fields; +// Sets the options to choose from for |field|. +- (void)setOptions:(NSArray<NSString*>*)options + forEditorField:(EditorField*)field; + @end #endif // IOS_CHROME_BROWSER_UI_PAYMENTS_PAYMENT_REQUEST_EDIT_CONSUMER_H_
diff --git a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm index 9e5c00a..9f58aa8 100644 --- a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm +++ b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm
@@ -68,18 +68,31 @@ } // namespace -@interface PaymentRequestEditViewController ()< - AutofillEditAccessoryDelegate, - UITextFieldDelegate> { +@interface PaymentRequestEditViewController ()<AutofillEditAccessoryDelegate, + UITextFieldDelegate, + UIPickerViewDataSource, + UIPickerViewDelegate> { // The currently focused cell. May be nil. __weak AutofillEditCell* _currentEditingCell; AutofillEditAccessoryView* _accessoryView; } +// The map of autofill types to the fields definitions for the editor. +@property(nonatomic, strong) + NSMutableDictionary<NSNumber*, EditorField*>* fieldsMap; + // The list of field definitions for the editor. @property(nonatomic, strong) NSArray<EditorField*>* fields; +// The map of autofill types to lists of UIPickerView options. +@property(nonatomic, strong) + NSMutableDictionary<NSNumber*, NSArray<NSString*>*>* options; + +// The map of autofill types to UIPickerView views. +@property(nonatomic, strong) + NSMutableDictionary<NSNumber*, UIPickerView*>* pickerViews; + // Returns the indexPath for the same row as that of |indexPath| in a section // with the given offset relative to that of |indexPath|. May return nil. - (NSIndexPath*)indexPathWithSectionOffset:(NSInteger)offset @@ -106,12 +119,17 @@ @synthesize dataSource = _dataSource; @synthesize delegate = _delegate; @synthesize validatorDelegate = _validatorDelegate; +@synthesize fieldsMap = _fieldsMap; @synthesize fields = _fields; +@synthesize options = _options; +@synthesize pickerViews = _pickerViews; - (instancetype)initWithStyle:(CollectionViewControllerStyle)style { self = [super initWithStyle:style]; if (self) { _accessoryView = [[AutofillEditAccessoryView alloc] initWithDelegate:self]; + _options = [[NSMutableDictionary alloc] init]; + _pickerViews = [[NSMutableDictionary alloc] init]; } return self; } @@ -139,6 +157,8 @@ [super loadModel]; CollectionViewModel* model = self.collectionViewModel; + [self.pickerViews removeAllObjects]; + CollectionViewItem* headerItem = [_dataSource headerItem]; if (headerItem) { [headerItem setType:ItemTypeHeader]; @@ -147,21 +167,22 @@ } // Iterate over the fields and add the respective sections and items. - int sectionIdentifier = static_cast<int>(SectionIdentifierFirstField); - for (EditorField* field in self.fields) { + [self.fields enumerateObjectsUsingBlock:^(EditorField* field, + NSUInteger index, BOOL* stop) { + NSInteger sectionIdentifier = SectionIdentifierFirstField + index; [model addSectionWithIdentifier:sectionIdentifier]; switch (field.fieldType) { case EditorFieldTypeTextField: { AutofillEditItem* item = [[AutofillEditItem alloc] initWithType:ItemTypeTextField]; item.textFieldName = field.label; - item.textFieldEnabled = YES; + item.textFieldEnabled = field.enabled; item.textFieldValue = field.value; item.required = field.isRequired; item.autofillUIType = field.autofillUIType; - [model addItem:item - toSectionWithIdentifier:static_cast<NSInteger>(sectionIdentifier)]; + [model addItem:item toSectionWithIdentifier:sectionIdentifier]; field.item = item; + break; } case EditorFieldTypeSelector: { @@ -172,8 +193,7 @@ item.required = field.isRequired; item.autofillUIType = field.autofillUIType; item.accessoryType = MDCCollectionViewCellAccessoryDisclosureIndicator; - [model addItem:item - toSectionWithIdentifier:static_cast<NSInteger>(sectionIdentifier)]; + [model addItem:item toSectionWithIdentifier:sectionIdentifier]; field.item = item; break; } @@ -181,9 +201,8 @@ NOTREACHED(); } - field.sectionIdentifier = static_cast<NSInteger>(sectionIdentifier); - ++sectionIdentifier; - } + field.sectionIdentifier = sectionIdentifier; + }]; [self loadFooterItems]; } @@ -204,6 +223,42 @@ - (void)setEditorFields:(NSArray<EditorField*>*)fields { self.fields = fields; + self.fieldsMap = [[NSMutableDictionary alloc] initWithCapacity:fields.count]; + // Iterate over the fields and populate the map. + [self.fields enumerateObjectsUsingBlock:^(EditorField* field, + NSUInteger index, BOOL* stop) { + NSNumber* key = [NSNumber numberWithInt:field.autofillUIType]; + [self.fieldsMap setObject:field forKey:key]; + }]; +} + +- (void)setOptions:(NSArray<NSString*>*)options + forEditorField:(EditorField*)field { + DCHECK(field.fieldType == EditorFieldTypeTextField); + AutofillEditItem* item = + base::mac::ObjCCastStrict<AutofillEditItem>(field.item); + + // Enable the previously disabled text field and reset its value. + item.textFieldEnabled = YES; + item.textFieldValue = nil; + + // Cache the options if there are any and set the text field's UIPickerView. + if (options.count) { + NSNumber* key = [NSNumber numberWithInt:field.autofillUIType]; + [self.options setObject:options forKey:key]; + + UIPickerView* pickerView = [[UIPickerView alloc] initWithFrame:CGRectZero]; + pickerView.delegate = self; + pickerView.dataSource = self; + [self.pickerViews setObject:pickerView forKey:key]; + item.inputView = pickerView; + } + + // Reload the item. + NSIndexPath* indexPath = + [self.collectionViewModel indexPathForItemType:ItemTypeTextField + sectionIdentifier:field.sectionIdentifier]; + [self.collectionView reloadItemsAtIndexPaths:@[ indexPath ]]; } #pragma mark - UITextFieldDelegate @@ -217,23 +272,20 @@ - (void)textFieldDidEndEditing:(UITextField*)textField { DCHECK(_currentEditingCell == AutofillEditCellForTextField(textField)); - // Validate the text field. CollectionViewModel* model = self.collectionViewModel; NSIndexPath* indexPath = [self indexPathForCurrentTextField]; AutofillEditItem* item = base::mac::ObjCCastStrict<AutofillEditItem>( [model itemAtIndexPath:indexPath]); - // Create a dummy EditorField for validation only. - EditorField* fieldForValidation = - [[EditorField alloc] initWithAutofillUIType:item.autofillUIType - fieldType:EditorFieldTypeTextField - label:nil - value:textField.text - required:item.required]; + // Find and validate the respective editor field. + NSNumber* key = [NSNumber numberWithInt:item.autofillUIType]; + EditorField* field = self.fieldsMap[key]; + DCHECK(field); + field.value = textField.text; NSString* errorMessage = [_validatorDelegate paymentRequestEditViewController:self - validateField:fieldForValidation]; + validateField:field]; NSInteger sectionIdentifier = [model sectionIdentifierForSection:[indexPath section]]; [self addOrRemoveErrorMessage:errorMessage @@ -272,6 +324,42 @@ [[_currentEditingCell textField] resignFirstResponder]; } +#pragma mark - UIPickerViewDataSource methods + +- (NSInteger)numberOfComponentsInPickerView:(UIPickerView*)thePickerView { + return 1; +} + +- (NSInteger)pickerView:(UIPickerView*)thePickerView + numberOfRowsInComponent:(NSInteger)component { + NSArray<NSNumber*>* indices = + [self.pickerViews allKeysForObject:thePickerView]; + DCHECK(indices.count == 1); + NSArray<NSString*>* options = self.options[indices[0]]; + return options.count; +} + +#pragma mark - UIPickerViewDelegate methods + +- (NSString*)pickerView:(UIPickerView*)thePickerView + titleForRow:(NSInteger)row + forComponent:(NSInteger)component { + NSArray<NSNumber*>* indices = + [self.pickerViews allKeysForObject:thePickerView]; + DCHECK(indices.count == 1); + NSArray<NSString*>* options = self.options[indices[0]]; + DCHECK(row < static_cast<NSInteger>(options.count)); + return options[row]; +} + +- (void)pickerView:(UIPickerView*)thePickerView + didSelectRow:(NSInteger)row + inComponent:(NSInteger)component { + DCHECK(_currentEditingCell); + _currentEditingCell.textField.text = + [self pickerView:thePickerView titleForRow:row forComponent:component]; +} + #pragma mark - UICollectionViewDataSource - (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView @@ -332,9 +420,13 @@ hasSectionForSectionIdentifier:SectionIdentifierHeader]) index--; DCHECK(index >= 0 && index < static_cast<NSInteger>(self.fields.count)); - [_delegate - paymentRequestEditViewController:self - didSelectField:[self.fields objectAtIndex:index]]; + EditorField* field = [self.fields objectAtIndex:index]; + + // If a selector field is selected, blur the focused text field. + if (field.fieldType == EditorFieldTypeSelector) + [[_currentEditingCell textField] resignFirstResponder]; + + [_delegate paymentRequestEditViewController:self didSelectField:field]; } #pragma mark MDCCollectionViewStylingDelegate
diff --git a/ios/chrome/browser/ui/payments/payment_request_editor_field.h b/ios/chrome/browser/ui/payments/payment_request_editor_field.h index def8ee85..8f54213 100644 --- a/ios/chrome/browser/ui/payments/payment_request_editor_field.h +++ b/ios/chrome/browser/ui/payments/payment_request_editor_field.h
@@ -34,6 +34,8 @@ @property(nonatomic, copy) NSString* displayValue; // Whether the field is required. @property(nonatomic, getter=isRequired) BOOL required; +// Whether the field is enabled. +@property(nonatomic, getter=isEnabled) BOOL enabled; // The associated CollectionViewItem instance. May be nil. @property(nonatomic, strong) CollectionViewItem* item; // The section identifier for the associated AutofillEditItem.
diff --git a/ios/chrome/browser/ui/payments/payment_request_editor_field.mm b/ios/chrome/browser/ui/payments/payment_request_editor_field.mm index 68740c4..e861027 100644 --- a/ios/chrome/browser/ui/payments/payment_request_editor_field.mm +++ b/ios/chrome/browser/ui/payments/payment_request_editor_field.mm
@@ -16,6 +16,7 @@ @synthesize value = _value; @synthesize displayValue = _displayValue; @synthesize required = _required; +@synthesize enabled = _enabled; @synthesize item = _item; @synthesize sectionIdentifier = _sectionIdentifier; @@ -31,6 +32,7 @@ _label = label; _value = value; _required = required; + _enabled = YES; } return self; }
diff --git a/ios/web/public/test/fakes/crw_test_web_state_observer.mm b/ios/web/public/test/fakes/crw_test_web_state_observer.mm index 51280fb..e133138 100644 --- a/ios/web/public/test/fakes/crw_test_web_state_observer.mm +++ b/ios/web/public/test/fakes/crw_test_web_state_observer.mm
@@ -132,7 +132,8 @@ _didStartNavigationInfo->web_state = webState; std::unique_ptr<web::NavigationContextImpl> context = web::NavigationContextImpl::CreateNavigationContext( - navigation->GetWebState(), navigation->GetUrl()); + navigation->GetWebState(), navigation->GetUrl(), + navigation->GetPageTransition()); context->SetIsSameDocument(navigation->IsSameDocument()); context->SetError(navigation->GetError()); _didStartNavigationInfo->context = std::move(context); @@ -154,7 +155,8 @@ _didFinishNavigationInfo->web_state = webState; std::unique_ptr<web::NavigationContextImpl> context = web::NavigationContextImpl::CreateNavigationContext( - navigation->GetWebState(), navigation->GetUrl()); + navigation->GetWebState(), navigation->GetUrl(), + navigation->GetPageTransition()); context->SetIsSameDocument(navigation->IsSameDocument()); context->SetError(navigation->GetError()); _didFinishNavigationInfo->context = std::move(context);
diff --git a/ios/web/public/test/fakes/test_web_state_observer.mm b/ios/web/public/test/fakes/test_web_state_observer.mm index 5521fad1..c184f6e 100644 --- a/ios/web/public/test/fakes/test_web_state_observer.mm +++ b/ios/web/public/test/fakes/test_web_state_observer.mm
@@ -65,7 +65,8 @@ did_start_navigation_info_->web_state = web_state(); std::unique_ptr<web::NavigationContextImpl> context = web::NavigationContextImpl::CreateNavigationContext( - navigation->GetWebState(), navigation->GetUrl()); + navigation->GetWebState(), navigation->GetUrl(), + navigation->GetPageTransition()); context->SetIsSameDocument(navigation->IsSameDocument()); context->SetError(navigation->GetError()); did_start_navigation_info_->context = std::move(context); @@ -78,7 +79,8 @@ did_finish_navigation_info_->web_state = web_state(); std::unique_ptr<web::NavigationContextImpl> context = web::NavigationContextImpl::CreateNavigationContext( - navigation->GetWebState(), navigation->GetUrl()); + navigation->GetWebState(), navigation->GetUrl(), + navigation->GetPageTransition()); context->SetIsSameDocument(navigation->IsSameDocument()); context->SetError(navigation->GetError()); did_finish_navigation_info_->context = std::move(context);
diff --git a/ios/web/public/web_state/navigation_context.h b/ios/web/public/web_state/navigation_context.h index b8d5b46..ee7073b 100644 --- a/ios/web/public/web_state/navigation_context.h +++ b/ios/web/public/web_state/navigation_context.h
@@ -7,6 +7,8 @@ #import <Foundation/Foundation.h> +#include "ui/base/page_transition_types.h" + class GURL; namespace net { @@ -30,6 +32,9 @@ // The URL the WebState is navigating to. virtual const GURL& GetUrl() const = 0; + // Returns the page transition type for this navigation. + virtual ui::PageTransition GetPageTransition() const = 0; + // Whether the navigation happened within the same document. Examples of same // document navigations are: // * reference fragment navigations
diff --git a/ios/web/test/web_int_test.mm b/ios/web/test/web_int_test.mm index edd8ad3..e2dd64038 100644 --- a/ios/web/test/web_int_test.mm +++ b/ios/web/test/web_int_test.mm
@@ -104,6 +104,7 @@ void WebIntTest::LoadUrl(const GURL& url) { ExecuteBlockAndWaitForLoad(url, ^{ web::NavigationManager::WebLoadParams params(url); + params.transition_type = ui::PageTransition::PAGE_TRANSITION_TYPED; navigation_manager()->LoadURLWithParams(params); }); }
diff --git a/ios/web/web_state/navigation_callbacks_inttest.mm b/ios/web/web_state/navigation_callbacks_inttest.mm index cee1fd5..085212aa 100644 --- a/ios/web/web_state/navigation_callbacks_inttest.mm +++ b/ios/web/web_state/navigation_callbacks_inttest.mm
@@ -16,6 +16,7 @@ #import "ios/web/test/web_int_test.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/page_transition_types.h" #include "url/gurl.h" #include "url/scheme_host_port.h" @@ -33,6 +34,9 @@ ASSERT_TRUE(*context); EXPECT_EQ(web_state, (*context)->GetWebState()); EXPECT_EQ(url, (*context)->GetUrl()); + EXPECT_TRUE( + PageTransitionCoreTypeIs(ui::PageTransition::PAGE_TRANSITION_TYPED, + (*context)->GetPageTransition())); EXPECT_FALSE((*context)->IsSameDocument()); EXPECT_FALSE((*context)->GetError()); ASSERT_FALSE((*context)->GetResponseHeaders()); @@ -50,6 +54,9 @@ ASSERT_TRUE((*context)); EXPECT_EQ(web_state, (*context)->GetWebState()); EXPECT_EQ(url, (*context)->GetUrl()); + EXPECT_TRUE( + PageTransitionCoreTypeIs(ui::PageTransition::PAGE_TRANSITION_TYPED, + (*context)->GetPageTransition())); EXPECT_FALSE((*context)->IsSameDocument()); EXPECT_FALSE((*context)->GetError()); ASSERT_TRUE((*context)->GetResponseHeaders()); @@ -65,11 +72,17 @@ // Verifies correctness of |NavigationContext| (|arg0|) for same page navigation // passed to |DidFinishNavigation|. Stores |NavigationContext| in |context| // pointer. -ACTION_P3(VerifySameDocumentStartedContext, web_state, url, context) { +ACTION_P4(VerifySameDocumentStartedContext, + web_state, + url, + context, + page_transition) { *context = arg0; ASSERT_TRUE(*context); EXPECT_EQ(web_state, (*context)->GetWebState()); EXPECT_EQ(url, (*context)->GetUrl()); + EXPECT_TRUE(PageTransitionTypeIncludingQualifiersIs( + page_transition, (*context)->GetPageTransition())); EXPECT_FALSE((*context)->IsSameDocument()); EXPECT_FALSE((*context)->GetError()); EXPECT_FALSE((*context)->GetResponseHeaders()); @@ -78,11 +91,17 @@ // Verifies correctness of |NavigationContext| (|arg0|) for same page navigation // passed to |DidFinishNavigation|. Asserts that |NavigationContext| the same as // |context|. -ACTION_P3(VerifySameDocumentFinishedContext, web_state, url, context) { +ACTION_P4(VerifySameDocumentFinishedContext, + web_state, + url, + context, + page_transition) { ASSERT_EQ(*context, arg0); ASSERT_TRUE(*context); EXPECT_EQ(web_state, (*context)->GetWebState()); EXPECT_EQ(url, (*context)->GetUrl()); + EXPECT_TRUE(PageTransitionTypeIncludingQualifiersIs( + page_transition, (*context)->GetPageTransition())); EXPECT_TRUE((*context)->IsSameDocument()); EXPECT_FALSE((*context)->GetError()); EXPECT_FALSE((*context)->GetResponseHeaders()); @@ -100,6 +119,9 @@ ASSERT_TRUE(*context); EXPECT_EQ(web_state, (*context)->GetWebState()); EXPECT_EQ(url, (*context)->GetUrl()); + EXPECT_TRUE( + PageTransitionCoreTypeIs(ui::PageTransition::PAGE_TRANSITION_TYPED, + (*context)->GetPageTransition())); EXPECT_FALSE((*context)->IsSameDocument()); EXPECT_FALSE((*context)->GetError()); EXPECT_FALSE((*context)->GetResponseHeaders()); @@ -116,6 +138,9 @@ ASSERT_TRUE(*context); EXPECT_EQ(web_state, (*context)->GetWebState()); EXPECT_EQ(url, (*context)->GetUrl()); + EXPECT_TRUE( + PageTransitionCoreTypeIs(ui::PageTransition::PAGE_TRANSITION_TYPED, + (*context)->GetPageTransition())); EXPECT_FALSE((*context)->IsSameDocument()); EXPECT_FALSE((*context)->GetError()); EXPECT_FALSE((*context)->GetResponseHeaders()); @@ -184,18 +209,24 @@ // Perform same-page navigation. const GURL hash_url = HttpServer::MakeUrl("http://chromium.test#1"); EXPECT_CALL(*observer_, DidStartNavigation(_)) - .WillOnce( - VerifySameDocumentStartedContext(web_state(), hash_url, &context)); + .WillOnce(VerifySameDocumentStartedContext( + web_state(), hash_url, &context, + ui::PageTransition::PAGE_TRANSITION_TYPED)); EXPECT_CALL(*observer_, DidFinishNavigation(_)) - .WillOnce( - VerifySameDocumentFinishedContext(web_state(), hash_url, &context)); + .WillOnce(VerifySameDocumentFinishedContext( + web_state(), hash_url, &context, + ui::PageTransition::PAGE_TRANSITION_TYPED)); LoadUrl(hash_url); // Perform same-page navigation by going back. EXPECT_CALL(*observer_, DidStartNavigation(_)) - .WillOnce(VerifySameDocumentStartedContext(web_state(), url, &context)); + .WillOnce(VerifySameDocumentStartedContext( + web_state(), url, &context, + ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT)); EXPECT_CALL(*observer_, DidFinishNavigation(_)) - .WillOnce(VerifySameDocumentFinishedContext(web_state(), url, &context)); + .WillOnce(VerifySameDocumentFinishedContext( + web_state(), url, &context, + ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT)); ExecuteBlockAndWaitForLoad(url, ^{ navigation_manager()->GoBack(); }); @@ -219,11 +250,13 @@ // Perform same-page navigation using JavaScript. const GURL hash_url = HttpServer::MakeUrl("http://chromium.test#1"); EXPECT_CALL(*observer_, DidStartNavigation(_)) - .WillOnce( - VerifySameDocumentStartedContext(web_state(), hash_url, &context)); + .WillOnce(VerifySameDocumentStartedContext( + web_state(), hash_url, &context, + ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT)); EXPECT_CALL(*observer_, DidFinishNavigation(_)) - .WillOnce( - VerifySameDocumentFinishedContext(web_state(), hash_url, &context)); + .WillOnce(VerifySameDocumentFinishedContext( + web_state(), hash_url, &context, + ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT)); ExecuteJavaScript(@"window.location.hash = '#1'"); } @@ -245,21 +278,25 @@ // Perform push state using JavaScript. const GURL push_url = HttpServer::MakeUrl("http://chromium.test/test.html"); EXPECT_CALL(*observer_, DidStartNavigation(_)) - .WillOnce( - VerifySameDocumentStartedContext(web_state(), push_url, &context)); + .WillOnce(VerifySameDocumentStartedContext( + web_state(), push_url, &context, + ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT)); EXPECT_CALL(*observer_, DidFinishNavigation(_)) - .WillOnce( - VerifySameDocumentFinishedContext(web_state(), push_url, &context)); + .WillOnce(VerifySameDocumentFinishedContext( + web_state(), push_url, &context, + ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT)); ExecuteJavaScript(@"window.history.pushState('', 'Test', 'test.html')"); // Perform replace state using JavaScript. const GURL replace_url = HttpServer::MakeUrl("http://chromium.test/1.html"); EXPECT_CALL(*observer_, DidStartNavigation(_)) - .WillOnce( - VerifySameDocumentStartedContext(web_state(), replace_url, &context)); + .WillOnce(VerifySameDocumentStartedContext( + web_state(), replace_url, &context, + ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT)); EXPECT_CALL(*observer_, DidFinishNavigation(_)) - .WillOnce(VerifySameDocumentFinishedContext(web_state(), replace_url, - &context)); + .WillOnce(VerifySameDocumentFinishedContext( + web_state(), replace_url, &context, + ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT)); ExecuteJavaScript(@"window.history.replaceState('', 'Test', '1.html')"); }
diff --git a/ios/web/web_state/navigation_context_impl.h b/ios/web/web_state/navigation_context_impl.h index 5ea8139..ebb6608 100644 --- a/ios/web/web_state/navigation_context_impl.h +++ b/ios/web/web_state/navigation_context_impl.h
@@ -22,7 +22,8 @@ // Response headers will ne null. static std::unique_ptr<NavigationContextImpl> CreateNavigationContext( WebState* web_state, - const GURL& url); + const GURL& url, + ui::PageTransition page_transition); #ifndef NDEBUG // Returns human readable description of this object. @@ -32,6 +33,7 @@ // NavigationContext overrides: WebState* GetWebState() override; const GURL& GetUrl() const override; + ui::PageTransition GetPageTransition() const override; bool IsSameDocument() const override; NSError* GetError() const override; net::HttpResponseHeaders* GetResponseHeaders() const override; @@ -48,10 +50,13 @@ void SetNavigationItemUniqueID(int unique_id); private: - NavigationContextImpl(WebState* web_state, const GURL& url); + NavigationContextImpl(WebState* web_state, + const GURL& url, + ui::PageTransition page_transition); WebState* web_state_ = nullptr; GURL url_; + ui::PageTransition page_transition_; bool is_same_document_ = false; base::scoped_nsobject<NSError> error_; scoped_refptr<net::HttpResponseHeaders> response_headers_;
diff --git a/ios/web/web_state/navigation_context_impl.mm b/ios/web/web_state/navigation_context_impl.mm index 5e971304..80a09c4 100644 --- a/ios/web/web_state/navigation_context_impl.mm +++ b/ios/web/web_state/navigation_context_impl.mm
@@ -13,10 +13,12 @@ // static std::unique_ptr<NavigationContextImpl> -NavigationContextImpl::CreateNavigationContext(WebState* web_state, - const GURL& url) { +NavigationContextImpl::CreateNavigationContext( + WebState* web_state, + const GURL& url, + ui::PageTransition page_transition) { std::unique_ptr<NavigationContextImpl> result( - new NavigationContextImpl(web_state, url)); + new NavigationContextImpl(web_state, url, page_transition)); return result; } @@ -38,6 +40,10 @@ return url_; } +ui::PageTransition NavigationContextImpl::GetPageTransition() const { + return page_transition_; +} + bool NavigationContextImpl::IsSameDocument() const { return is_same_document_; } @@ -72,9 +78,11 @@ } NavigationContextImpl::NavigationContextImpl(WebState* web_state, - const GURL& url) + const GURL& url, + ui::PageTransition page_transition) : web_state_(web_state), url_(url), + page_transition_(page_transition), is_same_document_(false), error_(nil), response_headers_(nullptr) {}
diff --git a/ios/web/web_state/navigation_context_impl_unittest.mm b/ios/web/web_state/navigation_context_impl_unittest.mm index 7566deb..9729d51 100644 --- a/ios/web/web_state/navigation_context_impl_unittest.mm +++ b/ios/web/web_state/navigation_context_impl_unittest.mm
@@ -33,10 +33,14 @@ // Tests CreateNavigationContext factory method. TEST_F(NavigationContextImplTest, NavigationContext) { std::unique_ptr<NavigationContext> context = - NavigationContextImpl::CreateNavigationContext(&web_state_, url_); + NavigationContextImpl::CreateNavigationContext( + &web_state_, url_, ui::PageTransition::PAGE_TRANSITION_FORWARD_BACK); ASSERT_TRUE(context); EXPECT_EQ(&web_state_, context->GetWebState()); + EXPECT_TRUE(PageTransitionTypeIncludingQualifiersIs( + context->GetPageTransition(), + ui::PageTransition::PAGE_TRANSITION_FORWARD_BACK)); EXPECT_EQ(url_, context->GetUrl()); EXPECT_FALSE(context->IsSameDocument()); EXPECT_FALSE(context->GetError()); @@ -46,7 +50,8 @@ // Tests NavigationContextImpl Setters. TEST_F(NavigationContextImplTest, Setters) { std::unique_ptr<NavigationContextImpl> context = - NavigationContextImpl::CreateNavigationContext(&web_state_, url_); + NavigationContextImpl::CreateNavigationContext( + &web_state_, url_, ui::PageTransition::PAGE_TRANSITION_FORWARD_BACK); ASSERT_TRUE(context); ASSERT_FALSE(context->IsSameDocument());
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index 77d6a767..a47f2f09c 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -1340,7 +1340,7 @@ transition:(ui::PageTransition)transition { std::unique_ptr<web::NavigationContextImpl> context = web::NavigationContextImpl::CreateNavigationContext(_webStateImpl, - pageURL); + pageURL, transition); _webStateImpl->OnNavigationStarted(context.get()); [[self sessionController] pushNewItemWithURL:pageURL stateObject:stateObject @@ -1353,8 +1353,9 @@ - (void)replaceStateWithPageURL:(const GURL&)pageURL stateObject:(NSString*)stateObject { std::unique_ptr<web::NavigationContextImpl> context = - web::NavigationContextImpl::CreateNavigationContext(_webStateImpl, - pageURL); + web::NavigationContextImpl::CreateNavigationContext( + _webStateImpl, pageURL, + ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT); _webStateImpl->OnNavigationStarted(context.get()); [[self sessionController] updateCurrentItemWithURL:pageURL stateObject:stateObject]; @@ -1529,8 +1530,8 @@ web::NavigationManager::UserAgentOverrideOption::INHERIT); } std::unique_ptr<web::NavigationContextImpl> context = - web::NavigationContextImpl::CreateNavigationContext(_webStateImpl, - requestURL); + web::NavigationContextImpl::CreateNavigationContext( + _webStateImpl, requestURL, transition); web::NavigationItem* item = self.navigationManagerImpl->GetPendingItem(); // TODO(crbug.com/676129): AddPendingItem does not always create a pending @@ -4176,17 +4177,18 @@ [_navigationStates setState:web::WKNavigationState::REQUESTED forNavigation:navigation]; std::unique_ptr<web::NavigationContextImpl> context; + const ui::PageTransition loadHTMLTransition = + ui::PageTransition::PAGE_TRANSITION_TYPED; if (_webStateImpl->HasWebUI()) { // WebUI uses |loadHTML:forURL:| to feed the content to web view. This // should not be treated as a navigation, but WKNavigationDelegate callbacks // still expect a valid context. - context = - web::NavigationContextImpl::CreateNavigationContext(_webStateImpl, URL); + context = web::NavigationContextImpl::CreateNavigationContext( + _webStateImpl, URL, loadHTMLTransition); } else { - context = [self - registerLoadRequestForURL:URL - referrer:web::Referrer() - transition:ui::PageTransition::PAGE_TRANSITION_TYPED]; + context = [self registerLoadRequestForURL:URL + referrer:web::Referrer() + transition:loadHTMLTransition]; } [_navigationStates setContext:std::move(context) forNavigation:navigation]; }
diff --git a/ios/web/web_state/ui/crw_wk_navigation_states_unittest.mm b/ios/web/web_state/ui/crw_wk_navigation_states_unittest.mm index 600b692d..d6988e8 100644 --- a/ios/web/web_state/ui/crw_wk_navigation_states_unittest.mm +++ b/ios/web/web_state/ui/crw_wk_navigation_states_unittest.mm
@@ -69,8 +69,9 @@ // navigation_3 is added later and hence the latest. std::unique_ptr<web::NavigationContextImpl> context = - NavigationContextImpl::CreateNavigationContext(nullptr /*web_state*/, - GURL(kTestUrl1)); + NavigationContextImpl::CreateNavigationContext( + nullptr /*web_state*/, GURL(kTestUrl1), + ui::PageTransition::PAGE_TRANSITION_SERVER_REDIRECT); [states_ setContext:std::move(context) forNavigation:navigation3_]; EXPECT_EQ(navigation3_, [states_ lastAddedNavigation]); EXPECT_EQ(WKNavigationState::NONE, [states_ lastAddedNavigationState]); @@ -84,8 +85,9 @@ // Add first context. std::unique_ptr<web::NavigationContextImpl> context1 = - NavigationContextImpl::CreateNavigationContext(nullptr /*web_state*/, - GURL(kTestUrl1)); + NavigationContextImpl::CreateNavigationContext( + nullptr /*web_state*/, GURL(kTestUrl1), + ui::PageTransition::PAGE_TRANSITION_RELOAD); context1->SetIsSameDocument(true); [states_ setContext:std::move(context1) forNavigation:navigation1_]; EXPECT_FALSE([states_ contextForNavigation:navigation2_]); @@ -98,8 +100,9 @@ // Replace existing context. std::unique_ptr<web::NavigationContextImpl> context2 = - NavigationContextImpl::CreateNavigationContext(nullptr /*web_state*/, - GURL(kTestUrl2)); + NavigationContextImpl::CreateNavigationContext( + nullptr /*web_state*/, GURL(kTestUrl2), + ui::PageTransition::PAGE_TRANSITION_GENERATED); NSError* error = [[[NSError alloc] init] autorelease]; context2->SetError(error); [states_ setContext:std::move(context2) forNavigation:navigation1_];
diff --git a/ios/web/web_state/web_state_impl_unittest.mm b/ios/web/web_state/web_state_impl_unittest.mm index 58dee9b..e919761 100644 --- a/ios/web/web_state/web_state_impl_unittest.mm +++ b/ios/web/web_state/web_state_impl_unittest.mm
@@ -350,7 +350,9 @@ ASSERT_FALSE(observer->did_finish_navigation_info()); const GURL url("http://test"); std::unique_ptr<web::NavigationContext> context = - NavigationContextImpl::CreateNavigationContext(web_state_.get(), url); + NavigationContextImpl::CreateNavigationContext( + web_state_.get(), url, + ui::PageTransition::PAGE_TRANSITION_AUTO_BOOKMARK); web_state_->OnNavigationFinished(context.get()); ASSERT_TRUE(observer->did_finish_navigation_info()); EXPECT_EQ(web_state_.get(), @@ -358,6 +360,8 @@ NavigationContext* actual_context = observer->did_finish_navigation_info()->context.get(); EXPECT_EQ(context->GetUrl(), actual_context->GetUrl()); + EXPECT_TRUE(PageTransitionTypeIncludingQualifiersIs( + context->GetPageTransition(), actual_context->GetPageTransition())); EXPECT_FALSE(actual_context->IsSameDocument()); EXPECT_FALSE(actual_context->GetError()); EXPECT_FALSE(actual_context->GetResponseHeaders()); @@ -369,6 +373,8 @@ EXPECT_EQ(web_state_.get(), observer->did_start_navigation_info()->web_state); actual_context = observer->did_start_navigation_info()->context.get(); EXPECT_EQ(context->GetUrl(), actual_context->GetUrl()); + EXPECT_TRUE(PageTransitionTypeIncludingQualifiersIs( + context->GetPageTransition(), actual_context->GetPageTransition())); EXPECT_FALSE(actual_context->IsSameDocument()); EXPECT_FALSE(actual_context->GetError()); EXPECT_FALSE(actual_context->GetResponseHeaders());
diff --git a/ios/web/web_state/web_state_observer_bridge_unittest.mm b/ios/web/web_state/web_state_observer_bridge_unittest.mm index 38daf32b..9b19baa 100644 --- a/ios/web/web_state/web_state_observer_bridge_unittest.mm +++ b/ios/web/web_state/web_state_observer_bridge_unittest.mm
@@ -44,8 +44,9 @@ GURL url("https://chromium.test/"); std::unique_ptr<web::NavigationContext> context = - web::NavigationContextImpl::CreateNavigationContext(&test_web_state_, - url); + web::NavigationContextImpl::CreateNavigationContext( + &test_web_state_, url, + ui::PageTransition::PAGE_TRANSITION_FORWARD_BACK); bridge_->DidStartNavigation(context.get()); ASSERT_TRUE([observer_ didStartNavigationInfo]); @@ -57,6 +58,9 @@ EXPECT_EQ(context->IsSameDocument(), actual_context->IsSameDocument()); EXPECT_EQ(context->GetError(), actual_context->GetError()); EXPECT_EQ(context->GetUrl(), actual_context->GetUrl()); + EXPECT_TRUE(PageTransitionTypeIncludingQualifiersIs( + ui::PageTransition::PAGE_TRANSITION_FORWARD_BACK, + actual_context->GetPageTransition())); EXPECT_EQ(context->GetResponseHeaders(), actual_context->GetResponseHeaders()); } @@ -67,8 +71,9 @@ GURL url("https://chromium.test/"); std::unique_ptr<web::NavigationContext> context = - web::NavigationContextImpl::CreateNavigationContext(&test_web_state_, - url); + web::NavigationContextImpl::CreateNavigationContext( + &test_web_state_, url, + ui::PageTransition::PAGE_TRANSITION_FROM_ADDRESS_BAR); bridge_->DidFinishNavigation(context.get()); ASSERT_TRUE([observer_ didFinishNavigationInfo]); @@ -80,6 +85,9 @@ EXPECT_EQ(context->IsSameDocument(), actual_context->IsSameDocument()); EXPECT_EQ(context->GetError(), actual_context->GetError()); EXPECT_EQ(context->GetUrl(), actual_context->GetUrl()); + EXPECT_TRUE(PageTransitionTypeIncludingQualifiersIs( + ui::PageTransition::PAGE_TRANSITION_FROM_ADDRESS_BAR, + actual_context->GetPageTransition())); EXPECT_EQ(context->GetResponseHeaders(), actual_context->GetResponseHeaders()); }
diff --git a/ios/web/webui/crw_web_ui_manager_unittest.mm b/ios/web/webui/crw_web_ui_manager_unittest.mm index fd9d107..22a1043 100644 --- a/ios/web/webui/crw_web_ui_manager_unittest.mm +++ b/ios/web/webui/crw_web_ui_manager_unittest.mm
@@ -148,8 +148,9 @@ GURL url(kTestWebUIUrl); EXPECT_CALL(*web_state_impl_, LoadWebUIHtml(html, url)); std::unique_ptr<web::NavigationContext> context = - NavigationContextImpl::CreateNavigationContext(web_state_impl_.get(), - url); + NavigationContextImpl::CreateNavigationContext( + web_state_impl_.get(), url, + ui::PageTransition::PAGE_TRANSITION_AUTO_BOOKMARK); web_state_impl_->OnNavigationStarted(context.get()); }
diff --git a/media/capture/video/video_capture_system.h b/media/capture/video/video_capture_system.h index 3897a20d..81257fe7 100644 --- a/media/capture/video/video_capture_system.h +++ b/media/capture/video/video_capture_system.h
@@ -21,7 +21,8 @@ // The passed-in |result_callback| must have ownership of the called // VideoCaptureSystem instance to guarantee that it stays alive during the - // asynchronous operation. + // asynchronous operation. |result_callback| is invoked on the same thread + // that calls GetDeviceInfosAsync() virtual void GetDeviceInfosAsync( const DeviceInfoCallback& result_callback) = 0;
diff --git a/net/BUILD.gn b/net/BUILD.gn index 74dd238..fa4ef1b 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -36,6 +36,7 @@ use_v8_in_net = !is_ios && !is_proto_quic enable_built_in_dns = !is_ios && !is_proto_quic +enable_net_mojo = !is_ios && !is_android && !is_proto_quic # True if certificates are represented with DER byte buffers. This can be true # in addition to use_openssl_certs or use_nss_certs, in that case byte certs @@ -2494,6 +2495,8 @@ "test/embedded_test_server/http_response.h", "test/embedded_test_server/request_handler_util.cc", "test/embedded_test_server/request_handler_util.h", + "test/embedded_test_server/simple_connection_listener.cc", + "test/embedded_test_server/simple_connection_listener.h", "test/event_waiter.h", "test/gtest_util.h", "test/net_test_suite.cc", @@ -2636,7 +2639,7 @@ } } -if (!is_ios && !is_android && !is_proto_quic) { +if (enable_net_mojo) { source_set("net_browser_services") { sources = [ "dns/mojo_host_resolver_impl.cc", @@ -2680,6 +2683,33 @@ } } +if (use_v8_in_net) { + source_set("net_context_builder_with_v8") { + sources = [ + "url_request/url_request_context_builder_v8.cc", + "url_request/url_request_context_builder_v8.h", + ] + + defines = [] + + deps = [ + ":net", + ":net_with_v8", + "//base", + ] + + if (enable_net_mojo) { + deps += [ + ":net_browser_services", + "//mojo/public/cpp/bindings", + "//net/interfaces", + ] + + defines += [ "ENABLE_NET_MOJO" ] + } + } +} + if (!is_ios && !is_android) { executable("cert_verify_tool") { testonly = true @@ -4560,6 +4590,8 @@ "proxy/proxy_server_unittest.cc", "proxy/proxy_service_mojo_unittest.cc", "proxy/proxy_service_unittest.cc", + "proxy/test_mojo_proxy_resolver_factory.cc", + "proxy/test_mojo_proxy_resolver_factory.h", "quic/chromium/bidirectional_stream_quic_impl_unittest.cc", "quic/chromium/crypto/proof_test_chromium.cc", "quic/chromium/crypto/proof_verifier_chromium_test.cc", @@ -4896,6 +4928,7 @@ "url_request/url_fetcher_impl_unittest.cc", "url_request/url_fetcher_response_writer_unittest.cc", "url_request/url_request_context_builder_unittest.cc", + "url_request/url_request_context_builder_v8_unittest.cc", "url_request/url_request_context_unittest.cc", "url_request/url_request_data_job_unittest.cc", "url_request/url_request_file_dir_job_unittest.cc", @@ -5155,21 +5188,27 @@ } if (use_v8_in_net) { - deps += [ ":net_with_v8" ] + deps += [ + ":net_context_builder_with_v8", + ":net_with_v8", + ] } else { sources -= [ "proxy/proxy_resolver_v8_tracing_unittest.cc", "proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc", "proxy/proxy_resolver_v8_unittest.cc", + "url_request/url_request_context_builder_v8_unittest.cc", ] } - if (use_v8_in_net && !is_android) { + if (enable_net_mojo) { deps += [ ":net_browser_services", ":net_utility_services", "//mojo/edk/system", ] + + defines += [ "ENABLE_NET_MOJO" ] } else { sources -= [ "dns/host_resolver_mojo_unittest.cc", @@ -5179,6 +5218,8 @@ "proxy/mojo_proxy_resolver_v8_tracing_bindings_unittest.cc", "proxy/proxy_resolver_factory_mojo_unittest.cc", "proxy/proxy_service_mojo_unittest.cc", + "proxy/test_mojo_proxy_resolver_factory.cc", + "proxy/test_mojo_proxy_resolver_factory.h", ] }
diff --git a/net/base/layered_network_delegate.cc b/net/base/layered_network_delegate.cc index f99d6e1..41c22c1 100644 --- a/net/base/layered_network_delegate.cc +++ b/net/base/layered_network_delegate.cc
@@ -254,4 +254,44 @@ const GURL& referrer_url) const { } +bool LayeredNetworkDelegate::OnCanQueueReportingReport( + const url::Origin& origin) const { + OnCanQueueReportingReportInternal(origin); + return nested_network_delegate_->CanQueueReportingReport(origin); +} + +void LayeredNetworkDelegate::OnCanQueueReportingReportInternal( + const url::Origin& origin) const {} + +bool LayeredNetworkDelegate::OnCanSendReportingReport( + const url::Origin& origin) const { + OnCanSendReportingReportInternal(origin); + return nested_network_delegate_->CanSendReportingReport(origin); +} + +void LayeredNetworkDelegate::OnCanSendReportingReportInternal( + const url::Origin& origin) const {} + +bool LayeredNetworkDelegate::OnCanSetReportingClient( + const url::Origin& origin, + const GURL& endpoint) const { + OnCanSetReportingClientInternal(origin, endpoint); + return nested_network_delegate_->CanSetReportingClient(origin, endpoint); +} + +void LayeredNetworkDelegate::OnCanSetReportingClientInternal( + const url::Origin& origin, + const GURL& endpoint) const {} + +bool LayeredNetworkDelegate::OnCanUseReportingClient( + const url::Origin& origin, + const GURL& endpoint) const { + OnCanUseReportingClientInternal(origin, endpoint); + return nested_network_delegate_->CanUseReportingClient(origin, endpoint); +} + +void LayeredNetworkDelegate::OnCanUseReportingClientInternal( + const url::Origin& origin, + const GURL& endpoint) const {} + } // namespace net
diff --git a/net/base/layered_network_delegate.h b/net/base/layered_network_delegate.h index 1666d86a..562ca0f7 100644 --- a/net/base/layered_network_delegate.h +++ b/net/base/layered_network_delegate.h
@@ -87,6 +87,16 @@ const GURL& target_url, const GURL& referrer_url) const final; + bool OnCanQueueReportingReport(const url::Origin& origin) const final; + + bool OnCanSendReportingReport(const url::Origin& origin) const final; + + bool OnCanSetReportingClient(const url::Origin& origin, + const GURL& endpoint) const final; + + bool OnCanUseReportingClient(const url::Origin& origin, + const GURL& endpoint) const final; + protected: virtual void OnBeforeURLRequestInternal(URLRequest* request, const CompletionCallback& callback, @@ -157,6 +167,18 @@ const GURL& target_url, const GURL& referrer_url) const; + virtual void OnCanQueueReportingReportInternal( + const url::Origin& origin) const; + + virtual void OnCanSendReportingReportInternal( + const url::Origin& origin) const; + + virtual void OnCanSetReportingClientInternal(const url::Origin& origin, + const GURL& endpoint) const; + + virtual void OnCanUseReportingClientInternal(const url::Origin& origin, + const GURL& endpoint) const; + private: std::unique_ptr<NetworkDelegate> nested_network_delegate_; };
diff --git a/net/base/layered_network_delegate_unittest.cc b/net/base/layered_network_delegate_unittest.cc index cd9f5d24..b92ee03 100644 --- a/net/base/layered_network_delegate_unittest.cc +++ b/net/base/layered_network_delegate_unittest.cc
@@ -335,6 +335,30 @@ "violating_referrer_header_count"]); } + void OnCanQueueReportingReportInternal( + const url::Origin& origin) const override { + ++(*counters_)["on_can_queue_reporting_report_count"]; + EXPECT_EQ(1, (*counters_)["on_can_queue_reporting_report_count"]); + } + + void OnCanSendReportingReportInternal( + const url::Origin& origin) const override { + ++(*counters_)["on_can_send_reporting_report_count"]; + EXPECT_EQ(1, (*counters_)["on_can_send_reporting_report_count"]); + } + + void OnCanSetReportingClientInternal(const url::Origin& origin, + const GURL& endpoint) const override { + ++(*counters_)["on_can_set_reporting_client_count"]; + EXPECT_EQ(1, (*counters_)["on_can_set_reporting_client_count"]); + } + + void OnCanUseReportingClientInternal(const url::Origin& origin, + const GURL& endpoint) const override { + ++(*counters_)["on_can_use_reporting_client_count"]; + EXPECT_EQ(1, (*counters_)["on_can_use_reporting_client_count"]); + } + private: TestURLRequestContext context_; TestDelegate delegate_;
diff --git a/net/base/network_delegate.cc b/net/base/network_delegate.cc index 960f05f..6344e4d 100644 --- a/net/base/network_delegate.cc +++ b/net/base/network_delegate.cc
@@ -185,6 +185,28 @@ request, target_url, referrer_url); } +bool NetworkDelegate::CanQueueReportingReport(const url::Origin& origin) const { + DCHECK(CalledOnValidThread()); + return OnCanQueueReportingReport(origin); +} + +bool NetworkDelegate::CanSendReportingReport(const url::Origin& origin) const { + DCHECK(CalledOnValidThread()); + return OnCanSendReportingReport(origin); +} + +bool NetworkDelegate::CanSetReportingClient(const url::Origin& origin, + const GURL& endpoint) const { + DCHECK(CalledOnValidThread()); + return OnCanSetReportingClient(origin, endpoint); +} + +bool NetworkDelegate::CanUseReportingClient(const url::Origin& origin, + const GURL& endpoint) const { + DCHECK(CalledOnValidThread()); + return OnCanUseReportingClient(origin, endpoint); +} + void NetworkDelegate::OnResponseStarted(URLRequest* request, int net_error) { OnResponseStarted(request); }
diff --git a/net/base/network_delegate.h b/net/base/network_delegate.h index f602f3c..eaa1e30 100644 --- a/net/base/network_delegate.h +++ b/net/base/network_delegate.h
@@ -24,6 +24,10 @@ class FilePath; } +namespace url { +class Origin; +} + namespace net { // NOTE: Layering violations! @@ -112,6 +116,13 @@ const GURL& target_url, const GURL& referrer_url) const; + bool CanQueueReportingReport(const url::Origin& origin) const; + bool CanSendReportingReport(const url::Origin& origin) const; + bool CanSetReportingClient(const url::Origin& origin, + const GURL& endpoint) const; + bool CanUseReportingClient(const url::Origin& origin, + const GURL& endpoint) const; + private: // This is the interface for subclasses of NetworkDelegate to implement. These // member functions will be called by the respective public notification @@ -292,6 +303,16 @@ const URLRequest& request, const GURL& target_url, const GURL& referrer_url) const = 0; + + virtual bool OnCanQueueReportingReport(const url::Origin& origin) const = 0; + + virtual bool OnCanSendReportingReport(const url::Origin& origin) const = 0; + + virtual bool OnCanSetReportingClient(const url::Origin& origin, + const GURL& endpoint) const = 0; + + virtual bool OnCanUseReportingClient(const url::Origin& origin, + const GURL& endpoint) const = 0; }; } // namespace net
diff --git a/net/base/network_delegate_impl.cc b/net/base/network_delegate_impl.cc index 52d4efc..3ca66c1 100644 --- a/net/base/network_delegate_impl.cc +++ b/net/base/network_delegate_impl.cc
@@ -114,4 +114,24 @@ return false; } +bool NetworkDelegateImpl::OnCanQueueReportingReport( + const url::Origin& origin) const { + return true; +} + +bool NetworkDelegateImpl::OnCanSendReportingReport( + const url::Origin& origin) const { + return true; +} + +bool NetworkDelegateImpl::OnCanSetReportingClient(const url::Origin& origin, + const GURL& endpoint) const { + return true; +} + +bool NetworkDelegateImpl::OnCanUseReportingClient(const url::Origin& origin, + const GURL& endpoint) const { + return true; +} + } // namespace net
diff --git a/net/base/network_delegate_impl.h b/net/base/network_delegate_impl.h index a46942a..16f2d603 100644 --- a/net/base/network_delegate_impl.h +++ b/net/base/network_delegate_impl.h
@@ -20,6 +20,10 @@ class FilePath; } +namespace url { +class Origin; +} + namespace net { class CookieOptions; @@ -98,6 +102,16 @@ const URLRequest& request, const GURL& target_url, const GURL& referrer_url) const override; + + bool OnCanQueueReportingReport(const url::Origin& origin) const override; + + bool OnCanSendReportingReport(const url::Origin& origin) const override; + + bool OnCanSetReportingClient(const url::Origin& origin, + const GURL& endpoint) const override; + + bool OnCanUseReportingClient(const url::Origin& origin, + const GURL& endpoint) const override; }; } // namespace net
diff --git a/net/proxy/proxy_script_fetcher_impl_unittest.cc b/net/proxy/proxy_script_fetcher_impl_unittest.cc index c1bebe74..a1a7e5e 100644 --- a/net/proxy/proxy_script_fetcher_impl_unittest.cc +++ b/net/proxy/proxy_script_fetcher_impl_unittest.cc
@@ -39,7 +39,7 @@ #include "net/socket/transport_client_socket_pool.h" #include "net/ssl/ssl_config_service_defaults.h" #include "net/test/embedded_test_server/embedded_test_server.h" -#include "net/test/embedded_test_server/embedded_test_server_connection_listener.h" +#include "net/test/embedded_test_server/simple_connection_listener.h" #include "net/test/gtest_util.h" #include "net/url_request/url_request_context_storage.h" #include "net/url_request/url_request_file_job.h" @@ -74,36 +74,6 @@ base::string16 text; }; -// Waits for the specified number of connection attempts to be seen. -class WaitForConnectionsListener - : public test_server::EmbeddedTestServerConnectionListener { - public: - explicit WaitForConnectionsListener(int expected_num_connections) - : expected_num_connections_(expected_num_connections), - task_runner_(base::SequencedTaskRunnerHandle::Get()) {} - - void AcceptedSocket(const StreamSocket& socket) override { - ++seen_connections_; - EXPECT_LE(seen_connections_, expected_num_connections_); - if (expected_num_connections_ == seen_connections_) - task_runner_->PostTask(FROM_HERE, run_loop_.QuitClosure()); - } - - void ReadFromSocket(const StreamSocket& socket, int rv) override {} - - void Wait() { run_loop_.Run(); } - - private: - int seen_connections_ = 0; - int expected_num_connections_; - - scoped_refptr<base::SequencedTaskRunner> task_runner_; - - base::RunLoop run_loop_; - - DISALLOW_COPY_AND_ASSIGN(WaitForConnectionsListener); -}; - // A non-mock URL request which can access http:// and file:// urls, in the case // the tests were built with file support. class RequestContext : public URLRequestContext { @@ -543,7 +513,9 @@ int num_requests = 10 + ClientSocketPoolManager::max_sockets_per_pool( HttpNetworkSession::NORMAL_SOCKET_POOL); - WaitForConnectionsListener connection_listener(num_requests); + net::test_server::SimpleConnectionListener connection_listener( + num_requests, net::test_server::SimpleConnectionListener:: + FAIL_ON_ADDITIONAL_CONNECTIONS); test_server_.SetConnectionListener(&connection_listener); ASSERT_TRUE(test_server_.Start()); @@ -562,7 +534,7 @@ pac_fetchers.push_back(std::move(pac_fetcher)); } - connection_listener.Wait(); + connection_listener.WaitForConnections(); // None of the callbacks should have been invoked - all jobs should still be // hung. EXPECT_FALSE(callback.have_result());
diff --git a/net/proxy/proxy_service_mojo_unittest.cc b/net/proxy/proxy_service_mojo_unittest.cc index d2b3526f..46338339 100644 --- a/net/proxy/proxy_service_mojo_unittest.cc +++ b/net/proxy/proxy_service_mojo_unittest.cc
@@ -11,10 +11,8 @@ #include "base/callback_helpers.h" #include "base/memory/ptr_util.h" -#include "base/memory/singleton.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" -#include "mojo/public/cpp/bindings/strong_binding.h" #include "net/base/network_delegate_impl.h" #include "net/base/test_completion_callback.h" #include "net/dns/mock_host_resolver.h" @@ -25,9 +23,9 @@ #include "net/proxy/dhcp_proxy_script_fetcher.h" #include "net/proxy/mock_proxy_script_fetcher.h" #include "net/proxy/mojo_proxy_resolver_factory.h" -#include "net/proxy/mojo_proxy_resolver_factory_impl.h" #include "net/proxy/proxy_config_service_fixed.h" #include "net/proxy/proxy_service.h" +#include "net/proxy/test_mojo_proxy_resolver_factory.h" #include "net/test/event_waiter.h" #include "net/test/gtest_util.h" #include "testing/gmock/include/gmock/gmock.h" @@ -124,34 +122,6 @@ } }; -class InProcessMojoProxyResolverFactory : public MojoProxyResolverFactory { - public: - static InProcessMojoProxyResolverFactory* GetInstance() { - return base::Singleton<InProcessMojoProxyResolverFactory>::get(); - } - - // Overridden from MojoProxyResolverFactory: - std::unique_ptr<base::ScopedClosureRunner> CreateResolver( - const std::string& pac_script, - mojo::InterfaceRequest<interfaces::ProxyResolver> req, - interfaces::ProxyResolverFactoryRequestClientPtr client) override { - factory_->CreateResolver(pac_script, std::move(req), std::move(client)); - return nullptr; - } - - private: - InProcessMojoProxyResolverFactory() { - mojo::MakeStrongBinding(base::MakeUnique<MojoProxyResolverFactoryImpl>(), - mojo::MakeRequest(&factory_)); - } - ~InProcessMojoProxyResolverFactory() override = default; - friend struct base::DefaultSingletonTraits<InProcessMojoProxyResolverFactory>; - - interfaces::ProxyResolverFactoryPtr factory_; - - DISALLOW_COPY_AND_ASSIGN(InProcessMojoProxyResolverFactory); -}; - } // namespace class ProxyServiceMojoTest : public testing::Test, @@ -172,7 +142,7 @@ const std::string& pac_script, mojo::InterfaceRequest<interfaces::ProxyResolver> req, interfaces::ProxyResolverFactoryRequestClientPtr client) override { - InProcessMojoProxyResolverFactory::GetInstance()->CreateResolver( + TestMojoProxyResolverFactory::GetInstance()->CreateResolver( pac_script, std::move(req), std::move(client)); return base::MakeUnique<base::ScopedClosureRunner>( on_delete_closure_.closure());
diff --git a/net/proxy/test_mojo_proxy_resolver_factory.cc b/net/proxy/test_mojo_proxy_resolver_factory.cc new file mode 100644 index 0000000..9a0223a2 --- /dev/null +++ b/net/proxy/test_mojo_proxy_resolver_factory.cc
@@ -0,0 +1,34 @@ +// 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 "net/proxy/test_mojo_proxy_resolver_factory.h" + +#include "base/memory/ptr_util.h" +#include "mojo/public/cpp/bindings/strong_binding.h" +#include "net/proxy/mojo_proxy_resolver_factory_impl.h" + +namespace net { + +TestMojoProxyResolverFactory* TestMojoProxyResolverFactory::GetInstance() { + return base::Singleton<TestMojoProxyResolverFactory>::get(); +} + +std::unique_ptr<base::ScopedClosureRunner> +TestMojoProxyResolverFactory::CreateResolver( + const std::string& pac_script, + mojo::InterfaceRequest<interfaces::ProxyResolver> req, + interfaces::ProxyResolverFactoryRequestClientPtr client) { + resolver_created_ = true; + factory_->CreateResolver(pac_script, std::move(req), std::move(client)); + return nullptr; +} + +TestMojoProxyResolverFactory::TestMojoProxyResolverFactory() { + mojo::MakeStrongBinding(base::MakeUnique<MojoProxyResolverFactoryImpl>(), + mojo::MakeRequest(&factory_)); +} + +TestMojoProxyResolverFactory::~TestMojoProxyResolverFactory() = default; + +} // namespace net
diff --git a/net/proxy/test_mojo_proxy_resolver_factory.h b/net/proxy/test_mojo_proxy_resolver_factory.h new file mode 100644 index 0000000..7be0be4 --- /dev/null +++ b/net/proxy/test_mojo_proxy_resolver_factory.h
@@ -0,0 +1,52 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_PROXY_TEST_MOJO_PROXY_RESOLVER_FACTORY_H_ +#define NET_PROXY_TEST_MOJO_PROXY_RESOLVER_FACTORY_H_ + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "base/memory/singleton.h" +#include "net/proxy/mojo_proxy_resolver_factory.h" + +namespace net { + +// MojoProxyResolverFactory that runs PAC scripts in-process, for tests. +class TestMojoProxyResolverFactory : public MojoProxyResolverFactory { + public: + static TestMojoProxyResolverFactory* GetInstance(); + + // Returns true if CreateResolver was called. + bool resolver_created() { return resolver_created_; } + + // Sets the value returned by resolver_created. Since this is a singleton, + // Serves to avoid with test fixture reuse. + void set_resolver_created(bool resolver_created) { + resolver_created_ = resolver_created; + } + + // Overridden from MojoProxyResolverFactory: + std::unique_ptr<base::ScopedClosureRunner> CreateResolver( + const std::string& pac_script, + mojo::InterfaceRequest<interfaces::ProxyResolver> req, + interfaces::ProxyResolverFactoryRequestClientPtr client) override; + + private: + TestMojoProxyResolverFactory(); + ~TestMojoProxyResolverFactory() override; + + friend struct base::DefaultSingletonTraits<TestMojoProxyResolverFactory>; + + interfaces::ProxyResolverFactoryPtr factory_; + + bool resolver_created_ = false; + + DISALLOW_COPY_AND_ASSIGN(TestMojoProxyResolverFactory); +}; + +} // namespace net + +#endif // NET_PROXY_TEST_MOJO_PROXY_RESOLVER_FACTORY_H_
diff --git a/net/reporting/reporting_context.cc b/net/reporting/reporting_context.cc index f8b3820..6d022be4 100644 --- a/net/reporting/reporting_context.cc +++ b/net/reporting/reporting_context.cc
@@ -40,7 +40,8 @@ : ReportingContext(policy, base::MakeUnique<base::DefaultClock>(), base::MakeUnique<base::DefaultTickClock>(), - ReportingUploader::Create(request_context)) {} + ReportingUploader::Create(request_context), + ReportingDelegate::Create(request_context)) {} }; } // namespace @@ -72,12 +73,13 @@ ReportingContext::ReportingContext(const ReportingPolicy& policy, std::unique_ptr<base::Clock> clock, std::unique_ptr<base::TickClock> tick_clock, - std::unique_ptr<ReportingUploader> uploader) + std::unique_ptr<ReportingUploader> uploader, + std::unique_ptr<ReportingDelegate> delegate) : policy_(policy), clock_(std::move(clock)), tick_clock_(std::move(tick_clock)), uploader_(std::move(uploader)), - delegate_(ReportingDelegate::Create()), + delegate_(std::move(delegate)), cache_(base::MakeUnique<ReportingCache>(this)), endpoint_manager_(base::MakeUnique<ReportingEndpointManager>(this)), delivery_agent_(ReportingDeliveryAgent::Create(this)),
diff --git a/net/reporting/reporting_context.h b/net/reporting/reporting_context.h index c3517da..4467cb0 100644 --- a/net/reporting/reporting_context.h +++ b/net/reporting/reporting_context.h
@@ -72,7 +72,8 @@ ReportingContext(const ReportingPolicy& policy, std::unique_ptr<base::Clock> clock, std::unique_ptr<base::TickClock> tick_clock, - std::unique_ptr<ReportingUploader> uploader); + std::unique_ptr<ReportingUploader> uploader, + std::unique_ptr<ReportingDelegate> delegate); private: ReportingPolicy policy_;
diff --git a/net/reporting/reporting_delegate.cc b/net/reporting/reporting_delegate.cc index 88ff913..25dfdf14 100644 --- a/net/reporting/reporting_delegate.cc +++ b/net/reporting/reporting_delegate.cc
@@ -5,6 +5,8 @@ #include "net/reporting/reporting_delegate.h" #include "base/memory/ptr_util.h" +#include "net/base/network_delegate.h" +#include "net/url_request/url_request_context.h" namespace net { @@ -12,30 +14,49 @@ class ReportingDelegateImpl : public ReportingDelegate { public: - ReportingDelegateImpl() {} + ReportingDelegateImpl(URLRequestContext* request_context) + : request_context_(request_context) { + DCHECK(request_context); + } ~ReportingDelegateImpl() override {} - bool CanQueueReport(const url::Origin& origin) const override { return true; } + bool CanQueueReport(const url::Origin& origin) const override { + return network_delegate() && + network_delegate()->CanQueueReportingReport(origin); + } - bool CanSendReport(const url::Origin& origin) const override { return true; } + bool CanSendReport(const url::Origin& origin) const override { + return network_delegate() && + network_delegate()->CanSendReportingReport(origin); + } bool CanSetClient(const url::Origin& origin, const GURL& endpoint) const override { - return true; + return network_delegate() && + network_delegate()->CanSetReportingClient(origin, endpoint); } bool CanUseClient(const url::Origin& origin, const GURL& endpoint) const override { - return true; + return network_delegate() && + network_delegate()->CanUseReportingClient(origin, endpoint); } + + private: + const NetworkDelegate* network_delegate() const { + return request_context_->network_delegate(); + } + + URLRequestContext* request_context_; }; } // namespace // static -std::unique_ptr<ReportingDelegate> ReportingDelegate::Create() { - return base::MakeUnique<ReportingDelegateImpl>(); +std::unique_ptr<ReportingDelegate> ReportingDelegate::Create( + URLRequestContext* request_context) { + return base::MakeUnique<ReportingDelegateImpl>(request_context); } ReportingDelegate::~ReportingDelegate() {}
diff --git a/net/reporting/reporting_delegate.h b/net/reporting/reporting_delegate.h index 7acf4c76..d2052f6e 100644 --- a/net/reporting/reporting_delegate.h +++ b/net/reporting/reporting_delegate.h
@@ -18,6 +18,8 @@ namespace net { +class URLRequestContext; + class NET_EXPORT ReportingDelegate { public: virtual ~ReportingDelegate(); @@ -38,7 +40,8 @@ virtual bool CanUseClient(const url::Origin& origin, const GURL& endpoint) const = 0; - static std::unique_ptr<ReportingDelegate> Create(); + static std::unique_ptr<ReportingDelegate> Create( + URLRequestContext* request_context); }; } // namespace net
diff --git a/net/reporting/reporting_test_util.cc b/net/reporting/reporting_test_util.cc index 2a7d1e0c..0b8237fb 100644 --- a/net/reporting/reporting_test_util.cc +++ b/net/reporting/reporting_test_util.cc
@@ -17,6 +17,7 @@ #include "net/reporting/reporting_cache.h" #include "net/reporting/reporting_client.h" #include "net/reporting/reporting_context.h" +#include "net/reporting/reporting_delegate.h" #include "net/reporting/reporting_delivery_agent.h" #include "net/reporting/reporting_garbage_collector.h" #include "net/reporting/reporting_persister.h" @@ -103,11 +104,34 @@ url, json, callback, base::Bind(&ErasePendingUpload, &pending_uploads_))); } +TestReportingDelegate::TestReportingDelegate() {} + +TestReportingDelegate::~TestReportingDelegate() {} + +bool TestReportingDelegate::CanQueueReport(const url::Origin& origin) const { + return true; +} + +bool TestReportingDelegate::CanSendReport(const url::Origin& origin) const { + return true; +} + +bool TestReportingDelegate::CanSetClient(const url::Origin& origin, + const GURL& endpoint) const { + return true; +} + +bool TestReportingDelegate::CanUseClient(const url::Origin& origin, + const GURL& endpoint) const { + return true; +} + TestReportingContext::TestReportingContext(const ReportingPolicy& policy) : ReportingContext(policy, base::MakeUnique<base::SimpleTestClock>(), base::MakeUnique<base::SimpleTestTickClock>(), - base::MakeUnique<TestReportingUploader>()), + base::MakeUnique<TestReportingUploader>(), + base::MakeUnique<TestReportingDelegate>()), delivery_timer_(new base::MockTimer(/* retain_user_task= */ false, /* is_repeating= */ false)), garbage_collection_timer_(
diff --git a/net/reporting/reporting_test_util.h b/net/reporting/reporting_test_util.h index 6e64870..9343278 100644 --- a/net/reporting/reporting_test_util.h +++ b/net/reporting/reporting_test_util.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "net/reporting/reporting_context.h" +#include "net/reporting/reporting_delegate.h" #include "net/reporting/reporting_uploader.h" #include "testing/gtest/include/gtest/gtest.h" @@ -76,6 +77,28 @@ DISALLOW_COPY_AND_ASSIGN(TestReportingUploader); }; +class TestReportingDelegate : public ReportingDelegate { + public: + TestReportingDelegate(); + + // ReportingDelegate implementation: + + ~TestReportingDelegate() override; + + bool CanQueueReport(const url::Origin& origin) const override; + + bool CanSendReport(const url::Origin& origin) const override; + + bool CanSetClient(const url::Origin& origin, + const GURL& endpoint) const override; + + bool CanUseClient(const url::Origin& origin, + const GURL& endpoint) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(TestReportingDelegate); +}; + // A test implementation of ReportingContext that uses test versions of // Clock, TickClock, Timer, and ReportingUploader. class TestReportingContext : public ReportingContext { @@ -96,6 +119,9 @@ TestReportingUploader* test_uploader() { return reinterpret_cast<TestReportingUploader*>(uploader()); } + TestReportingDelegate* test_delegate() { + return reinterpret_cast<TestReportingDelegate*>(delegate()); + } private: // Owned by the Persister and GarbageCollector, respectively, but referenced
diff --git a/net/test/embedded_test_server/http_request.cc b/net/test/embedded_test_server/http_request.cc index ef624dc..ecac880 100644 --- a/net/test/embedded_test_server/http_request.cc +++ b/net/test/embedded_test_server/http_request.cc
@@ -110,7 +110,7 @@ // know) anything about the server address. GURL url(header_line_tokens[1]); if (url.is_valid()) { - http_request_->relative_url = url.path(); + http_request_->relative_url = url.PathForRequest(); } else if (header_line_tokens[1][0] == '/') { http_request_->relative_url = header_line_tokens[1]; } else {
diff --git a/net/test/embedded_test_server/simple_connection_listener.cc b/net/test/embedded_test_server/simple_connection_listener.cc new file mode 100644 index 0000000..7cbe4dc --- /dev/null +++ b/net/test/embedded_test_server/simple_connection_listener.cc
@@ -0,0 +1,41 @@ +// 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 "net/test/embedded_test_server/simple_connection_listener.h" + +#include "base/location.h" +#include "base/sequenced_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace net { +namespace test_server { + +SimpleConnectionListener::SimpleConnectionListener( + int expected_connections, + AllowAdditionalConnections allow_additional_connections) + : expected_connections_(expected_connections), + allow_additional_connections_(allow_additional_connections), + run_loop_task_runner_(base::ThreadTaskRunnerHandle::Get()) {} + +SimpleConnectionListener::~SimpleConnectionListener() {} + +void SimpleConnectionListener::AcceptedSocket(const StreamSocket& socket) { + ++seen_connections_; + if (allow_additional_connections_ != ALLOW_ADDITIONAL_CONNECTIONS) + EXPECT_LE(seen_connections_, expected_connections_); + if (seen_connections_ == expected_connections_) + run_loop_task_runner_->PostTask(FROM_HERE, run_loop_.QuitClosure()); +} + +void SimpleConnectionListener::ReadFromSocket(const StreamSocket& socket, + int rv) {} + +void SimpleConnectionListener::WaitForConnections() { + EXPECT_TRUE(run_loop_task_runner_->RunsTasksOnCurrentThread()); + run_loop_.Run(); +} + +} // namespace test_server +} // namespace net
diff --git a/net/test/embedded_test_server/simple_connection_listener.h b/net/test/embedded_test_server/simple_connection_listener.h new file mode 100644 index 0000000..3370cf3 --- /dev/null +++ b/net/test/embedded_test_server/simple_connection_listener.h
@@ -0,0 +1,67 @@ +// 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 NET_TEST_EMBEDDED_TEST_SERVER_SIMPLE_CONNECTION_LISTENER_H_ +#define NET_TEST_EMBEDDED_TEST_SERVER_SIMPLE_CONNECTION_LISTENER_H_ + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/run_loop.h" +#include "net/test/embedded_test_server/embedded_test_server_connection_listener.h" + +namespace base { +class SequencedTaskRunner; +} + +namespace net { + +class StreamSocket; + +namespace test_server { + +// Waits for a specified number of connection attempts to be seen. +class SimpleConnectionListener : public EmbeddedTestServerConnectionListener { + public: + enum AllowAdditionalConnections { + // Add an expect failure if more than the specified number of connections + // are seen. + FAIL_ON_ADDITIONAL_CONNECTIONS, + // Silently ignores extra connection attempts. + ALLOW_ADDITIONAL_CONNECTIONS + }; + + // A connection listener that waits for the specified number of total + // connections when WaitForConnections() is called. Must be created on a + // thread with a SingleThreadedTaskRunner. + SimpleConnectionListener( + int expected_connections, + AllowAdditionalConnections allow_additional_connections); + + // Must be torn down only after the EmbeddedTestServer it's attached to is + // shut down. + ~SimpleConnectionListener() override; + + void AcceptedSocket(const StreamSocket& socket) override; + void ReadFromSocket(const StreamSocket& socket, int rv) override; + + // Wait until the expected number of connections have been seen. + void WaitForConnections(); + + private: + int seen_connections_ = 0; + + const int expected_connections_; + const AllowAdditionalConnections allow_additional_connections_; + + const scoped_refptr<base::SequencedTaskRunner> run_loop_task_runner_; + + base::RunLoop run_loop_; + + DISALLOW_COPY_AND_ASSIGN(SimpleConnectionListener); +}; + +} // namespace test_server +} // namespace net + +#endif // NET_TEST_EMBEDDED_TEST_SERVER_SIMPLE_CONNECTION_LISTENER_H_
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc index 40e842d..3309974b 100644 --- a/net/url_request/url_request_context_builder.cc +++ b/net/url_request/url_request_context_builder.cc
@@ -133,13 +133,23 @@ }; // Define a context class that can self-manage the ownership of its components -// via a UrlRequestContextStorage object. -class ContainerURLRequestContext : public URLRequestContext { +// via a UrlRequestContextStorage object. Since it cancels requests in its +// destructor, it's not safe to subclass this. +class ContainerURLRequestContext final : public URLRequestContext { public: explicit ContainerURLRequestContext( const scoped_refptr<base::SingleThreadTaskRunner>& file_task_runner) : file_task_runner_(file_task_runner), storage_(this) {} - ~ContainerURLRequestContext() override { AssertNoURLRequests(); } + + ~ContainerURLRequestContext() override { + // Shut down the ProxyService, as it may have pending URLRequests using this + // context. Since this cancels requests, it's not safe to subclass this, as + // some parts of the URLRequestContext may then be torn down before this + // cancels the ProxyService's URLRequests. + proxy_service()->OnShutdown(); + + AssertNoURLRequests(); + } URLRequestContextStorage* storage() { return &storage_; @@ -358,22 +368,6 @@ } storage->set_host_resolver(std::move(host_resolver_)); - if (!proxy_service_) { - // TODO(willchan): Switch to using this code when - // ProxyService::CreateSystemProxyConfigService()'s signature doesn't suck. -#if !defined(OS_LINUX) && !defined(OS_ANDROID) - if (!proxy_config_service_) { - proxy_config_service_ = ProxyService::CreateSystemProxyConfigService( - base::ThreadTaskRunnerHandle::Get().get(), - context->GetFileTaskRunner()); - } -#endif // !defined(OS_LINUX) && !defined(OS_ANDROID) - proxy_service_ = ProxyService::CreateUsingSystemProxyResolver( - std::move(proxy_config_service_), - context->net_log()); - } - storage->set_proxy_service(std::move(proxy_service_)); - storage->set_ssl_config_service(new SSLConfigServiceDefaults); if (!http_auth_handler_factory_) { @@ -440,6 +434,23 @@ base::MakeUnique<URLRequestThrottlerManager>()); } + if (!proxy_service_) { +#if !defined(OS_LINUX) && !defined(OS_ANDROID) + // TODO(willchan): Switch to using this code when + // ProxyService::CreateSystemProxyConfigService()'s signature doesn't suck. + if (!proxy_config_service_) { + proxy_config_service_ = ProxyService::CreateSystemProxyConfigService( + base::ThreadTaskRunnerHandle::Get().get(), + context->GetFileTaskRunner()); + } +#endif // !defined(OS_LINUX) && !defined(OS_ANDROID) + proxy_service_ = + CreateProxyService(std::move(proxy_config_service_), context.get(), + context->host_resolver(), + context->network_delegate(), context->net_log()); + } + storage->set_proxy_service(std::move(proxy_service_)); + HttpNetworkSession::Params network_session_params; SetHttpNetworkSessionComponents(context.get(), &network_session_params); http_network_session_params_.ConfigureSessionParams(&network_session_params); @@ -525,4 +536,14 @@ return std::move(context); } +std::unique_ptr<ProxyService> URLRequestContextBuilder::CreateProxyService( + std::unique_ptr<ProxyConfigService> proxy_config_service, + URLRequestContext* url_request_context, + HostResolver* host_resolver, + NetworkDelegate* network_delegate, + NetLog* net_log) { + return ProxyService::CreateUsingSystemProxyResolver( + std::move(proxy_config_service), net_log); +} + } // namespace net
diff --git a/net/url_request/url_request_context_builder.h b/net/url_request/url_request_context_builder.h index 2c04437..a622625 100644 --- a/net/url_request/url_request_context_builder.h +++ b/net/url_request/url_request_context_builder.h
@@ -112,7 +112,7 @@ }; URLRequestContextBuilder(); - ~URLRequestContextBuilder(); + virtual ~URLRequestContextBuilder(); // Sets a name for this URLRequestContext. Currently the name is used in // MemoryDumpProvier to annotate memory usage. The name does not need to be @@ -143,6 +143,11 @@ std::unique_ptr<ProxyConfigService> proxy_config_service) { proxy_config_service_ = std::move(proxy_config_service); } + + // Sets the proxy service. If one is not provided, by default, uses system + // libraries to evaluate PAC scripts, if available (And if not, skips PAC + // resolution). Subclasses may override CreateProxyService for different + // default behavior. void set_proxy_service(std::unique_ptr<ProxyService> proxy_service) { proxy_service_ = std::move(proxy_service); } @@ -331,6 +336,17 @@ std::unique_ptr<URLRequestContext> Build(); + protected: + // Lets subclasses override ProxyService creation, using a ProxyService that + // uses the URLRequestContext itself to get PAC scripts. When this method is + // invoked, the URLRequestContext is not yet ready to service requests. + virtual std::unique_ptr<ProxyService> CreateProxyService( + std::unique_ptr<ProxyConfigService> proxy_config_service, + URLRequestContext* url_request_context, + HostResolver* host_resolver, + NetworkDelegate* network_delegate, + NetLog* net_log); + private: const char* name_; bool enable_brotli_;
diff --git a/net/url_request/url_request_context_builder_v8.cc b/net/url_request/url_request_context_builder_v8.cc new file mode 100644 index 0000000..d16f4d7 --- /dev/null +++ b/net/url_request/url_request_context_builder_v8.cc
@@ -0,0 +1,64 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/url_request/url_request_context_builder_v8.h" + +#include "base/logging.h" +#include "net/proxy/proxy_config_service.h" +#include "net/proxy/proxy_script_fetcher_impl.h" +#include "net/proxy/proxy_service_v8.h" + +#ifdef ENABLE_NET_MOJO +#include "net/proxy/proxy_service_mojo.h" +#endif + +namespace net { + +URLRequestContextBuilderV8::URLRequestContextBuilderV8() + : dhcp_fetcher_factory_(new DhcpProxyScriptFetcherFactory()) {} + +URLRequestContextBuilderV8::~URLRequestContextBuilderV8() = default; + +std::unique_ptr<ProxyService> URLRequestContextBuilderV8::CreateProxyService( + std::unique_ptr<ProxyConfigService> proxy_config_service, + URLRequestContext* url_request_context, + HostResolver* host_resolver, + NetworkDelegate* network_delegate, + NetLog* net_log) { + DCHECK(url_request_context); + DCHECK(host_resolver); + + if (!use_v8_) { + return URLRequestContextBuilder::CreateProxyService( + std::move(proxy_config_service), url_request_context, host_resolver, + network_delegate, net_log); + } + + std::unique_ptr<net::DhcpProxyScriptFetcher> dhcp_proxy_script_fetcher = + dhcp_fetcher_factory_->Create(url_request_context); + std::unique_ptr<net::ProxyScriptFetcher> proxy_script_fetcher = + base::MakeUnique<ProxyScriptFetcherImpl>(url_request_context); + std::unique_ptr<ProxyService> proxy_service; +#ifdef ENABLE_NET_MOJO + if (mojo_proxy_resolver_factory_) { + proxy_service = CreateProxyServiceUsingMojoFactory( + mojo_proxy_resolver_factory_, std::move(proxy_config_service), + proxy_script_fetcher.release(), std::move(dhcp_proxy_script_fetcher), + host_resolver, net_log, network_delegate); + } +#endif // ENABLE_NET_MOJO + if (!proxy_service) { + proxy_service = CreateProxyServiceUsingV8ProxyResolver( + std::move(proxy_config_service), proxy_script_fetcher.release(), + std::move(dhcp_proxy_script_fetcher), host_resolver, net_log, + network_delegate); + } + + proxy_service->set_quick_check_enabled(quick_check_enabled_); + proxy_service->set_sanitize_url_policy(sanitize_url_policy_); + + return proxy_service; +} + +} // namespace net
diff --git a/net/url_request/url_request_context_builder_v8.h b/net/url_request/url_request_context_builder_v8.h new file mode 100644 index 0000000..e44c359 --- /dev/null +++ b/net/url_request/url_request_context_builder_v8.h
@@ -0,0 +1,92 @@ +// 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 NET_URL_REQUEST_URL_REQUEST_CONTEXT_BUILDER_V8_H_ +#define NET_URL_REQUEST_URL_REQUEST_CONTEXT_BUILDER_V8_H_ + +#include <memory> + +#include "base/macros.h" +#include "net/proxy/dhcp_proxy_script_fetcher_factory.h" +#include "net/proxy/proxy_service.h" +#include "net/url_request/url_request_context_builder.h" + +namespace net { + +class HostResolver; +class NetLog; +class NetworkDelegate; +class MojoProxyResolverFactory; +class URLRequestContext; + +// Specialization of URLRequestContextBuilder that can create a ProxyService +// that uses a V8 ProxyResolver. PAC scripts are run by V8 in process, by +// default, but a Mojo factory can be passed in for out-of-process resolution. +// PAC scripts will be fetched using the request context itself. If a +// PoxyService is set directly via the URLRequestContextBuilder API, it will be +// used instead of the one this class normally creates. +class URLRequestContextBuilderV8 : public URLRequestContextBuilder { + public: + URLRequestContextBuilderV8(); + ~URLRequestContextBuilderV8() override; + + // If set to false, the URLrequestContextBuilder will create a ProxyService, + // which won't use V8. Defaults to true. + void set_use_v8(bool use_v8) { use_v8_ = use_v8; } + + // Sets whether quick PAC checks are enabled. Defaults to true. Ignored if + // use_v8 is false. + void set_quick_check_enabled(bool quick_check_enabled) { + quick_check_enabled_ = quick_check_enabled; + } + + // Sets policy for sanitizing URLs before passing them a PAC. Defaults to + // ProxyService::SanitizeUrlPolicy::SAFE. Ignored if use_v8 is false. + void set_pac_sanitize_url_policy( + net::ProxyService::SanitizeUrlPolicy sanitize_url_policy) { + sanitize_url_policy_ = sanitize_url_policy; + } + + // Overrides default DhcpProxyScriptFetcherFactory. Ignored if use_v8 is + // false. + void set_dhcp_fetcher_factory( + std::unique_ptr<DhcpProxyScriptFetcherFactory> dhcp_fetcher_factory) { + dhcp_fetcher_factory = std::move(dhcp_fetcher_factory_); + } + +#ifdef ENABLE_NET_MOJO + // Sets Mojo factory used to create ProxyResolvers. If not set, V8 will be + // used in process instead of Mojo. Ignored if use_v8 is false. The passed in + // factory must outlive the URLRequestContext the builder creates. + void set_mojo_proxy_resolver_factory( + MojoProxyResolverFactory* mojo_proxy_resolver_factory) { + mojo_proxy_resolver_factory_ = mojo_proxy_resolver_factory; + } +#endif // ENABLE_NET_MOJO + + private: + std::unique_ptr<ProxyService> CreateProxyService( + std::unique_ptr<ProxyConfigService> proxy_config_service, + URLRequestContext* url_request_context, + HostResolver* host_resolver, + NetworkDelegate* network_delegate, + NetLog* net_log) override; + + bool use_v8_ = true; + bool quick_check_enabled_ = true; + net::ProxyService::SanitizeUrlPolicy sanitize_url_policy_ = + net::ProxyService::SanitizeUrlPolicy::SAFE; + + std::unique_ptr<DhcpProxyScriptFetcherFactory> dhcp_fetcher_factory_; + +#ifdef ENABLE_NET_MOJO + MojoProxyResolverFactory* mojo_proxy_resolver_factory_ = nullptr; +#endif + + DISALLOW_COPY_AND_ASSIGN(URLRequestContextBuilderV8); +}; + +} // namespace net + +#endif // NET_URL_REQUEST_URL_REQUEST_CONTEXT_BUILDER_V8_H_
diff --git a/net/url_request/url_request_context_builder_v8_unittest.cc b/net/url_request/url_request_context_builder_v8_unittest.cc new file mode 100644 index 0000000..f302d35 --- /dev/null +++ b/net/url_request/url_request_context_builder_v8_unittest.cc
@@ -0,0 +1,131 @@ +// 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 "net/url_request/url_request_context_builder_v8.h" + +#include "base/run_loop.h" +#include "base/strings/stringprintf.h" +#include "net/base/host_port_pair.h" +#include "net/proxy/proxy_config.h" +#include "net/proxy/proxy_config_service_fixed.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_request.h" +#include "net/test/embedded_test_server/http_response.h" +#include "net/test/embedded_test_server/simple_connection_listener.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_test_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" +#include "url/gurl.h" + +#ifdef ENABLE_NET_MOJO +#include "net/proxy/test_mojo_proxy_resolver_factory.h" +#endif + +namespace net { + +namespace { + +const char kPacPath[] = "/super.pac"; + +// When kPacPath is requested, returns a PAC script that uses the test server +// itself as the proxy. +std::unique_ptr<test_server::HttpResponse> HandlePacRequest( + const test_server::HttpRequest& request) { + if (request.relative_url != kPacPath) + return nullptr; + std::unique_ptr<test_server::BasicHttpResponse> response = + base::MakeUnique<test_server::BasicHttpResponse>(); + response->set_content(base::StringPrintf( + "function FindProxyForURL(url, host) { return 'PROXY %s;'; }", + HostPortPair::FromURL(request.base_url).ToString().c_str())); + response->set_content_type("text/html"); + return std::move(response); +} + +class URLRequestContextBuilderV8Test : public PlatformTest { + protected: + URLRequestContextBuilderV8Test() { + test_server_.RegisterRequestHandler(base::Bind(&HandlePacRequest)); + test_server_.AddDefaultHandlers( + base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); + } + + EmbeddedTestServer test_server_; + URLRequestContextBuilderV8 builder_; +}; + +TEST_F(URLRequestContextBuilderV8Test, V8InProcess) { + EXPECT_TRUE(test_server_.Start()); + + builder_.set_proxy_config_service(base::MakeUnique<ProxyConfigServiceFixed>( + ProxyConfig::CreateFromCustomPacURL(test_server_.GetURL(kPacPath)))); + std::unique_ptr<URLRequestContext> context(builder_.Build()); + + TestDelegate delegate; + std::unique_ptr<URLRequest> request(context->CreateRequest( + GURL("http://hats:12345/echoheader?Foo"), DEFAULT_PRIORITY, &delegate, + TRAFFIC_ANNOTATION_FOR_TESTS)); + request->SetExtraRequestHeaderByName("Foo", "Bar", false); + request->Start(); + base::RunLoop().Run(); + EXPECT_EQ("Bar", delegate.data_received()); +} + +// Makes sure that pending PAC requests are correctly shutdown during teardown. +TEST_F(URLRequestContextBuilderV8Test, V8InProcessShutdownWithHungRequest) { + test_server::SimpleConnectionListener connection_listener( + 1, test_server::SimpleConnectionListener::FAIL_ON_ADDITIONAL_CONNECTIONS); + test_server_.SetConnectionListener(&connection_listener); + EXPECT_TRUE(test_server_.Start()); + + builder_.set_proxy_config_service(base::MakeUnique<ProxyConfigServiceFixed>( + ProxyConfig::CreateFromCustomPacURL(test_server_.GetURL("/hung")))); + + std::unique_ptr<URLRequestContext> context(builder_.Build()); + TestDelegate delegate; + std::unique_ptr<URLRequest> request(context->CreateRequest( + GURL("http://hats:12345/echoheader?Foo"), DEFAULT_PRIORITY, &delegate, + TRAFFIC_ANNOTATION_FOR_TESTS)); + request->Start(); + connection_listener.WaitForConnections(); + + // Have to shut down the test server before |connection_listener| falls out of + // scope. + EXPECT_TRUE(test_server_.ShutdownAndWaitUntilComplete()); + + // Tearing down the URLRequestContext should not cause an AssertNoURLRequests + // failure. +} + +#ifdef ENABLE_NET_MOJO +TEST_F(URLRequestContextBuilderV8Test, MojoProxyResolver) { + EXPECT_TRUE(test_server_.Start()); + TestMojoProxyResolverFactory::GetInstance()->set_resolver_created(false); + + builder_.set_proxy_config_service(base::MakeUnique<ProxyConfigServiceFixed>( + ProxyConfig::CreateFromCustomPacURL(test_server_.GetURL(kPacPath)))); + builder_.set_mojo_proxy_resolver_factory( + TestMojoProxyResolverFactory::GetInstance()); + + std::unique_ptr<URLRequestContext> context(builder_.Build()); + TestDelegate delegate; + std::unique_ptr<URLRequest> request(context->CreateRequest( + GURL("http://hats:12345/echoheader?Foo"), DEFAULT_PRIORITY, &delegate, + TRAFFIC_ANNOTATION_FOR_TESTS)); + request->SetExtraRequestHeaderByName("Foo", "Bar", false); + request->Start(); + base::RunLoop().Run(); + EXPECT_EQ("Bar", delegate.data_received()); + + // Make sure that the Mojo factory was used. + EXPECT_TRUE(TestMojoProxyResolverFactory::GetInstance()->resolver_created()); +} +#endif // ENABLE_NET_MOJO + +} // namespace + +} // namespace net
diff --git a/services/identity/OWNERS b/services/identity/OWNERS index 2654e53..3532cb2 100644 --- a/services/identity/OWNERS +++ b/services/identity/OWNERS
@@ -1,2 +1,4 @@ blundell@chromium.org msarda@chromium.org + +# COMPONENT: Services>SignIn
diff --git a/services/ui/service.cc b/services/ui/service.cc index f44fe04..59b670f 100644 --- a/services/ui/service.cc +++ b/services/ui/service.cc
@@ -100,9 +100,9 @@ #endif } -void Service::InitializeResources(service_manager::Connector* connector) { +bool Service::InitializeResources(service_manager::Connector* connector) { if (ui::ResourceBundle::HasSharedInstance()) - return; + return true; std::set<std::string> resource_paths; resource_paths.insert(kResourceFileStrings); @@ -112,7 +112,10 @@ catalog::ResourceLoader loader; filesystem::mojom::DirectoryPtr directory; connector->BindInterface(catalog::mojom::kServiceName, &directory); - CHECK(loader.OpenFiles(std::move(directory), resource_paths)); + if (!loader.OpenFiles(std::move(directory), resource_paths)) { + LOG(ERROR) << "Service failed to open resource files."; + return false; + } ui::RegisterPathProvider(); @@ -125,6 +128,7 @@ ui::SCALE_FACTOR_100P); rb.AddDataPackFromFile(loader.TakeFile(kResourceFile200), ui::SCALE_FACTOR_200P); + return true; } Service::UserState* Service::GetUserState( @@ -156,7 +160,11 @@ if (test_config_) ui::test::EnableTestConfigForPlatformWindows(); - InitializeResources(context()->connector()); + // If resources are unavailable do not complete start-up. + if (!InitializeResources(context()->connector())) { + context()->QuitNow(); + return; + } #if defined(USE_OZONE) // The ozone platform can provide its own event source. So initialize the
diff --git a/services/ui/service.h b/services/ui/service.h index 0bf1f15d..6bf2463 100644 --- a/services/ui/service.h +++ b/services/ui/service.h
@@ -87,7 +87,9 @@ using UserIdToUserState = std::map<ws::UserId, std::unique_ptr<UserState>>; - void InitializeResources(service_manager::Connector* connector); + // Attempts to initialize the resource bundle. Returns true if successful, + // otherwise false if resources cannot be loaded. + bool InitializeResources(service_manager::Connector* connector); // Returns the user specific state for the user id of |remote_identity|. // Service owns the return value.
diff --git a/services/video_capture/BUILD.gn b/services/video_capture/BUILD.gn index c834b7aa..be8833cb 100644 --- a/services/video_capture/BUILD.gn +++ b/services/video_capture/BUILD.gn
@@ -51,10 +51,6 @@ "//services/video_capture/public/interfaces", "//services/video_capture/public/interfaces:constants", ] - - data_deps = [ - ":manifest", - ] } source_set("tests") {
diff --git a/services/video_capture/device_factory_media_to_mojo_adapter.cc b/services/video_capture/device_factory_media_to_mojo_adapter.cc index b7241270..60b2b370 100644 --- a/services/video_capture/device_factory_media_to_mojo_adapter.cc +++ b/services/video_capture/device_factory_media_to_mojo_adapter.cc
@@ -35,17 +35,10 @@ translated_device_info.descriptor = device_info.descriptor; for (const auto& format : device_info.supported_formats) { media::VideoCaptureFormat translated_format; - switch (format.pixel_format) { - case media::PIXEL_FORMAT_I420: - case media::PIXEL_FORMAT_MJPEG: - translated_format.pixel_format = media::PIXEL_FORMAT_I420; - break; - case media::PIXEL_FORMAT_Y16: - translated_format.pixel_format = media::PIXEL_FORMAT_Y16; - default: - // Any other format cannot be consumed by VideoCaptureDeviceClient. - continue; - } + translated_format.pixel_format = + (format.pixel_format == media::PIXEL_FORMAT_Y16) + ? media::PIXEL_FORMAT_Y16 + : media::PIXEL_FORMAT_I420; translated_format.frame_size = format.frame_size; translated_format.frame_rate = format.frame_rate; translated_format.pixel_storage = media::PIXEL_STORAGE_CPU;
diff --git a/services/video_capture/public/cpp/BUILD.gn b/services/video_capture/public/cpp/BUILD.gn index 4362d25..59094d47 100644 --- a/services/video_capture/public/cpp/BUILD.gn +++ b/services/video_capture/public/cpp/BUILD.gn
@@ -4,6 +4,8 @@ source_set("cpp") { sources = [ + "constants.cc", + "constants.h", "device_to_feedback_observer_adapter.cc", "device_to_feedback_observer_adapter.h", "receiver_media_to_mojo_adapter.cc",
diff --git a/services/video_capture/public/cpp/constants.cc b/services/video_capture/public/cpp/constants.cc new file mode 100644 index 0000000..37a25ed --- /dev/null +++ b/services/video_capture/public/cpp/constants.cc
@@ -0,0 +1,12 @@ +// 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/video_capture/public/cpp/constants.h" + +namespace video_capture { + +const base::Feature kMojoVideoCapture{"MojoVideoCapture", + base::FEATURE_DISABLED_BY_DEFAULT}; + +} // namespace video_capture
diff --git a/services/video_capture/public/cpp/constants.h b/services/video_capture/public/cpp/constants.h new file mode 100644 index 0000000..9a970a5 --- /dev/null +++ b/services/video_capture/public/cpp/constants.h
@@ -0,0 +1,16 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_VIDEO_CAPTURE_PUBLIC_CPP_CONSTANTS_H_ +#define SERVICES_VIDEO_CAPTURE_PUBLIC_CPP_CONSTANTS_H_ + +#include "base/feature_list.h" + +namespace video_capture { + +extern const base::Feature kMojoVideoCapture; + +} // namespace video_capture + +#endif // SERVICES_VIDEO_CAPTURE_PUBLIC_CPP_CONSTANTS_H_
diff --git a/services/video_capture/service_manifest.json b/services/video_capture/service_manifest.json index 4e5bffc37..62d76da 100644 --- a/services/video_capture/service_manifest.json +++ b/services/video_capture/service_manifest.json
@@ -4,7 +4,7 @@ "interface_provider_specs": { "service_manager:connector": { "provides": { - "production": [ "*" ], + "capture": [ "video_capture::mojom::DeviceFactoryProvider" ], "tests": [ "*" ] }, "requires": {
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 3b368499..abe0cfa 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -240,6 +240,18 @@ "test": "latency_unittests" }, { + "args": [ + "--ozone-platform=headless", + "--override-use-software-gl-for-tests", + "--test-launcher-filter-file=../../testing/buildbot/filters/mash.browser_tests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "hard_timeout": 900 + }, + "test": "mash_browser_tests" + }, + { "swarming": { "can_use_on_swarming_builders": true },
diff --git a/testing/buildbot/filters/mash.browser_tests.filter b/testing/buildbot/filters/mash.browser_tests.filter index 0fb95080..c260db5 100644 --- a/testing/buildbot/filters/mash.browser_tests.filter +++ b/testing/buildbot/filters/mash.browser_tests.filter
@@ -1,4 +1,3 @@ -BrowserTest.* # Failing test -BrowserTest.FullscreenBookmarkBar @@ -15,25 +14,7 @@ -ExtensionsLoadTestWithLoginScreenApps.CommandLineExtensionsDontLoad # Trying to whitelist -AppWindowApiTest.AlphaEnabledHasPermissions -AppWindowApiTest.AlphaEnabledInStable -AppWindowApiTest.AlphaEnabledNoPermissions -AppWindowApiTest.AlphaEnabledWrongFrameType -AppWindowApiTest.AlwaysOnTopNoPermissions -AppWindowApiTest.AlwaysOnTopWithOldPermissions -AppWindowApiTest.AlwaysOnTopWithPermissions -AppWindowApiTest.Get -AppWindowApiTest.ImeWindowHasPermissions -AppWindowApiTest.ImeWindowNoPermissions -AppWindowApiTest.ImeWindowNotFullscreen -AppWindowApiTest.SetShapeHasPerm -AppWindowApiTest.SetShapeNoPerm -AppWindowApiTest.VisibleOnAllWorkspacesInStable -BluetoothInternalsTest.Startup_BluetoothInternals -BootstrapTest.CleanUpFailedUser -BootstrapTest.PRE_CleanUpFailedUser BrowserDialogTest.Invoke -BrowsingDataRemoverTransportSecurityStateBrowserTest.ClearTransportSecurityState CastSessionBrowserTest.CreateAndDestroy ChromeContentRendererClientSearchBoxTest.RewriteThumbnailURL ChromeRenderFrameObserverTest.SkipCapturingSubFrames @@ -42,25 +23,10 @@ ChromeRenderViewTest.ImagesBlockedByDefault ChromeRenderViewTest.JSBlockSentAfterPageLoad ChromeRenderViewTest.PluginsTemporarilyAllowed -ChromeServiceWorkerManifestFetchTest.OtherOrigin -ChromeServiceWorkerManifestFetchTest.OtherOriginUseCredentials -ChromeServiceWorkerManifestFetchTest.SameOrigin -ChromeServiceWorkerManifestFetchTest.SameOriginUseCredentials -ChromeServiceWorkerTest.CanCloseIncognitoWindowWithServiceWorkerController -ChromeServiceWorkerTest.CanShutDownWithRegisteredServiceWorker -ChromeServiceWorkerTest.FailRegisterServiceWorkerWhenJSDisabled -ChromeServiceWorkerTest.FallbackMainResourceRequestWhenJSDisabled -ConstrainedWebDialogBrowserTest.ReleaseWebContents -ContentVerifierPolicyTest.PRE_PolicyCorruptedOnStartup -ContentVerifierPolicyTest.PolicyCorruptedOnStartup CreateNewFolder/FileManagerBrowserTest.Test/0 CreateNewFolder/FileManagerBrowserTest.Test/1 CreateNewFolder/FileManagerBrowserTest.Test/2 CreateNewFolder/FileManagerBrowserTest.Test/3 -DefaultTaskDialog/FileManagerBrowserTest.Test/0 -DefaultTaskDialog/FileManagerBrowserTest.Test/1 -DefaultTaskDialog/FileManagerBrowserTest.Test/2 -Delete/FileManagerBrowserTest.Test/1 DeviceStatusCollectorNetworkInterfacesTest.NetworkInterfaces DeviceStatusCollectorNetworkInterfacesTest.ReportIfPublicSession DeviceStatusCollectorTest.ActivityCrossingMidnight @@ -89,44 +55,8 @@ DeviceStatusCollectorTest.TestVolumeInfo DeviceStatusCollectorTest.Times DeviceStatusCollectorTest.VersionInfo -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/0 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/1 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/10 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/11 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/12 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/13 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/14 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/15 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/16 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/17 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/18 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/19 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/2 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/20 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/21 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/22 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/24 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/3 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/4 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/5 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/6 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/7 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/8 -DirectoryTreeContextMenu/FileManagerBrowserTest.Test/9 DownloadInterruptReasonEnumsSynced.DownloadInterruptReasonEnumsSynced -DriveSpecific/FileManagerBrowserTest.Test/0 -DriveSpecific/FileManagerBrowserTest.Test/1 -DriveSpecific/FileManagerBrowserTest.Test/2 -DriveSpecific/FileManagerBrowserTest.Test/3 -DriveSpecific/FileManagerBrowserTest.Test/4 -DriveSpecific/FileManagerBrowserTest.Test/5 -DriveSpecific/FileManagerBrowserTest.Test/6 -ExecuteDefaultTaskOnDownloads/FileManagerBrowserTest.Test/0 -ExecuteDefaultTaskOnDownloads/FileManagerBrowserTest.Test/1 -ExecuteDefaultTaskOnDrive/FileManagerBrowserTest.Test/0 ExtensionDetermineDownloadFilenameInternal.ExtensionDetermineDownloadFilenameInternal -FolderShortcuts/FileManagerBrowserTest.Test/0 -FolderShortcuts/FileManagerBrowserTest.Test/1 FormAutocompleteTest.AjaxSucceeded_FilledFormIsInvisible FormAutocompleteTest.AjaxSucceeded_FilledFormStillVisible FormAutocompleteTest.AjaxSucceeded_FormlessElements @@ -158,18 +88,6 @@ FormClassifierTest.kChangeFormWithTreePasswordFieldsHTML InstantProcessNavigationTest.ForkForNavigationsFromInstantProcess InstantProcessNavigationTest.ForkForNavigationsToSearchURLs -MultiProfileFileManagerBrowserTest.BasicDownloads -MultiProfileFileManagerBrowserTest.BasicDrive -MultiProfileFileManagerBrowserTest.PRE_BasicDownloads -OpenAudioFiles/FileManagerBrowserTest.Test/1 -OpenAudioFiles/FileManagerBrowserTest.Test/2 -OpenAudioFiles/FileManagerBrowserTest.Test/3 -OpenAudioFiles/FileManagerBrowserTest.Test/4 -OpenAudioFiles/FileManagerBrowserTest.Test/5 -OpenAudioFiles/FileManagerBrowserTest.Test/6 -OpenFileDialog/FileManagerBrowserTest.Test/0 -OpenFileDialog/FileManagerBrowserTest.Test/2 -OpenFileDialog/FileManagerBrowserTest.Test/5 PageClickTrackerTest.PageClickTrackerClickDisabledInputDoesNotResetClickCounter PageClickTrackerTest.PageClickTrackerDisabledInputClickedNoEvent PageClickTrackerTest.PageClickTrackerInputClicked @@ -219,13 +137,5 @@ PolicyCertVerifierTest.VerifyTrustedCert PolicyCertVerifierTest.VerifyUntrustedCert PolicyCertVerifierTest.VerifyUsingAdditionalTrustAnchor -Providers/FileManagerBrowserTest.Test/0 -Providers/FileManagerBrowserTest.Test/1 -Providers/FileManagerBrowserTest.Test/2 -Providers/FileManagerBrowserTest.Test/3 -RestoreGeometry/FileManagerBrowserTest.Test/0 -RestoreGeometry/FileManagerBrowserTest.Test/1 ScriptContextTest.GetEffectiveDocumentURL -ShowGridView/FileManagerBrowserTest.Test/0 -ShowGridView/FileManagerBrowserTest.Test/1 SiteEngagementUiBrowserTest.Basic
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cssom/interfaces-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cssom/interfaces-expected.txt index 4c43e9b..05df14d5 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/cssom/interfaces-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/cssom/interfaces-expected.txt
@@ -1,12 +1,12 @@ This is a testharness.js-based test. -Found 187 tests; 156 PASS, 31 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 187 tests; 159 PASS, 28 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Document interface: attribute styleSheets FAIL Document must be primary interface of document assert_equals: document's prototype is not Document.prototype expected object "[object Document]" but got object "[object HTMLDocument]" FAIL Stringification of document assert_equals: class string of document expected "[object Document]" but got "[object HTMLDocument]" PASS Document interface: document must inherit property "styleSheets" with the proper type (0) -FAIL Document must be primary interface of new Document() assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Stringification of new Document() assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "styleSheets" with the proper type (0) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" +PASS Document must be primary interface of new Document() +PASS Stringification of new Document() +PASS Document interface: new Document() must inherit property "styleSheets" with the proper type (0) PASS ProcessingInstruction interface: attribute sheet PASS HTMLElement interface: attribute style PASS SVGElement interface: attribute style
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/adopted-callback-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/adopted-callback-expected.txt deleted file mode 100644 index f201c5f..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/adopted-callback-expected.txt +++ /dev/null
@@ -1,61 +0,0 @@ -This is a testharness.js-based test. -Found 57 tests; 49 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN. -PASS Inserting a custom element into the owner document must not enqueue and invoke adoptedCallback -PASS Inserting a custom element into the document of the template elements must enqueue and invoke adoptedCallback -PASS Moving a custom element from the owner document into the document of the template elements must enqueue and invoke adoptedCallback -PASS Inserting an ancestor of custom element into the document of the template elements must enqueue and invoke adoptedCallback -PASS Moving an ancestor of custom element from the owner document into the document of the template elements must enqueue and invoke adoptedCallback -PASS Inserting a custom element into a shadow tree in the document of the template elements must enqueue and invoke adoptedCallback -PASS Inserting the shadow host of a custom element into the document of the template elements must enqueue and invoke adoptedCallback -PASS Moving the shadow host of a custom element from the owner document into the document of the template elements must enqueue and invoke adoptedCallback -PASS Inserting a custom element into a detached shadow tree that belongs to the document of the template elements must enqueue and invoke adoptedCallback -FAIL Inserting a custom element into a new document must enqueue and invoke adoptedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Moving a custom element from the owner document into a new document must enqueue and invoke adoptedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Inserting an ancestor of custom element into a new document must enqueue and invoke adoptedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Moving an ancestor of custom element from the owner document into a new document must enqueue and invoke adoptedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Inserting a custom element into a shadow tree in a new document must enqueue and invoke adoptedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Inserting the shadow host of a custom element into a new document must enqueue and invoke adoptedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Moving the shadow host of a custom element from the owner document into a new document must enqueue and invoke adoptedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Inserting a custom element into a detached shadow tree that belongs to a new document must enqueue and invoke adoptedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -PASS Inserting a custom element into a cloned document must enqueue and invoke adoptedCallback -PASS Moving a custom element from the owner document into a cloned document must enqueue and invoke adoptedCallback -PASS Inserting an ancestor of custom element into a cloned document must enqueue and invoke adoptedCallback -PASS Moving an ancestor of custom element from the owner document into a cloned document must enqueue and invoke adoptedCallback -PASS Inserting a custom element into a shadow tree in a cloned document must enqueue and invoke adoptedCallback -PASS Inserting the shadow host of a custom element into a cloned document must enqueue and invoke adoptedCallback -PASS Moving the shadow host of a custom element from the owner document into a cloned document must enqueue and invoke adoptedCallback -PASS Inserting a custom element into a detached shadow tree that belongs to a cloned document must enqueue and invoke adoptedCallback -PASS Inserting a custom element into a document created by createHTMLDocument must enqueue and invoke adoptedCallback -PASS Moving a custom element from the owner document into a document created by createHTMLDocument must enqueue and invoke adoptedCallback -PASS Inserting an ancestor of custom element into a document created by createHTMLDocument must enqueue and invoke adoptedCallback -PASS Moving an ancestor of custom element from the owner document into a document created by createHTMLDocument must enqueue and invoke adoptedCallback -PASS Inserting a custom element into a shadow tree in a document created by createHTMLDocument must enqueue and invoke adoptedCallback -PASS Inserting the shadow host of a custom element into a document created by createHTMLDocument must enqueue and invoke adoptedCallback -PASS Moving the shadow host of a custom element from the owner document into a document created by createHTMLDocument must enqueue and invoke adoptedCallback -PASS Inserting a custom element into a detached shadow tree that belongs to a document created by createHTMLDocument must enqueue and invoke adoptedCallback -PASS Inserting a custom element into an HTML document created by createDocument must enqueue and invoke adoptedCallback -PASS Moving a custom element from the owner document into an HTML document created by createDocument must enqueue and invoke adoptedCallback -PASS Inserting an ancestor of custom element into an HTML document created by createDocument must enqueue and invoke adoptedCallback -PASS Moving an ancestor of custom element from the owner document into an HTML document created by createDocument must enqueue and invoke adoptedCallback -PASS Inserting a custom element into a shadow tree in an HTML document created by createDocument must enqueue and invoke adoptedCallback -PASS Inserting the shadow host of a custom element into an HTML document created by createDocument must enqueue and invoke adoptedCallback -PASS Moving the shadow host of a custom element from the owner document into an HTML document created by createDocument must enqueue and invoke adoptedCallback -PASS Inserting a custom element into a detached shadow tree that belongs to an HTML document created by createDocument must enqueue and invoke adoptedCallback -PASS Inserting a custom element into the document of an iframe must enqueue and invoke adoptedCallback -PASS Moving a custom element from the owner document into the document of an iframe must enqueue and invoke adoptedCallback -PASS Inserting an ancestor of custom element into the document of an iframe must enqueue and invoke adoptedCallback -PASS Moving an ancestor of custom element from the owner document into the document of an iframe must enqueue and invoke adoptedCallback -PASS Inserting a custom element into a shadow tree in the document of an iframe must enqueue and invoke adoptedCallback -PASS Inserting the shadow host of a custom element into the document of an iframe must enqueue and invoke adoptedCallback -PASS Moving the shadow host of a custom element from the owner document into the document of an iframe must enqueue and invoke adoptedCallback -PASS Inserting a custom element into a detached shadow tree that belongs to the document of an iframe must enqueue and invoke adoptedCallback -PASS Inserting a custom element into an HTML document fetched by XHR must enqueue and invoke adoptedCallback -PASS Moving a custom element from the owner document into an HTML document fetched by XHR must enqueue and invoke adoptedCallback -PASS Inserting an ancestor of custom element into an HTML document fetched by XHR must enqueue and invoke adoptedCallback -PASS Moving an ancestor of custom element from the owner document into an HTML document fetched by XHR must enqueue and invoke adoptedCallback -PASS Inserting a custom element into a shadow tree in an HTML document fetched by XHR must enqueue and invoke adoptedCallback -PASS Inserting the shadow host of a custom element into an HTML document fetched by XHR must enqueue and invoke adoptedCallback -PASS Moving the shadow host of a custom element from the owner document into an HTML document fetched by XHR must enqueue and invoke adoptedCallback -PASS Inserting a custom element into a detached shadow tree that belongs to an HTML document fetched by XHR must enqueue and invoke adoptedCallback -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/connected-callbacks-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/connected-callbacks-expected.txt deleted file mode 100644 index 6a4c52a..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/connected-callbacks-expected.txt +++ /dev/null
@@ -1,43 +0,0 @@ -This is a testharness.js-based test. -PASS Inserting a custom element into the document must enqueue and invoke connectedCallback -PASS Inserting an ancestor of custom element into the document must enqueue and invoke connectedCallback -PASS Inserting a custom element into a shadow tree in the document must enqueue and invoke connectedCallback -PASS Inserting the shadow host of a custom element into the document must enqueue and invoke connectedCallback -PASS Inserting a custom element into a detached shadow tree that belongs to the document must not enqueue and invoke connectedCallback -PASS Inserting a custom element into the document of the template elements must enqueue and invoke connectedCallback -PASS Inserting an ancestor of custom element into the document of the template elements must enqueue and invoke connectedCallback -PASS Inserting a custom element into a shadow tree in the document of the template elements must enqueue and invoke connectedCallback -PASS Inserting the shadow host of a custom element into the document of the template elements must enqueue and invoke connectedCallback -PASS Inserting a custom element into a detached shadow tree that belongs to the document of the template elements must not enqueue and invoke connectedCallback -FAIL Inserting a custom element into a new document must enqueue and invoke connectedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Inserting an ancestor of custom element into a new document must enqueue and invoke connectedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Inserting a custom element into a shadow tree in a new document must enqueue and invoke connectedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Inserting the shadow host of a custom element into a new document must enqueue and invoke connectedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Inserting a custom element into a detached shadow tree that belongs to a new document must not enqueue and invoke connectedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -PASS Inserting a custom element into a cloned document must enqueue and invoke connectedCallback -PASS Inserting an ancestor of custom element into a cloned document must enqueue and invoke connectedCallback -PASS Inserting a custom element into a shadow tree in a cloned document must enqueue and invoke connectedCallback -PASS Inserting the shadow host of a custom element into a cloned document must enqueue and invoke connectedCallback -PASS Inserting a custom element into a detached shadow tree that belongs to a cloned document must not enqueue and invoke connectedCallback -PASS Inserting a custom element into a document created by createHTMLDocument must enqueue and invoke connectedCallback -PASS Inserting an ancestor of custom element into a document created by createHTMLDocument must enqueue and invoke connectedCallback -PASS Inserting a custom element into a shadow tree in a document created by createHTMLDocument must enqueue and invoke connectedCallback -PASS Inserting the shadow host of a custom element into a document created by createHTMLDocument must enqueue and invoke connectedCallback -PASS Inserting a custom element into a detached shadow tree that belongs to a document created by createHTMLDocument must not enqueue and invoke connectedCallback -PASS Inserting a custom element into an HTML document created by createDocument must enqueue and invoke connectedCallback -PASS Inserting an ancestor of custom element into an HTML document created by createDocument must enqueue and invoke connectedCallback -PASS Inserting a custom element into a shadow tree in an HTML document created by createDocument must enqueue and invoke connectedCallback -PASS Inserting the shadow host of a custom element into an HTML document created by createDocument must enqueue and invoke connectedCallback -PASS Inserting a custom element into a detached shadow tree that belongs to an HTML document created by createDocument must not enqueue and invoke connectedCallback -PASS Inserting a custom element into the document of an iframe must enqueue and invoke connectedCallback -PASS Inserting an ancestor of custom element into the document of an iframe must enqueue and invoke connectedCallback -PASS Inserting a custom element into a shadow tree in the document of an iframe must enqueue and invoke connectedCallback -PASS Inserting the shadow host of a custom element into the document of an iframe must enqueue and invoke connectedCallback -PASS Inserting a custom element into a detached shadow tree that belongs to the document of an iframe must not enqueue and invoke connectedCallback -PASS Inserting a custom element into an HTML document fetched by XHR must enqueue and invoke connectedCallback -PASS Inserting an ancestor of custom element into an HTML document fetched by XHR must enqueue and invoke connectedCallback -PASS Inserting a custom element into a shadow tree in an HTML document fetched by XHR must enqueue and invoke connectedCallback -PASS Inserting the shadow host of a custom element into an HTML document fetched by XHR must enqueue and invoke connectedCallback -PASS Inserting a custom element into a detached shadow tree that belongs to an HTML document fetched by XHR must not enqueue and invoke connectedCallback -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/disconnected-callbacks-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/disconnected-callbacks-expected.txt deleted file mode 100644 index 9994c59..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/disconnected-callbacks-expected.txt +++ /dev/null
@@ -1,43 +0,0 @@ -This is a testharness.js-based test. -PASS Removing a custom element from the document must enqueue and invoke disconnectedCallback -PASS Removing an ancestor of custom element from the document must enqueue and invoke disconnectedCallback -PASS Removing a custom element from a shadow tree in the document must enqueue and invoke disconnectedCallback -PASS Removing the shadow host of a custom element from athe document must enqueue and invoke disconnectedCallback -PASS Removing a custom element from a detached shadow tree that belongs to the document must not enqueue and invoke disconnectedCallback -PASS Removing a custom element from the document of the template elements must enqueue and invoke disconnectedCallback -PASS Removing an ancestor of custom element from the document of the template elements must enqueue and invoke disconnectedCallback -PASS Removing a custom element from a shadow tree in the document of the template elements must enqueue and invoke disconnectedCallback -PASS Removing the shadow host of a custom element from athe document of the template elements must enqueue and invoke disconnectedCallback -PASS Removing a custom element from a detached shadow tree that belongs to the document of the template elements must not enqueue and invoke disconnectedCallback -FAIL Removing a custom element from a new document must enqueue and invoke disconnectedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Removing an ancestor of custom element from a new document must enqueue and invoke disconnectedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Removing a custom element from a shadow tree in a new document must enqueue and invoke disconnectedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Removing the shadow host of a custom element from aa new document must enqueue and invoke disconnectedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Removing a custom element from a detached shadow tree that belongs to a new document must not enqueue and invoke disconnectedCallback promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -PASS Removing a custom element from a cloned document must enqueue and invoke disconnectedCallback -PASS Removing an ancestor of custom element from a cloned document must enqueue and invoke disconnectedCallback -PASS Removing a custom element from a shadow tree in a cloned document must enqueue and invoke disconnectedCallback -PASS Removing the shadow host of a custom element from aa cloned document must enqueue and invoke disconnectedCallback -PASS Removing a custom element from a detached shadow tree that belongs to a cloned document must not enqueue and invoke disconnectedCallback -PASS Removing a custom element from a document created by createHTMLDocument must enqueue and invoke disconnectedCallback -PASS Removing an ancestor of custom element from a document created by createHTMLDocument must enqueue and invoke disconnectedCallback -PASS Removing a custom element from a shadow tree in a document created by createHTMLDocument must enqueue and invoke disconnectedCallback -PASS Removing the shadow host of a custom element from aa document created by createHTMLDocument must enqueue and invoke disconnectedCallback -PASS Removing a custom element from a detached shadow tree that belongs to a document created by createHTMLDocument must not enqueue and invoke disconnectedCallback -PASS Removing a custom element from an HTML document created by createDocument must enqueue and invoke disconnectedCallback -PASS Removing an ancestor of custom element from an HTML document created by createDocument must enqueue and invoke disconnectedCallback -PASS Removing a custom element from a shadow tree in an HTML document created by createDocument must enqueue and invoke disconnectedCallback -PASS Removing the shadow host of a custom element from aan HTML document created by createDocument must enqueue and invoke disconnectedCallback -PASS Removing a custom element from a detached shadow tree that belongs to an HTML document created by createDocument must not enqueue and invoke disconnectedCallback -PASS Removing a custom element from the document of an iframe must enqueue and invoke disconnectedCallback -PASS Removing an ancestor of custom element from the document of an iframe must enqueue and invoke disconnectedCallback -PASS Removing a custom element from a shadow tree in the document of an iframe must enqueue and invoke disconnectedCallback -PASS Removing the shadow host of a custom element from athe document of an iframe must enqueue and invoke disconnectedCallback -PASS Removing a custom element from a detached shadow tree that belongs to the document of an iframe must not enqueue and invoke disconnectedCallback -PASS Removing a custom element from an HTML document fetched by XHR must enqueue and invoke disconnectedCallback -PASS Removing an ancestor of custom element from an HTML document fetched by XHR must enqueue and invoke disconnectedCallback -PASS Removing a custom element from a shadow tree in an HTML document fetched by XHR must enqueue and invoke disconnectedCallback -PASS Removing the shadow host of a custom element from aan HTML document fetched by XHR must enqueue and invoke disconnectedCallback -PASS Removing a custom element from a detached shadow tree that belongs to an HTML document fetched by XHR must not enqueue and invoke disconnectedCallback -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt index b7b5bf9..142a37f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt
@@ -5,7 +5,7 @@ PASS HTML parser must not instantiate a custom element defined inside an frame in frame element's owner document PASS HTML parser must use the registry of window.document in a document created by document.implementation.createHTMLDocument() FAIL HTML parser must use the registry of window.document in a document created by document.implementation.createXHTMLDocument() assert_true: expected true got false -FAIL HTML parser must use the registry of window.document in a document created by new Document Illegal constructor +PASS HTML parser must use the registry of window.document in a document created by new Document PASS HTML parser must use the registry of window.document in a document created by XMLHttpRequest Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/upgrading-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/upgrading-expected.txt deleted file mode 100644 index 4fedcfe..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/upgrading-expected.txt +++ /dev/null
@@ -1,28 +0,0 @@ -This is a testharness.js-based test. -PASS Creating an element in the document of the template elements must not enqueue a custom element upgrade reaction because the document does not have a browsing context -PASS Creating an element in the document of the template elements and inserting into the document must not enqueue a custom element upgrade reaction -PASS Creating an element in the document of the template elements and adopting back to a document with browsing context must enqueue a custom element upgrade reaction -FAIL Creating an element in a new document must not enqueue a custom element upgrade reaction because the document does not have a browsing context promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Creating an element in a new document and inserting into the document must not enqueue a custom element upgrade reaction promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -FAIL Creating an element in a new document and adopting back to a document with browsing context must enqueue a custom element upgrade reaction promise_test: Unhandled rejection with value: object "TypeError: Illegal constructor" -PASS Creating an element in a cloned document must not enqueue a custom element upgrade reaction because the document does not have a browsing context -PASS Creating an element in a cloned document and inserting into the document must not enqueue a custom element upgrade reaction -PASS Creating an element in a cloned document and adopting back to a document with browsing context must enqueue a custom element upgrade reaction -PASS Creating an element in a document created by createHTMLDocument must not enqueue a custom element upgrade reaction because the document does not have a browsing context -PASS Creating an element in a document created by createHTMLDocument and inserting into the document must not enqueue a custom element upgrade reaction -PASS Creating an element in a document created by createHTMLDocument and adopting back to a document with browsing context must enqueue a custom element upgrade reaction -PASS Creating an element in an HTML document created by createDocument must not enqueue a custom element upgrade reaction because the document does not have a browsing context -PASS Creating an element in an HTML document created by createDocument and inserting into the document must not enqueue a custom element upgrade reaction -PASS Creating an element in an HTML document created by createDocument and adopting back to a document with browsing context must enqueue a custom element upgrade reaction -PASS Creating an element in an HTML document fetched by XHR must not enqueue a custom element upgrade reaction because the document does not have a browsing context -PASS Creating an element in an HTML document fetched by XHR and inserting into the document must not enqueue a custom element upgrade reaction -PASS Creating an element in an HTML document fetched by XHR and adopting back to a document with browsing context must enqueue a custom element upgrade reaction -PASS Creating an element in the document of an iframe must not enqueue a custom element upgrade reaction if there is no matching definition -PASS Creating an element in the document of an iframe must enqueue a custom element upgrade reaction if there is a matching definition -PASS "define" in the document of an iframe must not enqueue a custom element upgrade reaction on a disconnected unresolved custom element -PASS Inserting an unresolved custom element into the document of an iframe must enqueue a custom element upgrade reaction -PASS "define" in the document of an iframe must enqueue a custom element upgrade reaction on a connected unresolved custom element -PASS Adopting (and leaving disconnceted) an unresolved custom element into the document of an iframe must not enqueue a custom element upgrade reaction -PASS Adopting and inserting an unresolved custom element into the document of an iframe must enqueue a custom element upgrade reaction -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/events/Event-dispatch-bubbles-false-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/dom/events/Event-dispatch-bubbles-false-expected.txt index cf63220..dbfb754 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/dom/events/Event-dispatch-bubbles-false-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/dom/events/Event-dispatch-bubbles-false-expected.txt
@@ -2,7 +2,7 @@ PASS In window.document with click event PASS In window.document with load event FAIL In window.document.cloneNode(true) assert_array_equals: targets lengths differ, expected 8 got 0 -FAIL In new Document() Illegal constructor +PASS In new Document() PASS In DOMImplementation.createHTMLDocument() Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/events/Event-dispatch-bubbles-true-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/dom/events/Event-dispatch-bubbles-true-expected.txt index dbee77a..da032a1 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/dom/events/Event-dispatch-bubbles-true-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/dom/events/Event-dispatch-bubbles-true-expected.txt
@@ -2,7 +2,7 @@ PASS In window.document with click event PASS In window.document with load event FAIL In window.document.cloneNode(true) assert_array_equals: targets lengths differ, expected 14 got 0 -FAIL In new Document() Illegal constructor +PASS In new Document() PASS In DOMImplementation.createHTMLDocument() Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/interfaces-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/dom/interfaces-expected.txt index 7b4a17dc..ce44fe68 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/dom/interfaces-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/dom/interfaces-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 1570 tests; 1440 PASS, 130 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 1570 tests; 1565 PASS, 5 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Test driver PASS Event interface: existence and properties of interface object PASS Event interface object length @@ -260,131 +260,131 @@ PASS Document interface: operation append([object Object],[object Object]) PASS Document interface: operation querySelector(DOMString) PASS Document interface: operation querySelectorAll(DOMString) -FAIL Document interface: new Document() must inherit property "implementation" with the proper type (0) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "URL" with the proper type (1) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "documentURI" with the proper type (2) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "origin" with the proper type (3) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "compatMode" with the proper type (4) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "characterSet" with the proper type (5) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "charset" with the proper type (6) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "inputEncoding" with the proper type (7) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "contentType" with the proper type (8) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "doctype" with the proper type (9) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "documentElement" with the proper type (10) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "getElementsByTagName" with the proper type (11) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling getElementsByTagName(DOMString) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "getElementsByTagNameNS" with the proper type (12) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling getElementsByTagNameNS(DOMString,DOMString) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "getElementsByClassName" with the proper type (13) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling getElementsByClassName(DOMString) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "createElement" with the proper type (14) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling createElement(DOMString,ElementCreationOptions) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "createElementNS" with the proper type (15) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling createElementNS(DOMString,DOMString,ElementCreationOptions) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "createDocumentFragment" with the proper type (16) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "createTextNode" with the proper type (17) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling createTextNode(DOMString) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "createCDATASection" with the proper type (18) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling createCDATASection(DOMString) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "createComment" with the proper type (19) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling createComment(DOMString) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "createProcessingInstruction" with the proper type (20) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling createProcessingInstruction(DOMString,DOMString) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "importNode" with the proper type (21) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling importNode(Node,boolean) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "adoptNode" with the proper type (22) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling adoptNode(Node) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "createAttribute" with the proper type (23) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling createAttribute(DOMString) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "createAttributeNS" with the proper type (24) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling createAttributeNS(DOMString,DOMString) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "createEvent" with the proper type (25) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling createEvent(DOMString) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "createRange" with the proper type (26) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "createNodeIterator" with the proper type (27) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling createNodeIterator(Node,unsigned long,NodeFilter) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "createTreeWalker" with the proper type (28) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling createTreeWalker(Node,unsigned long,NodeFilter) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "getElementById" with the proper type (29) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling getElementById(DOMString) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "children" with the proper type (30) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "firstElementChild" with the proper type (31) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "lastElementChild" with the proper type (32) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "childElementCount" with the proper type (33) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "prepend" with the proper type (34) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling prepend([object Object],[object Object]) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "append" with the proper type (35) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling append([object Object],[object Object]) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "querySelector" with the proper type (36) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling querySelector(DOMString) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document() must inherit property "querySelectorAll" with the proper type (37) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: calling querySelectorAll(DOMString) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "ELEMENT_NODE" with the proper type (0) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "ATTRIBUTE_NODE" with the proper type (1) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "TEXT_NODE" with the proper type (2) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "CDATA_SECTION_NODE" with the proper type (3) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "ENTITY_REFERENCE_NODE" with the proper type (4) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "ENTITY_NODE" with the proper type (5) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "PROCESSING_INSTRUCTION_NODE" with the proper type (6) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "COMMENT_NODE" with the proper type (7) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "DOCUMENT_NODE" with the proper type (8) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "DOCUMENT_TYPE_NODE" with the proper type (9) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "DOCUMENT_FRAGMENT_NODE" with the proper type (10) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "NOTATION_NODE" with the proper type (11) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "nodeType" with the proper type (12) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "nodeName" with the proper type (13) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "baseURI" with the proper type (14) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "isConnected" with the proper type (15) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "ownerDocument" with the proper type (16) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "getRootNode" with the proper type (17) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: calling getRootNode(GetRootNodeOptions) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "parentNode" with the proper type (18) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "parentElement" with the proper type (19) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "hasChildNodes" with the proper type (20) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "childNodes" with the proper type (21) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "firstChild" with the proper type (22) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "lastChild" with the proper type (23) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "previousSibling" with the proper type (24) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "nextSibling" with the proper type (25) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "nodeValue" with the proper type (26) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "textContent" with the proper type (27) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "normalize" with the proper type (28) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "cloneNode" with the proper type (29) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: calling cloneNode(boolean) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "isEqualNode" with the proper type (30) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: calling isEqualNode(Node) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "isSameNode" with the proper type (31) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: calling isSameNode(Node) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "DOCUMENT_POSITION_DISCONNECTED" with the proper type (32) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "DOCUMENT_POSITION_PRECEDING" with the proper type (33) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "DOCUMENT_POSITION_FOLLOWING" with the proper type (34) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "DOCUMENT_POSITION_CONTAINS" with the proper type (35) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "DOCUMENT_POSITION_CONTAINED_BY" with the proper type (36) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC" with the proper type (37) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "compareDocumentPosition" with the proper type (38) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: calling compareDocumentPosition(Node) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "contains" with the proper type (39) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: calling contains(Node) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "lookupPrefix" with the proper type (40) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: calling lookupPrefix(DOMString) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "lookupNamespaceURI" with the proper type (41) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: calling lookupNamespaceURI(DOMString) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "isDefaultNamespace" with the proper type (42) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: calling isDefaultNamespace(DOMString) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "insertBefore" with the proper type (43) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: calling insertBefore(Node,Node) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "appendChild" with the proper type (44) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: calling appendChild(Node) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "replaceChild" with the proper type (45) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: calling replaceChild(Node,Node) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: new Document() must inherit property "removeChild" with the proper type (46) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Node interface: calling removeChild(Node) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL EventTarget interface: new Document() must inherit property "addEventListener" with the proper type (0) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL EventTarget interface: calling addEventListener(DOMString,EventListener,[object Object],[object Object]) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL EventTarget interface: new Document() must inherit property "removeEventListener" with the proper type (1) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL EventTarget interface: calling removeEventListener(DOMString,EventListener,[object Object],[object Object]) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL EventTarget interface: new Document() must inherit property "dispatchEvent" with the proper type (2) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL EventTarget interface: calling dispatchEvent(Event) on new Document() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" +PASS Document interface: new Document() must inherit property "implementation" with the proper type (0) +PASS Document interface: new Document() must inherit property "URL" with the proper type (1) +PASS Document interface: new Document() must inherit property "documentURI" with the proper type (2) +PASS Document interface: new Document() must inherit property "origin" with the proper type (3) +PASS Document interface: new Document() must inherit property "compatMode" with the proper type (4) +PASS Document interface: new Document() must inherit property "characterSet" with the proper type (5) +PASS Document interface: new Document() must inherit property "charset" with the proper type (6) +PASS Document interface: new Document() must inherit property "inputEncoding" with the proper type (7) +PASS Document interface: new Document() must inherit property "contentType" with the proper type (8) +PASS Document interface: new Document() must inherit property "doctype" with the proper type (9) +PASS Document interface: new Document() must inherit property "documentElement" with the proper type (10) +PASS Document interface: new Document() must inherit property "getElementsByTagName" with the proper type (11) +PASS Document interface: calling getElementsByTagName(DOMString) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "getElementsByTagNameNS" with the proper type (12) +PASS Document interface: calling getElementsByTagNameNS(DOMString,DOMString) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "getElementsByClassName" with the proper type (13) +PASS Document interface: calling getElementsByClassName(DOMString) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "createElement" with the proper type (14) +PASS Document interface: calling createElement(DOMString,ElementCreationOptions) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "createElementNS" with the proper type (15) +PASS Document interface: calling createElementNS(DOMString,DOMString,ElementCreationOptions) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "createDocumentFragment" with the proper type (16) +PASS Document interface: new Document() must inherit property "createTextNode" with the proper type (17) +PASS Document interface: calling createTextNode(DOMString) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "createCDATASection" with the proper type (18) +PASS Document interface: calling createCDATASection(DOMString) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "createComment" with the proper type (19) +PASS Document interface: calling createComment(DOMString) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "createProcessingInstruction" with the proper type (20) +PASS Document interface: calling createProcessingInstruction(DOMString,DOMString) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "importNode" with the proper type (21) +PASS Document interface: calling importNode(Node,boolean) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "adoptNode" with the proper type (22) +PASS Document interface: calling adoptNode(Node) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "createAttribute" with the proper type (23) +PASS Document interface: calling createAttribute(DOMString) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "createAttributeNS" with the proper type (24) +PASS Document interface: calling createAttributeNS(DOMString,DOMString) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "createEvent" with the proper type (25) +PASS Document interface: calling createEvent(DOMString) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "createRange" with the proper type (26) +PASS Document interface: new Document() must inherit property "createNodeIterator" with the proper type (27) +PASS Document interface: calling createNodeIterator(Node,unsigned long,NodeFilter) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "createTreeWalker" with the proper type (28) +PASS Document interface: calling createTreeWalker(Node,unsigned long,NodeFilter) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "getElementById" with the proper type (29) +PASS Document interface: calling getElementById(DOMString) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "children" with the proper type (30) +PASS Document interface: new Document() must inherit property "firstElementChild" with the proper type (31) +PASS Document interface: new Document() must inherit property "lastElementChild" with the proper type (32) +PASS Document interface: new Document() must inherit property "childElementCount" with the proper type (33) +PASS Document interface: new Document() must inherit property "prepend" with the proper type (34) +PASS Document interface: calling prepend([object Object],[object Object]) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "append" with the proper type (35) +PASS Document interface: calling append([object Object],[object Object]) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "querySelector" with the proper type (36) +PASS Document interface: calling querySelector(DOMString) on new Document() with too few arguments must throw TypeError +PASS Document interface: new Document() must inherit property "querySelectorAll" with the proper type (37) +PASS Document interface: calling querySelectorAll(DOMString) on new Document() with too few arguments must throw TypeError +PASS Node interface: new Document() must inherit property "ELEMENT_NODE" with the proper type (0) +PASS Node interface: new Document() must inherit property "ATTRIBUTE_NODE" with the proper type (1) +PASS Node interface: new Document() must inherit property "TEXT_NODE" with the proper type (2) +PASS Node interface: new Document() must inherit property "CDATA_SECTION_NODE" with the proper type (3) +PASS Node interface: new Document() must inherit property "ENTITY_REFERENCE_NODE" with the proper type (4) +PASS Node interface: new Document() must inherit property "ENTITY_NODE" with the proper type (5) +PASS Node interface: new Document() must inherit property "PROCESSING_INSTRUCTION_NODE" with the proper type (6) +PASS Node interface: new Document() must inherit property "COMMENT_NODE" with the proper type (7) +PASS Node interface: new Document() must inherit property "DOCUMENT_NODE" with the proper type (8) +PASS Node interface: new Document() must inherit property "DOCUMENT_TYPE_NODE" with the proper type (9) +PASS Node interface: new Document() must inherit property "DOCUMENT_FRAGMENT_NODE" with the proper type (10) +PASS Node interface: new Document() must inherit property "NOTATION_NODE" with the proper type (11) +PASS Node interface: new Document() must inherit property "nodeType" with the proper type (12) +PASS Node interface: new Document() must inherit property "nodeName" with the proper type (13) +PASS Node interface: new Document() must inherit property "baseURI" with the proper type (14) +PASS Node interface: new Document() must inherit property "isConnected" with the proper type (15) +PASS Node interface: new Document() must inherit property "ownerDocument" with the proper type (16) +PASS Node interface: new Document() must inherit property "getRootNode" with the proper type (17) +PASS Node interface: calling getRootNode(GetRootNodeOptions) on new Document() with too few arguments must throw TypeError +PASS Node interface: new Document() must inherit property "parentNode" with the proper type (18) +PASS Node interface: new Document() must inherit property "parentElement" with the proper type (19) +PASS Node interface: new Document() must inherit property "hasChildNodes" with the proper type (20) +PASS Node interface: new Document() must inherit property "childNodes" with the proper type (21) +PASS Node interface: new Document() must inherit property "firstChild" with the proper type (22) +PASS Node interface: new Document() must inherit property "lastChild" with the proper type (23) +PASS Node interface: new Document() must inherit property "previousSibling" with the proper type (24) +PASS Node interface: new Document() must inherit property "nextSibling" with the proper type (25) +PASS Node interface: new Document() must inherit property "nodeValue" with the proper type (26) +PASS Node interface: new Document() must inherit property "textContent" with the proper type (27) +PASS Node interface: new Document() must inherit property "normalize" with the proper type (28) +PASS Node interface: new Document() must inherit property "cloneNode" with the proper type (29) +PASS Node interface: calling cloneNode(boolean) on new Document() with too few arguments must throw TypeError +PASS Node interface: new Document() must inherit property "isEqualNode" with the proper type (30) +PASS Node interface: calling isEqualNode(Node) on new Document() with too few arguments must throw TypeError +PASS Node interface: new Document() must inherit property "isSameNode" with the proper type (31) +PASS Node interface: calling isSameNode(Node) on new Document() with too few arguments must throw TypeError +PASS Node interface: new Document() must inherit property "DOCUMENT_POSITION_DISCONNECTED" with the proper type (32) +PASS Node interface: new Document() must inherit property "DOCUMENT_POSITION_PRECEDING" with the proper type (33) +PASS Node interface: new Document() must inherit property "DOCUMENT_POSITION_FOLLOWING" with the proper type (34) +PASS Node interface: new Document() must inherit property "DOCUMENT_POSITION_CONTAINS" with the proper type (35) +PASS Node interface: new Document() must inherit property "DOCUMENT_POSITION_CONTAINED_BY" with the proper type (36) +PASS Node interface: new Document() must inherit property "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC" with the proper type (37) +PASS Node interface: new Document() must inherit property "compareDocumentPosition" with the proper type (38) +PASS Node interface: calling compareDocumentPosition(Node) on new Document() with too few arguments must throw TypeError +PASS Node interface: new Document() must inherit property "contains" with the proper type (39) +PASS Node interface: calling contains(Node) on new Document() with too few arguments must throw TypeError +PASS Node interface: new Document() must inherit property "lookupPrefix" with the proper type (40) +PASS Node interface: calling lookupPrefix(DOMString) on new Document() with too few arguments must throw TypeError +PASS Node interface: new Document() must inherit property "lookupNamespaceURI" with the proper type (41) +PASS Node interface: calling lookupNamespaceURI(DOMString) on new Document() with too few arguments must throw TypeError +PASS Node interface: new Document() must inherit property "isDefaultNamespace" with the proper type (42) +PASS Node interface: calling isDefaultNamespace(DOMString) on new Document() with too few arguments must throw TypeError +PASS Node interface: new Document() must inherit property "insertBefore" with the proper type (43) +PASS Node interface: calling insertBefore(Node,Node) on new Document() with too few arguments must throw TypeError +PASS Node interface: new Document() must inherit property "appendChild" with the proper type (44) +PASS Node interface: calling appendChild(Node) on new Document() with too few arguments must throw TypeError +PASS Node interface: new Document() must inherit property "replaceChild" with the proper type (45) +PASS Node interface: calling replaceChild(Node,Node) on new Document() with too few arguments must throw TypeError +PASS Node interface: new Document() must inherit property "removeChild" with the proper type (46) +PASS Node interface: calling removeChild(Node) on new Document() with too few arguments must throw TypeError +PASS EventTarget interface: new Document() must inherit property "addEventListener" with the proper type (0) +PASS EventTarget interface: calling addEventListener(DOMString,EventListener,[object Object],[object Object]) on new Document() with too few arguments must throw TypeError +PASS EventTarget interface: new Document() must inherit property "removeEventListener" with the proper type (1) +PASS EventTarget interface: calling removeEventListener(DOMString,EventListener,[object Object],[object Object]) on new Document() with too few arguments must throw TypeError +PASS EventTarget interface: new Document() must inherit property "dispatchEvent" with the proper type (2) +PASS EventTarget interface: calling dispatchEvent(Event) on new Document() with too few arguments must throw TypeError PASS XMLDocument interface: existence and properties of interface object PASS XMLDocument interface object length PASS XMLDocument interface object name
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-constructor-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-constructor-expected.txt index bfd1f56..8318e20 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-constructor-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-constructor-expected.txt
@@ -1,8 +1,8 @@ This is a testharness.js-based test. -FAIL new Document(): interfaces Illegal constructor -FAIL new Document(): children Illegal constructor -FAIL new Document(): metadata Illegal constructor -FAIL new Document(): characterSet aliases Illegal constructor -FAIL new Document(): URL parsing Illegal constructor +PASS new Document(): interfaces +PASS new Document(): children +PASS new Document(): metadata +PASS new Document(): characterSet aliases +FAIL new Document(): URL parsing assert_equals: expected "http://example.org/?%C3%A4" but got "http://example.org/?ä" Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-constructor-svg.svg b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-constructor-svg.svg new file mode 100644 index 0000000..28aaf16 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-constructor-svg.svg
@@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="windows-1252"?> +<!-- Using windows-1252 to ensure that new Document() doesn't inherit utf-8 + from the parent document. --> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:html="http://www.w3.org/1999/xhtml" + width="100%" height="100%" viewBox="0 0 800 600"> +<title>Document constructor</title> +<html:script src="/resources/testharness.js"></html:script> +<html:script src="/resources/testharnessreport.js"></html:script> +<html:script><![CDATA[ +test(function() { + var doc = new Document(); + assert_true(doc instanceof Node, "Should be a Node"); + assert_true(doc instanceof Document, "Should be a Document"); + assert_false(doc instanceof XMLDocument, "Should not be an XMLDocument"); + assert_equals(Object.getPrototypeOf(doc), Document.prototype, + "Document should be the primary interface"); +}, "new Document(): interfaces") + +test(function() { + var doc = new Document(); + assert_equals(doc.firstChild, null, "firstChild"); + assert_equals(doc.lastChild, null, "lastChild"); + assert_equals(doc.doctype, null, "doctype"); + assert_equals(doc.documentElement, null, "documentElement"); + assert_array_equals(doc.childNodes, [], "childNodes"); +}, "new Document(): children") + +test(function() { + var doc = new Document(); + assert_equals(doc.URL, "about:blank"); + assert_equals(doc.documentURI, "about:blank"); + assert_equals(doc.compatMode, "CSS1Compat"); + assert_equals(doc.characterSet, "UTF-8"); + assert_equals(doc.contentType, "application/xml"); + assert_equals(doc.origin, document.origin); + assert_equals(doc.createElement("DIV").localName, "DIV"); +}, "new Document(): metadata") + +test(function() { + var doc = new Document(); + assert_equals(doc.characterSet, "UTF-8", "characterSet"); + assert_equals(doc.charset, "UTF-8", "charset"); + assert_equals(doc.inputEncoding, "UTF-8", "inputEncoding"); +}, "new Document(): characterSet aliases") +]]></html:script> +</svg> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-constructor-xml.xml b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-constructor-xml.xml new file mode 100644 index 0000000..9aada51 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-constructor-xml.xml
@@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="windows-1252"?> +<!-- Using windows-1252 to ensure that new Document() doesn't inherit utf-8 + from the parent document. --> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>Document constructor</title> +<link rel="help" href="https://dom.spec.whatwg.org/#dom-document" /> +</head> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script><![CDATA[ +test(function() { + var doc = new Document(); + assert_true(doc instanceof Node, "Should be a Node"); + assert_true(doc instanceof Document, "Should be a Document"); + assert_false(doc instanceof XMLDocument, "Should not be an XMLDocument"); + assert_equals(Object.getPrototypeOf(doc), Document.prototype, + "Document should be the primary interface"); +}, "new Document(): interfaces") + +test(function() { + var doc = new Document(); + assert_equals(doc.firstChild, null, "firstChild"); + assert_equals(doc.lastChild, null, "lastChild"); + assert_equals(doc.doctype, null, "doctype"); + assert_equals(doc.documentElement, null, "documentElement"); + assert_array_equals(doc.childNodes, [], "childNodes"); +}, "new Document(): children") + +test(function() { + var doc = new Document(); + assert_equals(doc.URL, "about:blank"); + assert_equals(doc.documentURI, "about:blank"); + assert_equals(doc.compatMode, "CSS1Compat"); + assert_equals(doc.characterSet, "UTF-8"); + assert_equals(doc.contentType, "application/xml"); + assert_equals(doc.origin, document.origin); + assert_equals(doc.createElement("DIV").localName, "DIV"); +}, "new Document(): metadata") + +test(function() { + var doc = new Document(); + assert_equals(doc.characterSet, "UTF-8", "characterSet"); + assert_equals(doc.charset, "UTF-8", "charset"); + assert_equals(doc.inputEncoding, "UTF-8", "inputEncoding"); +}, "new Document(): characterSet aliases") +]]></script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-constructor.html b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-constructor.html index 11549da..3ebc780e 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-constructor.html +++ b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-constructor.html
@@ -33,6 +33,7 @@ assert_equals(doc.compatMode, "CSS1Compat"); assert_equals(doc.characterSet, "UTF-8"); assert_equals(doc.contentType, "application/xml"); + assert_equals(doc.origin, document.origin); assert_equals(doc.createElement("DIV").localName, "DIV"); }, "new Document(): metadata")
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-doctype-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-doctype-expected.txt deleted file mode 100644 index fcffef53..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-doctype-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -This is a testharness.js-based test. -PASS Window document with doctype -FAIL new Document() Illegal constructor -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Node-childNodes-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Node-childNodes-expected.txt deleted file mode 100644 index 10389f3..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Node-childNodes-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -PASS Caching of Node.childNodes -PASS Node.childNodes on an Element. -PASS Node.childNodes on a DocumentFragment. -FAIL Node.childNodes on a Document. Illegal constructor -PASS Iterator behavior of Node.childNodes -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/headers/headers-record.html b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/headers/headers-record.html index 6e2ec8d..173daf0a 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/headers/headers-record.html +++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/headers/headers-record.html
@@ -306,6 +306,94 @@ assert_equals(h.get("c"), "2"); }, "Correct operation ordering with repeated keys"); -// Need to add symbol tests, but those are pending -// https://github.com/heycam/webidl/issues/294 being resolved. +test(function() { + this.add_cleanup(clearLog); + var record = { + a: "b", + [Symbol.toStringTag]: { + // Make sure the ToString conversion of the value happens + // after the ToString conversion of the key. + toString: function () { addLogEntry("toString", [this]); return "nope"; } + }, + c: "d" }; + var proxy = new Proxy(record, loggingHandler); + assert_throws(new TypeError(), + function() { var h = new Headers(proxy); }); + + assert_equals(log.length, 7); + // The first thing is the [[Get]] of Symbol.iterator to figure out whether + // we're a sequence, during overload resolution. + assert_array_equals(log[0], ["get", record, Symbol.iterator, proxy]); + // Then we have the [[OwnPropertyKeys]] from + // https://heycam.github.io/webidl/#es-to-record step 4. + assert_array_equals(log[1], ["ownKeys", record]); + // Then the [[GetOwnProperty]] from step 5.1. + assert_array_equals(log[2], ["getOwnPropertyDescriptor", record, "a"]); + // Then the [[Get]] from step 5.2. + assert_array_equals(log[3], ["get", record, "a", proxy]); + // Then the second [[GetOwnProperty]] from step 5.1. + assert_array_equals(log[4], ["getOwnPropertyDescriptor", record, "c"]); + // Then the second [[Get]] from step 5.2. + assert_array_equals(log[5], ["get", record, "c", proxy]); + // Then the third [[GetOwnProperty]] from step 5.1. + assert_array_equals(log[6], ["getOwnPropertyDescriptor", record, + Symbol.toStringTag]); + // Then we throw an exception converting the Symbol to a string, before we do + // the third [[Get]]. +}, "Basic operation with Symbol keys"); + +test(function() { + this.add_cleanup(clearLog); + var record = { + a: { + toString: function() { addLogEntry("toString", [this]); return "b"; } + }, + [Symbol.toStringTag]: { + toString: function () { addLogEntry("toString", [this]); return "nope"; } + }, + c: { + toString: function() { addLogEntry("toString", [this]); return "d"; } + } + }; + // Now make that Symbol-named property not enumerable. + Object.defineProperty(record, Symbol.toStringTag, { enumerable: false }); + assert_array_equals(Reflect.ownKeys(record), + ["a", "c", Symbol.toStringTag]); + + var proxy = new Proxy(record, loggingHandler); + var h = new Headers(proxy); + + assert_equals(log.length, 9); + // The first thing is the [[Get]] of Symbol.iterator to figure out whether + // we're a sequence, during overload resolution. + assert_array_equals(log[0], ["get", record, Symbol.iterator, proxy]); + // Then we have the [[OwnPropertyKeys]] from + // https://heycam.github.io/webidl/#es-to-record step 4. + assert_array_equals(log[1], ["ownKeys", record]); + // Then the [[GetOwnProperty]] from step 5.1. + assert_array_equals(log[2], ["getOwnPropertyDescriptor", record, "a"]); + // Then the [[Get]] from step 5.2. + assert_array_equals(log[3], ["get", record, "a", proxy]); + // Then the ToString on the value. + assert_array_equals(log[4], ["toString", record.a]); + // Then the second [[GetOwnProperty]] from step 5.1. + assert_array_equals(log[5], ["getOwnPropertyDescriptor", record, "c"]); + // Then the second [[Get]] from step 5.2. + assert_array_equals(log[6], ["get", record, "c", proxy]); + // Then the ToString on the value. + assert_array_equals(log[7], ["toString", record.c]); + // Then the third [[GetOwnProperty]] from step 5.1. + assert_array_equals(log[8], ["getOwnPropertyDescriptor", record, + Symbol.toStringTag]); + // No [[Get]] because not enumerable. + + // Check the results. + assert_equals([...h].length, 2); + assert_array_equals([...h.keys()], ["a", "c"]); + assert_true(h.has("a")); + assert_equals(h.get("a"), "b"); + assert_true(h.has("c")); + assert_equals(h.get("c"), "d"); +}, "Operation with non-enumerable Symbol keys"); + </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fullscreen/interfaces-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fullscreen/interfaces-expected.txt index 082e6fa..2787f89 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/fullscreen/interfaces-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/fullscreen/interfaces-expected.txt
@@ -6,14 +6,14 @@ PASS Document interface: attribute onfullscreenchange PASS Document interface: attribute onfullscreenerror FAIL Document interface: attribute fullscreenElement assert_equals: setter must be function for PutForwards, Replaceable, or non-readonly attributes expected "function" but got "undefined" -FAIL Document must be primary interface of new Document assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Stringification of new Document assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document must inherit property "fullscreenEnabled" with the proper type (29) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document must inherit property "fullscreen" with the proper type (30) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document must inherit property "exitFullscreen" with the proper type (31) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document must inherit property "onfullscreenchange" with the proper type (32) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document must inherit property "onfullscreenerror" with the proper type (33) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" -FAIL Document interface: new Document must inherit property "fullscreenElement" with the proper type (35) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Illegal constructor" +PASS Document must be primary interface of new Document +PASS Stringification of new Document +PASS Document interface: new Document must inherit property "fullscreenEnabled" with the proper type (29) +FAIL Document interface: new Document must inherit property "fullscreen" with the proper type (30) assert_inherits: property "fullscreen" not found in prototype chain +PASS Document interface: new Document must inherit property "exitFullscreen" with the proper type (31) +PASS Document interface: new Document must inherit property "onfullscreenchange" with the proper type (32) +PASS Document interface: new Document must inherit property "onfullscreenerror" with the proper type (33) +PASS Document interface: new Document must inherit property "fullscreenElement" with the proper type (35) FAIL ShadowRoot interface: attribute fullscreenElement assert_equals: setter must be function for PutForwards, Replaceable, or non-readonly attributes expected "function" but got "undefined" FAIL Element interface: operation requestFullscreen() assert_unreached: Throws "TypeError: Illegal invocation" instead of rejecting promise Reached unreachable code PASS Element must be primary interface of document.createElementNS(null, "test")
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain-expected.txt index 6282ea6..740f2dc8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain-expected.txt
@@ -1,6 +1,6 @@ This is a testharness.js-based test. PASS sanity checks PASS current document -FAIL new document Illegal constructor +FAIL new document assert_equals: new document has empty domain expected "" but got "web-platform.test" Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/Document-defaultView-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/Document-defaultView-expected.txt deleted file mode 100644 index af71375d..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/Document-defaultView-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -This is a testharness.js-based test. -PASS Document in a browsing context -FAIL Document created with the Document constructor Illegal constructor -PASS Document created with createDocument -PASS Document created with createHTMLDocument -PASS Document created with XML DOMParser -PASS Document created with HTML DOMParser -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/fast/dom/dom-constructors-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/dom-constructors-expected.txt index 6f5609653..8e9e8e7 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/dom-constructors-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/dom-constructors-expected.txt
@@ -6,7 +6,6 @@ PASS TryAllocate('Attr') is 'exception' PASS TryAllocate('CharacterData') is 'exception' PASS TryAllocate('CDATASection') is 'exception' -PASS TryAllocate('Document') is 'exception' PASS TryAllocate('DocumentType') is 'exception' PASS TryAllocate('Element') is 'exception' PASS TryAllocate('EventTarget') is 'exception' @@ -121,6 +120,9 @@ PASS TryAllocate('DOMParser') is '[object DOMParser]' PASS TryAllocate('DOMParser') is '[object DOMParser]' PASS TryAllocate('DOMParser') is '[object DOMParser]' +PASS TryAllocate('Document') is '[object Document]' +PASS TryAllocate('Document') is '[object Document]' +PASS TryAllocate('Document') is '[object Document]' PASS TryAllocate('DocumentFragment') is '[object DocumentFragment]' PASS TryAllocate('DocumentFragment') is '[object DocumentFragment]' PASS TryAllocate('DocumentFragment') is '[object DocumentFragment]'
diff --git a/third_party/WebKit/LayoutTests/fast/dom/dom-constructors.html b/third_party/WebKit/LayoutTests/fast/dom/dom-constructors.html index 4d7c572..9a63addb 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/dom-constructors.html +++ b/third_party/WebKit/LayoutTests/fast/dom/dom-constructors.html
@@ -16,7 +16,6 @@ 'Attr', 'CharacterData', 'CDATASection', - 'Document', 'DocumentType', 'Element', 'EventTarget', @@ -124,6 +123,7 @@ 'Comment', 'DataTransfer', 'DOMParser', + 'Document', 'DocumentFragment', 'Range', 'Text',
diff --git a/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImpl.h b/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImpl.h index 5276efa..f693688 100644 --- a/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImpl.h +++ b/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImpl.h
@@ -430,13 +430,10 @@ // While we could pass v8::ONLY_ENUMERABLE below, doing so breaks // web-platform-tests' headers-record.html and deviates from the spec // algorithm. - // Symbols are being skipped due to - // https://github.com/heycam/webidl/issues/294. if (!v8_object ->GetOwnPropertyNames(context, static_cast<v8::PropertyFilter>( - v8::PropertyFilter::ALL_PROPERTIES | - v8::PropertyFilter::SKIP_SYMBOLS)) + v8::PropertyFilter::ALL_PROPERTIES)) .ToLocal(&keys)) { exception_state.RethrowV8Exception(block.Exception()); return ImplType(); @@ -464,11 +461,14 @@ return ImplType(); } + // V8's GetOwnPropertyNames() does not convert numeric property indices + // to strings, so we have to do it ourselves. + if (!key->IsName()) + key = key->ToString(context).ToLocalChecked(); + // "4.1. Let desc be ? O.[[GetOwnProperty]](key)." v8::Local<v8::Value> desc; - if (!v8_object - ->GetOwnPropertyDescriptor( - context, key->ToString(context).ToLocalChecked()) + if (!v8_object->GetOwnPropertyDescriptor(context, key.As<v8::Name>()) .ToLocal(&desc)) { exception_state.RethrowV8Exception(block.Exception()); return ImplType();
diff --git a/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp b/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp index 71a82a2f..8203b29 100644 --- a/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp
@@ -200,27 +200,15 @@ EXPECT_TRUE(V8CallBoolean(v8_object->Set( scope.GetContext(), ToV8(&scope, "foo"), ToV8(&scope, 42)))); - NonThrowableExceptionState exception_state; + // The presence of symbols should throw a TypeError when the conversion to + // the record's key type is attempted. + DummyExceptionStateForTesting exception_state; const auto& record = NativeValueTraits<IDLRecord<IDLString, IDLShort>>::NativeValue( scope.GetIsolate(), v8_object, exception_state); - EXPECT_EQ(1U, record.size()); - EXPECT_EQ(std::make_pair(String("foo"), int16_t(42)), record[0]); - } - { - v8::Local<v8::Object> v8_object = v8::Object::New(scope.GetIsolate()); - EXPECT_TRUE(V8CallBoolean(v8_object->Set( - scope.GetContext(), v8::Symbol::GetToStringTag(scope.GetIsolate()), - ToV8(&scope, 34)))); - EXPECT_TRUE(V8CallBoolean(v8_object->Set( - scope.GetContext(), ToV8(&scope, "foo"), ToV8(&scope, 42)))); - - NonThrowableExceptionState exception_state; - const auto& record = - NativeValueTraits<IDLRecord<IDLString, IDLShort>>::NativeValue( - scope.GetIsolate(), v8_object, exception_state); - EXPECT_EQ(1U, record.size()); - EXPECT_EQ(std::make_pair(String("foo"), int16_t(42)), record[0]); + EXPECT_TRUE(record.IsEmpty()); + EXPECT_TRUE(exception_state.HadException()); + EXPECT_TRUE(exception_state.Message().IsEmpty()); } { v8::Local<v8::Object> v8_parent_object =
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp index 45cd4f15..3677190d 100644 --- a/third_party/WebKit/Source/core/dom/Document.cpp +++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -491,6 +491,14 @@ DEFINE_INLINE_VIRTUAL_TRACE() { ContextLifecycleObserver::Trace(visitor); } }; +Document* Document::Create(const Document& document) { + Document* new_document = new Document( + DocumentInit::FromContext(const_cast<Document*>(&document), BlankURL())); + new_document->SetSecurityOrigin(document.GetSecurityOrigin()); + new_document->SetContextFeatures(document.GetContextFeatures()); + return new_document; +} + Document::Document(const DocumentInit& initializer, DocumentClassFlags document_classes) : ContainerNode(0, kCreateDocument),
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h index 0f79aedd8..ad3b948 100644 --- a/third_party/WebKit/Source/core/dom/Document.h +++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -261,6 +261,11 @@ static Document* Create(const DocumentInit& initializer = DocumentInit()) { return new Document(initializer); } + // Factory for web-exposed Document constructor. The argument document must be + // a document instance representing window.document, and it works as the + // source of ExecutionContext and security origin of the new document. + // https://dom.spec.whatwg.org/#dom-document-document + static Document* Create(const Document&); ~Document() override; MediaQueryMatcher& GetMediaQueryMatcher();
diff --git a/third_party/WebKit/Source/core/dom/Document.idl b/third_party/WebKit/Source/core/dom/Document.idl index ec933ed0..48f4f0c 100644 --- a/third_party/WebKit/Source/core/dom/Document.idl +++ b/third_party/WebKit/Source/core/dom/Document.idl
@@ -34,8 +34,10 @@ // https://dom.spec.whatwg.org/#interface-document -// FIXME: Document should have a constructor. crbug.com/238234 -interface Document : Node { +[ + Constructor(), + ConstructorCallWith=Document, +] interface Document : Node { [SameObject] readonly attribute DOMImplementation implementation; [ImplementedAs=urlForBinding] readonly attribute DOMString URL; // FIXME: documentURI should not be nullable.
diff --git a/third_party/WebKit/Source/platform/wtf/Assertions.h b/third_party/WebKit/Source/platform/wtf/Assertions.h index a39a133e..33e2b7a 100644 --- a/third_party/WebKit/Source/platform/wtf/Assertions.h +++ b/third_party/WebKit/Source/platform/wtf/Assertions.h
@@ -120,27 +120,10 @@ #define CRASH() IMMEDIATE_CRASH() #endif -// ASSERT -// These macros are compiled out of release builds. -// Expressions inside them are evaluated in debug builds only. -// This is deprecated. We should use: -// - DCHECK() for ASSERT() -#if OS(WIN) -// FIXME: Change to use something other than ASSERT to avoid this conflict with -// the underlying platform. -#undef ASSERT -#endif - #define DCHECK_AT(assertion, file, line) \ LAZY_STREAM(logging::LogMessage(file, line, #assertion).stream(), \ DCHECK_IS_ON() ? !(assertion) : false) -#if DCHECK_IS_ON() -#define ASSERT(assertion) DCHECK(assertion) -#else -#define ASSERT(assertion) ((void)0) -#endif - // Users must test "#if ENABLE(SECURITY_ASSERT)", which helps ensure // that code testing this macro has included this header. #if defined(ADDRESS_SANITIZER) || DCHECK_IS_ON()
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/update_test_expectations.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/update_test_expectations.py index 0ade6bf..bc5929d 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/update_test_expectations.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/update_test_expectations.py
@@ -27,6 +27,7 @@ import logging import webbrowser +from webkitpy.layout_tests.models.test_expectations import CHROMIUM_BUG_PREFIX from webkitpy.layout_tests.models.test_expectations import TestExpectations from webkitpy.tool.commands.flaky_tests import FlakyTests @@ -51,18 +52,16 @@ _log.warning("Didn't find generic expectations file at: " + expectations_file) return 1 - remove_flakes_o_matic = RemoveFlakesOMatic(host, - port, - bot_test_expectations_factory, - webbrowser) + remove_flakes_o_matic = RemoveFlakesOMatic( + host, port, bot_test_expectations_factory, webbrowser) test_expectations = remove_flakes_o_matic.get_updated_test_expectations() if args.show_results: remove_flakes_o_matic.show_removed_results() - remove_flakes_o_matic.write_test_expectations(test_expectations, - expectations_file) + remove_flakes_o_matic.write_test_expectations(test_expectations, expectations_file) + remove_flakes_o_matic.print_suggested_commit_description() return 0 @@ -319,15 +318,13 @@ return test_expectations def show_removed_results(self): - """Opens removed lines in the results dashboard. + """Opens a browser showing the removed lines in the results dashboard. - Opens the results dashboard in the browser, showing all the tests for lines that the script - removed from the TestExpectations file and allowing the user to manually confirm the - results. + Opens the results dashboard in the browser, showing all the tests for + lines removed from the TestExpectations file, allowing the user to + manually confirm the results. """ - removed_test_names = ','.join(x.name for x in self._expectations_to_remove()) - url = FlakyTests.FLAKINESS_DASHBOARD_URL % removed_test_names - + url = self._flakiness_dashboard_url() _log.info('Opening results dashboard: ' + url) self._browser.open(url) @@ -342,3 +339,26 @@ self._host.filesystem.write_text_file( test_expectations_file, TestExpectations.list_to_string(test_expectations, reconstitute_only_these=[])) + + def print_suggested_commit_description(self): + """Prints the body of a suggested CL description after removing some lines.""" + dashboard_url = self._flakiness_dashboard_url() + bugs = ','.join(self._bug_numbers()) + message = ('Remove flaky TestExpectations for tests which appear non-flaky recently.\n\n' + 'This change was made by the update-test-expectations script.\n\n' + 'Recent test results history:\n%s\n\n' + 'BUG=%s') % (dashboard_url, bugs) + _log.info('Suggested commit description:\n' + message) + + def _flakiness_dashboard_url(self): + removed_test_names = ','.join(x.name for x in self._expectations_to_remove()) + return FlakyTests.FLAKINESS_DASHBOARD_URL % removed_test_names + + def _bug_numbers(self): + """Returns the list of all bug numbers affected by this change.""" + numbers = [] + for line in self._expectations_to_remove(): + for bug in line.bugs: + if bug.startswith(CHROMIUM_BUG_PREFIX): + numbers.append(bug[len(CHROMIUM_BUG_PREFIX):]) + return sorted(numbers)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/update_test_expectations_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/update_test_expectations_unittest.py index 13817716..3e5e9b7f 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/update_test_expectations_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/update_test_expectations_unittest.py
@@ -1061,3 +1061,44 @@ self.assertEqual( FlakyTests.FLAKINESS_DASHBOARD_URL % 'test/a.html,test/b.html', self._mock_web_browser.opened_url) + + def test_suggested_commit_description(self): + """Tests display of the suggested commit message. + """ + test_expectations_before = ( + """# Remove this since it's passing all runs. + crbug.com/2222 test/a.html [ Failure Pass ] + # Remove this since, although there's a failure, it's not a timeout. + crbug.com/1111 test/b.html [ Pass Timeout ] + # Keep since we have both crashes and passes. + crbug.com/3333 test/c.html [ Crash Pass ]""") + + self._define_builders({ + 'WebKit Linux': { + 'port_name': 'linux-trusty', + 'specifiers': ['Trusty', 'Release'] + }, + }) + self._port.all_build_types = ('release',) + self._port.all_systems = (('trusty', 'x86_64'),) + + self._parse_expectations(test_expectations_before) + self._expectation_factory.all_results_by_builder = { + 'WebKit Linux': { + 'test/a.html': ['PASS', 'PASS', 'PASS'], + 'test/b.html': ['PASS', 'IMAGE', 'PASS'], + 'test/c.html': ['PASS', 'CRASH', 'PASS'], + } + } + self._flake_remover.print_suggested_commit_description() + self.assertLog([ + 'INFO: Deleting line "crbug.com/2222 test/a.html [ Failure Pass ]"\n', + 'INFO: Deleting line "crbug.com/1111 test/b.html [ Pass Timeout ]"\n', + 'INFO: Suggested commit description:\n' + 'Remove flaky TestExpectations for tests which appear non-flaky recently.\n\n' + 'This change was made by the update-test-expectations script.\n\n' + 'Recent test results history:\n' + 'https://test-results.appspot.com/dashboards/flakiness_dashboard.html' + '#testType=webkit_layout_tests&tests=test/a.html,test/b.html\n\n' + 'BUG=1111,2222\n' + ])
diff --git a/tools/binary_size/diagnose_bloat.py b/tools/binary_size/diagnose_bloat.py index edaeb30e..0bf0e05 100755 --- a/tools/binary_size/diagnose_bloat.py +++ b/tools/binary_size/diagnose_bloat.py
@@ -249,7 +249,8 @@ self.extra_gn_args_str = (' exclude_unwind_tables=true ' 'ffmpeg_branding="Chrome" proprietary_codecs=true') if self.IsLinux(): - self.extra_gn_args_str += ' allow_posix_link_time_opt=false' + self.extra_gn_args_str += ( + ' allow_posix_link_time_opt=false generate_linker_map=true') self.target = self.target if self.IsAndroid() else 'chrome' def _GenGnCmd(self):
diff --git a/tools/gdb/gdb_chrome.py b/tools/gdb/gdb_chrome.py index f3073e3..67e333f 100644 --- a/tools/gdb/gdb_chrome.py +++ b/tools/gdb/gdb_chrome.py
@@ -107,26 +107,6 @@ pp_set.add_printer('FilePath', '^FilePath$', FilePathPrinter) -class SizePrinter(Printer): - def to_string(self): - return '%sx%s' % (self.val['width_'], self.val['height_']) -pp_set.add_printer('gfx::Size', '^gfx::(Size|SizeF|SizeBase<.*>)$', SizePrinter) - - -class PointPrinter(Printer): - def to_string(self): - return '%s,%s' % (self.val['x_'], self.val['y_']) -pp_set.add_printer('gfx::Point', '^gfx::(Point|PointF|PointBase<.*>)$', - PointPrinter) - - -class RectPrinter(Printer): - def to_string(self): - return '%s %s' % (self.val['origin_'], self.val['size_']) -pp_set.add_printer('gfx::Rect', '^gfx::(Rect|RectF|RectBase<.*>)$', - RectPrinter) - - class SmartPtrPrinter(Printer): def to_string(self): return '%s%s' % (self.typename, typed_ptr(self.ptr())) @@ -246,7 +226,7 @@ pp_set.add_printer('base::ManualConstructor', '^base::ManualConstructor<.*>$', ManualConstructorPrinter) -class FlatMapPrinter(object): +class FlatTreePrinter(object): def __init__(self, val): self.val = val @@ -256,8 +236,11 @@ # Python is much more complicated and this output is reasonable. # (Without this printer, a flat_map will output 7 lines of internal # template goop before the vector contents.) - return 'base::flat_map with ' + str(self.val['impl_']['body_']) -pp_set.add_printer('base::flat_map', '^base::flat_map<.*>$', FlatMapPrinter) + return 'base::flat_tree with ' + str(self.val['impl_']['body_']) +pp_set.add_printer('base::flat_map', '^base::flat_map<.*>$', FlatTreePrinter) +pp_set.add_printer('base::flat_set', '^base::flat_set<.*>$', FlatTreePrinter) +pp_set.add_printer('base::flat_tree', '^base::internal::flat_tree<.*>$', + FlatTreePrinter) class ValuePrinter(object): @@ -290,7 +273,10 @@ valuestr = self.val['list_'] return "base::Value of type %s = %s" % (typestr, str(valuestr)) -pp_set.add_printer('base::Value', '^base::(List|Dictionary|)Value$', ValuePrinter) +pp_set.add_printer('base::Value', '^base::Value$', ValuePrinter) +pp_set.add_printer('base::ListValue', '^base::ListValue$', ValuePrinter) +pp_set.add_printer('base::DictionaryValue', '^base::DictionaryValue$', + ValuePrinter) class IpcMessagePrinter(Printer):
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 58a44813..f55e2e4 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -13036,8 +13036,7 @@ </summary> </histogram> -<histogram name="DnsProbe.Probe.NcnOffline.Result" - enum="DnsProbe.ObsoleteProbeResult"> +<histogram name="DnsProbe.Probe.NcnOffline.Result"> <obsolete> Removed 7/2013. </obsolete> @@ -13057,8 +13056,7 @@ </summary> </histogram> -<histogram name="DnsProbe.Probe.NcnOnline.Result" - enum="DnsProbe.ObsoleteProbeResult"> +<histogram name="DnsProbe.Probe.NcnOnline.Result"> <obsolete> Removed 7/2013. </obsolete> @@ -13068,7 +13066,7 @@ </summary> </histogram> -<histogram name="DnsProbe.Probe.Result" enum="DnsProbe.ObsoleteProbeResult"> +<histogram name="DnsProbe.Probe.Result"> <obsolete> Renamed 7/2013 to DnsProbe.ProbeResult. (Also switched to the full DnsProbe.ProbeStatus enum.) @@ -46403,9 +46401,9 @@ <histogram name="Omnibox.ProgressBarBreakPointUpdateCount" units="break point updates"> - <obselete> + <obsolete> Obselete 05/16/2017. Data is unused (crbug.com/719801). - </obselete> + </obsolete> <owner>kkimlabs@chromium.org</owner> <summary> The number of progress bar break point updates from page load started to @@ -46414,9 +46412,9 @@ </histogram> <histogram name="Omnibox.ProgressBarUpdateCount" units="frame updates"> - <obselete> + <obsolete> Obselete 05/16/2017. Data is unused (crbug.com/719801). - </obselete> + </obsolete> <owner>kkimlabs@chromium.org</owner> <summary> The number of progress bar frame updates from page load started to page load @@ -72083,16 +72081,12 @@ <histogram base="true" name="Storage.BytesRead" units="bytes"> <owner>michaeln@chromium.org</owner> - <summary> - The number of bytes read. Recorded on each read. - </summary> + <summary>The number of bytes read. Recorded on each read.</summary> </histogram> <histogram base="true" name="Storage.BytesWritten" units="bytes"> <owner>michaeln@chromium.org</owner> - <summary> - The number of bytes written. Recorded on each write. - </summary> + <summary>The number of bytes written. Recorded on each write.</summary> </histogram> <histogram name="Storage.ImportantSites.CBDChosenReason" @@ -82167,8 +82161,8 @@ <owner>philipel@chromium.org</owner> <summary> A successful probing attempt for a given bitrate, triggered by an update to - the max configured bitrate. NOTE! This is not the resulting bitrate from - a probing attempt, see WebRTC.BWE.MidCallProbing.ProbedKbps. + the max configured bitrate. NOTE! This is not the resulting bitrate from a + probing attempt, see WebRTC.BWE.MidCallProbing.ProbedKbps. </summary> </histogram>
diff --git a/tools/perf/benchmarks/system_health_smoke_test.py b/tools/perf/benchmarks/system_health_smoke_test.py index 6b9841d8..9646110 100644 --- a/tools/perf/benchmarks/system_health_smoke_test.py +++ b/tools/perf/benchmarks/system_health_smoke_test.py
@@ -63,6 +63,9 @@ # crbug.com/699966 'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_desktop.multitab:misc:typical24', # pylint: disable=line-too-long + + # crbug.com/725386 + 'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_desktop.browse:social:twitter', # pylint: disable=line-too-long })