[carnelian] need to reset timer on new key

Previous implementation would not reset the timer if a second
key was pressed before the first key was released, leading to
too quick repeats.

Testing: manual
Change-Id: Iee49a133e16b2b513d47a57235b06b9b13467cc1
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/560370
Fuchsia-Auto-Submit: Rob Tsuk <robtsuk@google.com>
Reviewed-by: David Reveman <reveman@google.com>
Commit-Queue: Auto-Submit <auto-submit@fuchsia-infra.iam.gserviceaccount.com>
diff --git a/src/lib/ui/carnelian/src/app/strategies/framebuffer.rs b/src/lib/ui/carnelian/src/app/strategies/framebuffer.rs
index debdb77..e1f0a61 100644
--- a/src/lib/ui/carnelian/src/app/strategies/framebuffer.rs
+++ b/src/lib/ui/carnelian/src/app/strategies/framebuffer.rs
@@ -38,6 +38,7 @@
 
 pub(crate) trait AutoRepeatTimer {
     fn schedule_autorepeat_timer(&mut self, device_id: &DeviceId);
+    fn continue_autorepeat_timer(&mut self, device_id: &DeviceId);
     fn cancel_autorepeat_timer(&mut self) {}
 }
 
@@ -50,12 +51,8 @@
             repeat_interval: Config::get().keyboard_autorepeat_slow_interval,
         }
     }
-}
 
-impl AutoRepeatTimer for AutoRepeatContext {
-    fn schedule_autorepeat_timer(&mut self, device_id: &DeviceId) {
-        self.repeat_interval =
-            (self.repeat_interval * 3 / 4).max(Config::get().keyboard_autorepeat_fast_interval);
+    fn schedule(&mut self, device_id: &DeviceId) {
         let timer = fasync::Timer::new(fuchsia_async::Time::after(self.repeat_interval.into()));
         let app_sender = self.app_sender.clone();
         let device_id = device_id.clone();
@@ -68,10 +65,28 @@
         });
         self.keyboard_autorepeat_task = Some(task);
     }
+}
+
+impl AutoRepeatTimer for AutoRepeatContext {
+    fn schedule_autorepeat_timer(&mut self, device_id: &DeviceId) {
+        self.repeat_interval = Config::get().keyboard_autorepeat_slow_interval;
+        self.schedule(device_id);
+    }
+
+    fn continue_autorepeat_timer(&mut self, device_id: &DeviceId) {
+        self.repeat_interval =
+            (self.repeat_interval * 3 / 4).max(Config::get().keyboard_autorepeat_fast_interval);
+        self.schedule(device_id);
+    }
 
     fn cancel_autorepeat_timer(&mut self) {
-        self.keyboard_autorepeat_task = None;
-        self.repeat_interval = Config::get().keyboard_autorepeat_slow_interval;
+        let task = self.keyboard_autorepeat_task.take();
+        if let Some(task) = task {
+            fasync::Task::local(async move {
+                task.cancel().await;
+            })
+            .detach();
+        }
     }
 }
 
diff --git a/src/lib/ui/carnelian/src/input/report.rs b/src/lib/ui/carnelian/src/input/report.rs
index 38bdee8..d7639c7 100644
--- a/src/lib/ui/carnelian/src/input/report.rs
+++ b/src/lib/ui/carnelian/src/input/report.rs
@@ -308,7 +308,7 @@
         if let Some(key) = self.repeating.as_ref() {
             let repeat_time = fuchsia_zircon::Time::get_monotonic();
             let modifiers = Modifiers::from_pressed_keys_3(&self.pressed_keys);
-            context.schedule_autorepeat_timer(&self.device_id);
+            context.continue_autorepeat_timer(&self.device_id);
             let repeat = create_keyboard_event(
                 repeat_time.into_nanos() as u64,
                 device_id,
diff --git a/src/lib/ui/carnelian/src/input/tests.rs b/src/lib/ui/carnelian/src/input/tests.rs
index 4b557a1..f01ed24 100644
--- a/src/lib/ui/carnelian/src/input/tests.rs
+++ b/src/lib/ui/carnelian/src/input/tests.rs
@@ -96,6 +96,7 @@
 
     impl AutoRepeatTimer for TestAutoRepeatContext {
         fn schedule_autorepeat_timer(&mut self, _device_id: &DeviceId) {}
+        fn continue_autorepeat_timer(&mut self, _device_id: &DeviceId) {}
     }
 
     fn make_input_handler() -> InputReportHandler<'static> {