From c0cc79bf2cc7252e62a9e53b5bc0399aa0c5a3fd Mon Sep 17 00:00:00 2001
From: Bryce Lee <brycelee@google.com>
Date: Wed, 24 Apr 2019 13:00:27 -0700
Subject: [PATCH] [SetUI] Support account login override mutations.

This changelist adds support for retrieving and modifying account
settings. It also updates the corresponding fidls by adding a
provision login override type and fixing a typo.

Bug: SU-167
Test: fx run-test setui_service_tests -- --test
Change-Id: I7ddb2ca2f41ebc71fb32feea1094cb3722e86263
---
 garnet/bin/setui/src/json_codec.rs    |  7 +++++
 garnet/bin/setui/src/main.rs          |  7 +++++
 garnet/bin/setui/src/mutation.rs      | 16 ++++++++++
 garnet/bin/setui/src/setui_handler.rs | 43 +++++++++++++++++++++++++++
 sdk/fidl/fuchsia.setui/mutations.fidl |  2 +-
 sdk/fidl/fuchsia.setui/types.fidl     |  2 ++
 6 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/garnet/bin/setui/src/json_codec.rs b/garnet/bin/setui/src/json_codec.rs
index 78977ff2ee1..2d2b2ff4639 100644
--- a/garnet/bin/setui/src/json_codec.rs
+++ b/garnet/bin/setui/src/json_codec.rs
@@ -123,6 +123,7 @@ fn decode_account(encoded: &Value) -> Result<SettingData, Error> {
 
 const LOGIN_MODE_NONE: u64 = 0;
 const LOGIN_MODE_GUEST_OVERRIDE: u64 = 1;
+const LOGIN_MODE_AUTH_PROVIDER: u64 = 2;
 
 fn encode_login_mode(mode: LoginOverride) -> Result<Value, Error> {
     match mode {
@@ -132,6 +133,9 @@ fn encode_login_mode(mode: LoginOverride) -> Result<Value, Error> {
         LoginOverride::AutologinGuest => {
             return Ok(json!(LOGIN_MODE_GUEST_OVERRIDE));
         }
+        LoginOverride::AuthProvider => {
+            return Ok(json!(LOGIN_MODE_AUTH_PROVIDER));
+        }
     }
 }
 
@@ -145,6 +149,9 @@ fn decode_login_mode(value: &Value) -> Result<LoginOverride, Error> {
                 LOGIN_MODE_GUEST_OVERRIDE => {
                     return Ok(LoginOverride::AutologinGuest);
                 }
+                LOGIN_MODE_AUTH_PROVIDER => {
+                    return Ok(LoginOverride::AuthProvider);
+                }
                 _ => {
                     return Err(format_err!("not a decodable type"));
                 }
diff --git a/garnet/bin/setui/src/main.rs b/garnet/bin/setui/src/main.rs
index da32da390ab..cbfb4107c3e 100644
--- a/garnet/bin/setui/src/main.rs
+++ b/garnet/bin/setui/src/main.rs
@@ -44,6 +44,13 @@ fn main() -> Result<(), Error> {
         None,
     )));
 
+    handler.register_adapter(Box::new(SettingAdapter::new(
+        SettingType::Account,
+        Box::new(DefaultStore::new("/data/account.dat".to_string(), Box::new(JsonCodec::new()))),
+        Box::new(process_account_mutation),
+        Some(SettingData::Account(AccountSettings { mode: None })),
+    )));
+
     fs.dir("public").add_fidl_service(move |stream: SetUiServiceRequestStream| {
         let handler_clone = handler.clone();
         fx_log_info!("Connecting to setui_service");
diff --git a/garnet/bin/setui/src/mutation.rs b/garnet/bin/setui/src/mutation.rs
index 0eee85710e2..d3f94330062 100644
--- a/garnet/bin/setui/src/mutation.rs
+++ b/garnet/bin/setui/src/mutation.rs
@@ -15,3 +15,19 @@ pub fn process_string_mutation(mutation: &Mutation) -> Result<Option<SettingData
         return Err(format_err!("invalid error"));
     }
 }
+
+pub fn process_account_mutation(mutation: &Mutation) -> Result<Option<SettingData>, Error> {
+    if let Mutation::AccountMutationValue(mutation_info) = mutation {
+        if let Some(operation) = mutation_info.operation {
+            if operation == AccountOperation::SetLoginOverride {
+                return Ok(Some(SettingData::Account(AccountSettings {
+                    mode: mutation_info.login_override,
+                })));
+            }
+        }
+
+        return Ok(None);
+    } else {
+        return Err(format_err!("invalid error"));
+    }
+}
diff --git a/garnet/bin/setui/src/setui_handler.rs b/garnet/bin/setui/src/setui_handler.rs
index e8c3c595e35..9d1306cd0db 100644
--- a/garnet/bin/setui/src/setui_handler.rs
+++ b/garnet/bin/setui/src/setui_handler.rs
@@ -202,4 +202,47 @@ mod tests {
             }
         }
     }
+
+    /// A test to verify behavior of the account adapter.
+    #[test]
+    fn test_account() {
+        let mut adapter = SettingAdapter::new(
+            SettingType::Account,
+            Box::new(TestStore::new()),
+            Box::new(process_account_mutation),
+            Some(SettingData::Account(AccountSettings { mode: None })),
+        );
+
+        check_login_override(&adapter, None);
+
+        let override_update = Some(LoginOverride::AutologinGuest);
+
+        adapter.mutate(&Mutation::AccountMutationValue(AccountMutation {
+            operation: Some(AccountOperation::SetLoginOverride),
+            login_override: override_update,
+        }));
+
+        check_login_override(&adapter, override_update);
+    }
+
+    fn check_login_override(adapter: &Adapter, expected_override: Option<LoginOverride>) {
+        let (sender, receiver) = channel();
+
+        // Ensure initial account settings returned.
+        adapter.listen(sender, None);
+
+        let listen_result = receiver.recv();
+        assert!(listen_result.is_ok());
+
+        let data = listen_result.unwrap();
+
+        match data {
+            SettingData::Account(val) => {
+                assert_eq!(val.mode, expected_override);
+            }
+            _ => {
+                panic!("unexpected listen value");
+            }
+        }
+    }
 }
diff --git a/sdk/fidl/fuchsia.setui/mutations.fidl b/sdk/fidl/fuchsia.setui/mutations.fidl
index 2b38579070c..2c0a2cf2a94 100644
--- a/sdk/fidl/fuchsia.setui/mutations.fidl
+++ b/sdk/fidl/fuchsia.setui/mutations.fidl
@@ -24,7 +24,7 @@ enum AccountOperation {
 /// Configuration for account mutations.
 table AccountMutation {
     1: AccountOperation operation;
-    2: LoginOverride login_overide;
+    2: LoginOverride login_override;
 };
 
 /// Operations supported by wireless settings.
diff --git a/sdk/fidl/fuchsia.setui/types.fidl b/sdk/fidl/fuchsia.setui/types.fidl
index 3d59ead8c80..f2d3086c067 100644
--- a/sdk/fidl/fuchsia.setui/types.fidl
+++ b/sdk/fidl/fuchsia.setui/types.fidl
@@ -32,6 +32,8 @@ enum LoginOverride {
     NONE = 0;
     /// Do not require an account and login always as guest.
     AUTOLOGIN_GUEST = 1;
+    /// Requires a provisioned account through auth provider.
+    AUTH_PROVIDER = 2;
 };
 
 table AccountSettings {
-- 
GitLab