[carnelian] Pass input events to scenic canvas view mode apps

This was omitted in the first implementation.

Testability: there is no additional test for this change, but the change ensures
that this bug cannot even compile anymore, which I think is better.

Change-Id: I1cbe63f051bed0dd16782e17a786edd2f891d12c
diff --git a/garnet/public/rust/carnelian/BUILD.gn b/garnet/public/rust/carnelian/BUILD.gn
index 1fab4ab..62af393 100644
--- a/garnet/public/rust/carnelian/BUILD.gn
+++ b/garnet/public/rust/carnelian/BUILD.gn
@@ -168,6 +168,7 @@
     "//garnet/public/rust/fuchsia-scenic",
     "//garnet/public/rust/fuchsia-zircon",
     "//sdk/fidl/fuchsia.images:fuchsia.images-rustc",
+    "//sdk/fidl/fuchsia.ui.input:fuchsia.ui.input-rustc",
     "//third_party/rust_crates:euclid",
     "//third_party/rust_crates:failure",
     "//third_party/rust_crates:futures-preview",
diff --git a/garnet/public/rust/carnelian/examples/drawing.rs b/garnet/public/rust/carnelian/examples/drawing.rs
index b43c441..5f39cda 100644
--- a/garnet/public/rust/carnelian/examples/drawing.rs
+++ b/garnet/public/rust/carnelian/examples/drawing.rs
@@ -5,11 +5,13 @@
 #![feature(async_await)]
 
 use carnelian::{
-    AnimationMode, App, AppAssistant, Canvas, Color, Coord, MappingPixelSink, Point, Rect, Size,
-    ViewAssistant, ViewAssistantContext, ViewAssistantPtr, ViewKey, ViewMode,
+    make_message, AnimationMode, App, AppAssistant, Canvas, Color, Coord, MappingPixelSink, Point,
+    Rect, Size, ViewAssistant, ViewAssistantContext, ViewAssistantPtr, ViewKey, ViewMessages,
+    ViewMode,
 };
 use euclid::rect;
 use failure::Error;
+use fidl_fuchsia_ui_input::{KeyboardEvent, KeyboardEventPhase};
 use fuchsia_zircon::{ClockId, Time};
 use std::{
     env,
@@ -163,6 +165,20 @@
         Ok(())
     }
 
+    fn handle_keyboard_event(
+        &mut self,
+        context: &mut ViewAssistantContext,
+        keyboard_event: &KeyboardEvent,
+    ) -> Result<(), Error> {
+        if keyboard_event.code_point == ' ' as u32
+            && keyboard_event.phase == KeyboardEventPhase::Pressed
+        {
+            self.color3 = Color::from_hash_code("#FFFFFF")?;
+        }
+        context.queue_message(make_message(ViewMessages::Update));
+        Ok(())
+    }
+
     fn initial_animation_mode(&mut self) -> AnimationMode {
         return AnimationMode::EveryFrame;
     }
diff --git a/garnet/public/rust/carnelian/src/view.rs b/garnet/public/rust/carnelian/src/view.rs
index 5fa1cf0..edb5e9c 100644
--- a/garnet/public/rust/carnelian/src/view.rs
+++ b/garnet/public/rust/carnelian/src/view.rs
@@ -185,24 +185,21 @@
 }
 
 trait ViewStrategy {
-    fn setup(&mut self, _view_details: &ViewDetails, _view_assistant: &mut ViewAssistantPtr) {}
+    fn setup(&mut self, _view_details: &ViewDetails, _view_assistant: &mut ViewAssistantPtr);
     fn update(&mut self, view_details: &ViewDetails, view_assistant: &mut ViewAssistantPtr);
-    fn present(&mut self) {}
+    fn present(&mut self);
     fn validate_root_node_id(&self, _: u32) -> bool {
         true
     }
     fn validate_view_id(&self, _: u32) -> bool {
         true
     }
-
     fn handle_input_event(
         &mut self,
         _view_details: &ViewDetails,
         _view_assistant: &mut ViewAssistantPtr,
         _: &fidl_fuchsia_ui_input::InputEvent,
-    ) -> Vec<Message> {
-        Vec::new()
-    }
+    ) -> Vec<Message>;
 }
 
 type ViewStrategyPtr = Box<dyn ViewStrategy>;
@@ -291,7 +288,7 @@
 
     fn make_view_assistant_context<'a>(
         view_details: &ViewDetails,
