[session_shell] Ermine uses SessionShell

Change ermine from using Start(request<ViewOwner>) to RequestStart()
and AttachView(ViewOwner).

Prerequisite peridot changes:
* https://fuchsia-review.googlesource.com/c/peridot/+/232386
* https://fuchsia-review.googlesource.com/c/peridot/+/233413

TESTED=built and run, watched the log.

MF-121 #comment Ermine uses SessionShell

Change-Id: Id2cf6f0d197bad0d1f4ab3ab85d7a531230ca11f
diff --git a/bin/session_shell/ermine_session_shell/src/main.rs b/bin/session_shell/ermine_session_shell/src/main.rs
index 2c7f4bd..2e48234 100644
--- a/bin/session_shell/ermine_session_shell/src/main.rs
+++ b/bin/session_shell/ermine_session_shell/src/main.rs
@@ -8,6 +8,7 @@
 use fidl_fuchsia_developer_tiles as tiles;
 use fidl_fuchsia_math::SizeF;
 use fidl_fuchsia_modular::{SessionShellContextMarker, SessionShellContextProxy,
+                           SessionShellMarker, SessionShellRequest, SessionShellRequestStream,
                            StoryProviderProxy, StoryProviderWatcherMarker,
                            StoryProviderWatcherRequest, StoryState};
 use fidl_fuchsia_ui_input::{KeyboardEvent, KeyboardEventPhase, MODIFIER_LEFT_SUPER,
@@ -154,12 +155,11 @@
         next_key
     }
 
-    pub fn add_view_for_story(&mut self, story_id: String) -> Result<(), Error> {
-        let key_to_use = self.next_story_key();
-        self.views[0]
-            .lock()
-            .display_story(key_to_use, "".to_string(), &story_id, &self.story_provider)
-            .context("display_story failed")?;
+    pub fn request_start_story(&mut self, story_id: String) -> Result<(), Error> {
+        let (story_controller, story_controller_end) = create_proxy()?;
+        self.story_provider
+            .get_controller(&story_id, story_controller_end)?;
+        story_controller.request_start()?;
         Ok(())
     }
 
@@ -175,6 +175,15 @@
         self.views[0].lock().list_stories()
     }
 
+    pub fn add_child_view_for_story_attach(
+        &mut self, story_id: String, view_owner: ClientEnd<ViewOwnerMarker>,
+    ) {
+        let key_to_use = self.next_story_key();
+        self.views[0]
+            .lock()
+            .add_child_view_for_story_attach(key_to_use, story_id, view_owner);
+    }
+
     pub fn spawn_tiles_server(chan: fasync::Channel) {
         fasync::spawn(
             tiles::ControllerRequestStream::from_channel(chan)
@@ -208,6 +217,29 @@
         )
     }
 
