[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