-        canvas: &'a RefCell<Canvas<MappingPixelSink>>,
+        canvas: Option<&'a RefCell<Canvas<MappingPixelSink>>>,
     ) -> ViewAssistantContext<'a> {
         ViewAssistantContext {
             key: view_details.key,
@@ -301,12 +298,18 @@
             presentation_time: Time::get(ClockId::Monotonic),
             messages: Vec::new(),
             scenic_resources: None,
-            canvas: Some(canvas),
+            canvas: canvas,
         }
     }
 }
 
 impl ViewStrategy for ScenicCanvasViewStrategy {
+    fn setup(&mut self, view_details: &ViewDetails, view_assistant: &mut ViewAssistantPtr) {
+        let canvas_context =
+            ScenicCanvasViewStrategy::make_view_assistant_context(view_details, None);
+        view_assistant.setup(&canvas_context).unwrap_or_else(|e| panic!("Setup error: {:?}", e));
+    }
+
     fn update(&mut self, view_details: &ViewDetails, view_assistant: &mut ViewAssistantPtr) {
         let size = view_details.physical_size.floor().to_u32();
         if size.width > 0 && size.height > 0 {
@@ -340,7 +343,7 @@
             ));
 
             let canvas_context =
-                ScenicCanvasViewStrategy::make_view_assistant_context(view_details, &canvas);
+                ScenicCanvasViewStrategy::make_view_assistant_context(view_details, Some(&canvas));
             view_assistant
                 .update(&canvas_context)
                 .unwrap_or_else(|e| panic!("Update error: {:?}", e));
@@ -350,6 +353,21 @@
     fn present(&mut self) {
         scenic_present(&self.scenic_resources);
     }
+
+    fn handle_input_event(
+        &mut self,
+        view_details: &ViewDetails,
+        view_assistant: &mut ViewAssistantPtr,
+        event: &fidl_fuchsia_ui_input::InputEvent,
+    ) -> Vec<Message> {
+        let mut canvas_context =
+            ScenicCanvasViewStrategy::make_view_assistant_context(view_details, None);
+        view_assistant
+            .handle_input_event(&mut canvas_context, &event)
+            .unwrap_or_else(|e| eprintln!("handle_event: {:?}", e));
+
+        canvas_context.messages
+    }
 }
 
 struct FrameBufferViewStrategy {
@@ -368,11 +386,9 @@
         let framebuffer_resources = FramebufferResources { canvas: RefCell::new(canvas) };
         Box::new(FrameBufferViewStrategy { framebuffer_resources })
     }
-}
 
-impl ViewStrategy for FrameBufferViewStrategy {
-    fn update(&mut self, view_details: &ViewDetails, view_assistant: &mut ViewAssistantPtr) {
-        let canvas_context = ViewAssistantContext {
+    fn make_context(&mut self, view_details: &ViewDetails) -> ViewAssistantContext {
+        ViewAssistantContext {
             key: view_details.key,
             logical_size: view_details.logical_size,
             size: view_details.physical_size,
@@ -381,8 +397,36 @@
             messages: Vec::new(),
             scenic_resources: None,
             canvas: Some(&self.framebuffer_resources.canvas),
-        };
-        view_assistant.update(&canvas_context).unwrap_or_else(|e| panic!("Update error: {:?}", e));
+        }
+    }
+}
+
+impl ViewStrategy for FrameBufferViewStrategy {
+    fn setup(&mut self, view_details: &ViewDetails, view_assistant: &mut ViewAssistantPtr) {
+        let framebuffer_context = self.make_context(view_details);
+        view_assistant
+            .setup(&framebuffer_context)
+            .unwrap_or_else(|e| panic!("Setup error: {:?}", e));
+    }
+
+    fn update(&mut self, view_details: &ViewDetails, view_assistant: &mut ViewAssistantPtr) {
+        let framebuffer_context = self.make_context(view_details);
+        view_assistant
+            .update(&framebuffer_context)
+            .unwrap_or_else(|e| panic!("Update error: {:?}", e));
+    }
+
+    fn present(&mut self) {
+        // this function intentionally left blank
+    }
+
+    fn handle_input_event(
+        &mut self,
+        _view_details: &ViewDetails,
+        _view_assistant: &mut ViewAssistantPtr,
+        _event: &fidl_fuchsia_ui_input::InputEvent,
+    ) -> Vec<Message> {
+        panic!("Not yet implemented");
     }
 }