[M149] Fixing a potential race condition in TouchInputInjector Original change's description: > Fixing a potential race condition in TouchInputInjector > > Move TouchInjectorWin creation and deletion to main_task_runner_. > > Bug: 513394258 > Change-Id: I8872bcae6012a53c9016395802f4b33f80c294ac > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7858188 > Commit-Queue: Joe Downing <joedow@chromium.org> > Reviewed-by: Yuwei Huang <yuweih@chromium.org> > Cr-Commit-Position: refs/heads/main@{#1633732} (cherry picked from commit 3484cc819abb4bf06aec11e87aa786c9b414480f) Bug: 515275887,513394258 Change-Id: I8872bcae6012a53c9016395802f4b33f80c294ac Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7883560 Commit-Queue: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com> Auto-Submit: chrome-cherry-picker@chops-service-accounts.iam.gserviceaccount.com <chrome-cherry-picker@chops-service-accounts.iam.gserviceaccount.com> Reviewed-by: Joe Downing <joedow@chromium.org> Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com> Cr-Commit-Position: refs/branch-heads/7827@{#1980} Cr-Branched-From: 9f3e9aaccba63bd2ec30334e45e0bfd07ebcc8f1-refs/heads/main@{#1625079}
diff --git a/remoting/host/input_injector_win.cc b/remoting/host/input_injector_win.cc index 10c9125..afc03ac 100644 --- a/remoting/host/input_injector_win.cc +++ b/remoting/host/input_injector_win.cc
@@ -21,6 +21,7 @@ #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "base/strings/utf_string_conversions.h" +#include "base/task/sequenced_task_runner.h" #include "base/task/single_thread_task_runner.h" #include "remoting/base/util.h" #include "remoting/host/clipboard.h" @@ -247,10 +248,14 @@ void HandleMouse(const MouseEvent& event); void HandleTouch(const TouchEvent& event); + void StartTouchInjector(); + void StopTouchInjector(); + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; std::unique_ptr<Clipboard> clipboard_; - std::unique_ptr<TouchInjectorWin> touch_injector_; + std::unique_ptr<TouchInjectorWin, base::OnTaskRunnerDeleter> + touch_injector_; }; scoped_refptr<Core> core_; @@ -297,7 +302,7 @@ : main_task_runner_(main_task_runner), ui_task_runner_(ui_task_runner), clipboard_(Clipboard::Create()), - touch_injector_(new TouchInjectorWin()) {} + touch_injector_(nullptr, base::OnTaskRunnerDeleter(main_task_runner)) {} void InputInjectorWin::Core::InjectClipboardEvent(const ClipboardEvent& event) { if (!ui_task_runner_->BelongsToCurrentThread()) { @@ -360,7 +365,8 @@ } clipboard_->Start(std::move(client_clipboard)); - touch_injector_->Init(); + main_task_runner_->PostTask(FROM_HERE, + base::BindOnce(&Core::StartTouchInjector, this)); } void InputInjectorWin::Core::Stop() { @@ -370,8 +376,22 @@ } clipboard_.reset(); + main_task_runner_->PostTask(FROM_HERE, + base::BindOnce(&Core::StopTouchInjector, this)); +} + +void InputInjectorWin::Core::StartTouchInjector() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + DCHECK(!touch_injector_); + touch_injector_.reset(new TouchInjectorWin()); + touch_injector_->Init(); +} + +void InputInjectorWin::Core::StopTouchInjector() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); if (touch_injector_) { touch_injector_->Deinitialize(); + touch_injector_.reset(); } } @@ -457,8 +477,9 @@ } void InputInjectorWin::Core::HandleTouch(const TouchEvent& event) { - DCHECK(touch_injector_); - touch_injector_->InjectTouchEvent(event); + if (touch_injector_) { + touch_injector_->InjectTouchEvent(event); + } } } // namespace
diff --git a/remoting/host/touch_injector_win.cc b/remoting/host/touch_injector_win.cc index 0634678..8829275 100644 --- a/remoting/host/touch_injector_win.cc +++ b/remoting/host/touch_injector_win.cc
@@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/native_library.h" #include "base/notreached.h" +#include "base/sequence_checker.h" #include "base/time/time.h" #include "remoting/proto/event.pb.h" #include "third_party/webrtc/modules/desktop_capture/desktop_capture_types.h" @@ -163,6 +164,7 @@ // so that a mock delegate can be injected in tests and set expectations on the // mock and return value of this method. bool TouchInjectorWin::Init() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!delegate_) { delegate_ = TouchInjectorWinDelegate::Create(); } @@ -186,6 +188,7 @@ } void TouchInjectorWin::Deinitialize() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); touches_in_contact_.clear(); // Same reason as TouchInjectorWin::Init(). For injecting mock delegates for // tests, a new delegate is created here. @@ -195,6 +198,7 @@ } void TouchInjectorWin::InjectTouchEvent(const TouchEvent& event) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!delegate_) { VLOG(3) << "Touch injection functions are not initialized."; return; @@ -224,6 +228,7 @@ } void TouchInjectorWin::AddNewTouchPoints(const TouchEvent& event) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(event.event_type(), TouchEvent::TOUCH_POINT_START); std::vector<POINTER_TOUCH_INFO> touches; @@ -249,6 +254,7 @@ } void TouchInjectorWin::MoveTouchPoints(const TouchEvent& event) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(event.event_type(), TouchEvent::TOUCH_POINT_MOVE); for (const TouchEventPoint& touch_point : event.touch_points()) { @@ -269,6 +275,7 @@ } void TouchInjectorWin::EndTouchPoints(const TouchEvent& event) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(event.event_type(), TouchEvent::TOUCH_POINT_END); std::vector<POINTER_TOUCH_INFO> touches; @@ -288,6 +295,7 @@ } void TouchInjectorWin::CancelTouchPoints(const TouchEvent& event) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(event.event_type(), TouchEvent::TOUCH_POINT_CANCEL); std::vector<POINTER_TOUCH_INFO> touches; @@ -309,6 +317,7 @@ bool TouchInjectorWin::InjectTouchInput( const std::vector<POINTER_TOUCH_INFO>& touches) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (delegate_->InjectTouchInput(touches.size(), touches.data()) == 0) { return false; } @@ -318,6 +327,7 @@ } void TouchInjectorWin::UpdateKeepAliveTimer() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (touches_in_contact_.empty()) { keep_alive_timer_.Stop(); return; @@ -329,6 +339,7 @@ } void TouchInjectorWin::OnKeepAlive() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if ((base::TimeTicks::Now() - last_injected_time_) < kKeepAliveInterval) { return; }
diff --git a/remoting/host/touch_injector_win.h b/remoting/host/touch_injector_win.h index 5abdab5..6d01e96 100644 --- a/remoting/host/touch_injector_win.h +++ b/remoting/host/touch_injector_win.h
@@ -14,6 +14,7 @@ #include <vector> #include "base/scoped_native_library.h" +#include "base/sequence_checker.h" #include "base/time/time.h" #include "base/timer/timer.h" @@ -129,6 +130,8 @@ base::TimeTicks last_injected_time_; base::RepeatingTimer keep_alive_timer_; + + SEQUENCE_CHECKER(sequence_checker_); }; } // namespace remoting