+    pub fn spawn_session_shell_server(chan: fasync::Channel) {
+        fasync::spawn(
+            SessionShellRequestStream::from_channel(chan)
+                .try_for_each(move |req| match req {
+                    SessionShellRequest::AttachView {
+                        view_id,
+                        view_owner,
+                        ..
+                    } => {
+                        println!("AttachView {:?}", view_id.story_id);
+                        APP.lock()
+                            .add_child_view_for_story_attach(view_id.story_id, view_owner);
+                        fready(Ok(()))
+                    }
+                    SessionShellRequest::DetachView { view_id, responder } => {
+                        println!("DetachView {:?}", view_id.story_id);
+                        fready(responder.send())
+                    }
+                })
+                .unwrap_or_else(|e| eprintln!("error running SessionShell server: {:?}", e)),
+        )
+    }
+
     pub fn spawn_story_watcher(&mut self) -> Result<(), Error> {
         let (story_watcher, story_watcher_request) =
             create_endpoints::<StoryProviderWatcherMarker>()?;
@@ -224,7 +256,7 @@
                     } => {
                         if story_state == StoryState::Stopped {
                             APP.lock()
-                                .add_view_for_story(story_info.id.to_string())
+                                .request_start_story(story_info.id.to_string())
                                 .unwrap_or_else(|e| {
                                     eprintln!("error adding story {}: {:?}", story_info.id, e);
                                 });
@@ -247,7 +279,7 @@
             f.map_ok(move |r| {
                 for story in r {
                     APP.lock()
-                        .add_view_for_story(story.id.to_string())
+                        .request_start_story(story.id.to_string())
                         .unwrap_or_else(|e| {
                             eprintln!("error adding view for initial story {}: {:?}", story.id, e);
                         });
@@ -278,11 +310,14 @@
     let mut executor = fasync::Executor::new().context("Error creating executor")?;
 
     let fut = component::server::ServicesServer::new()
-        .add_service((ViewProviderMarker::NAME, move |channel| {
-            App::spawn_view_provider_server(channel);
+        .add_service((ViewProviderMarker::NAME, move |chan| {
+            App::spawn_view_provider_server(chan);
         }))
         .add_service((tiles::ControllerMarker::NAME, move |chan| {
-            App::spawn_tiles_server(chan)
+            App::spawn_tiles_server(chan);
+        }))
+        .add_service((SessionShellMarker::NAME, move |chan| {
+            App::spawn_session_shell_server(chan);
         }))
         .start()
         .context("Error starting services server")?;
diff --git a/bin/session_shell/ermine_session_shell/src/view.rs b/bin/session_shell/ermine_session_shell/src/view.rs
index d4aba62..96233e1 100644
--- a/bin/session_shell/ermine_session_shell/src/view.rs
+++ b/bin/session_shell/ermine_session_shell/src/view.rs
@@ -8,8 +8,8 @@
 use fidl::endpoints::{create_proxy, ClientEnd, ServerEnd, ServiceMarker};
 use fidl_fuchsia_math::{InsetF, RectF, SizeF};
 use fidl_fuchsia_modular::{AddMod, Intent, PuppetMasterMarker, PuppetMasterProxy, StoryCommand,
-                           StoryProviderProxy, StoryPuppetMasterProxy, SurfaceArrangement,
-                           SurfaceDependency, SurfaceRelation};
+                           StoryPuppetMasterProxy, SurfaceArrangement, SurfaceDependency,
+                           SurfaceRelation};
 use fidl_fuchsia_ui_gfx::{self as gfx, ColorRgba};
 use fidl_fuchsia_ui_input::{InputConnectionMarker, InputConnectionProxy, InputListenerMarker,
                             InputListenerRequest, KeyboardEvent};
@@ -17,10 +17,11 @@
 use fidl_fuchsia_ui_viewsv1::{CustomFocusBehavior, ViewContainerListenerMarker,
                               ViewContainerListenerRequest, ViewLayout, ViewListenerMarker,
                               ViewListenerRequest, ViewProperties};
+use fidl_fuchsia_ui_viewsv1token::ViewOwnerMarker;
 use fuchsia_app::client::connect_to_service;
 use fuchsia_async as fasync;
 use fuchsia_scenic::{EntityNode, ImportNode, Material, Rectangle, Session, SessionPtr, ShapeNode};
-use fuchsia_zircon::{self as zx, Channel};
+use fuchsia_zircon as zx;
 use futures::{future::ready as fready, TryFutureExt, TryStreamExt};
 use itertools::Itertools;
 use parking_lot::Mutex;
@@ -317,34 +318,23 @@
         }
     }
 
-    fn add_child_view_for_story(
-        &mut self, key: u32, url: String, story_id: String, allow_focus: bool, view_owner: Channel,
+    pub fn add_child_view_for_story_attach(
+        &mut self, key: u32, story_id: String, view_owner: ClientEnd<ViewOwnerMarker>,
     ) {
         let host_node = EntityNode::new(self.session.clone());
         let host_import_token = host_node.export_as_request();
 
         self.view_container
-            .add_child(key, ClientEnd::new(view_owner), host_import_token)
+            .add_child(key, view_owner, host_import_token)
             .unwrap();
 
         self.import_node.add_child(&host_node);
-        let view_data = ViewData::new(key, url, story_id, allow_focus, host_node);
+        let view_data = ViewData::new(key, "".to_string(), story_id, true, host_node);
         self.views.insert(key, view_data);
         self.update();
         self.layout();
     }
 
-    pub fn display_story(
-        &mut self, key: u32, url: String, story_id: &String, story_provider: &StoryProviderProxy,
-    ) -> Result<(), Error> {
-        let (story_controller, story_controller_end) = create_proxy()?;
-        story_provider.get_controller(story_id, story_controller_end)?;
-        let (view_owner_client, view_owner_server) = Channel::create()?;
-        story_controller.start(ServerEnd::new(view_owner_client))?;
-        self.add_child_view_for_story(key, url, story_id.to_string(), true, view_owner_server);
-        Ok(())
-    }
-
     pub fn remove_view_for_story(&mut self, story_id: &String) -> Result<(), Error> {
         let result = self
             .views