Keystore2: implement getState method in IKeystoreMaintenance AIDL.

Bug: 176123105
Test: TBD
Change-Id: I96a6a2aa8832a5356c7d108e9bc6ac9a5091d272
diff --git a/keystore2/src/permission.rs b/keystore2/src/permission.rs
index 576ac3f..e2ee75f 100644
--- a/keystore2/src/permission.rs
+++ b/keystore2/src/permission.rs
@@ -291,7 +291,7 @@
         AddAuth = 1,    selinux name: add_auth;
         /// Checked when an app is uninstalled or wiped.
         ClearNs = 2,    selinux name: clear_ns;
-        /// Checked when Keystore 2.0 gets locked.
+        /// Checked when the user state is queried from Keystore 2.0.
         GetState = 4,   selinux name: get_state;
         /// Checked when Keystore 2.0 is asked to list a namespace that the caller
         /// does not have the get_info permission for.
diff --git a/keystore2/src/user_manager.rs b/keystore2/src/user_manager.rs
index b84cb82..c17fa72 100644
--- a/keystore2/src/user_manager.rs
+++ b/keystore2/src/user_manager.rs
@@ -20,8 +20,9 @@
 use crate::permission::KeystorePerm;
 use crate::super_key::UserState;
 use crate::utils::check_keystore_permission;
-use android_security_maintenance::aidl::android::security::maintenance::IKeystoreMaintenance::{
-    BnKeystoreMaintenance, IKeystoreMaintenance,
+use android_security_maintenance::aidl::android::security::maintenance::{
+    IKeystoreMaintenance::{BnKeystoreMaintenance, IKeystoreMaintenance},
+    UserState::UserState as AidlUserState,
 };
 use android_security_maintenance::binder::{Interface, Result as BinderResult};
 use android_system_keystore2::aidl::android::system::keystore2::Domain::Domain;
@@ -97,6 +98,23 @@
         DB.with(|db| db.borrow_mut().unbind_keys_for_namespace(domain, nspace))
             .context("In clear_namespace: Trying to delete keys from db.")
     }
+
+    fn get_state(user_id: i32) -> Result<AidlUserState> {
+        // Check permission. Function should return if this failed. Therefore having '?' at the end
+        // is very important.
+        check_keystore_permission(KeystorePerm::get_state()).context("In get_state.")?;
+        let state = DB
+            .with(|db| {
+                UserState::get(&mut db.borrow_mut(), &LEGACY_MIGRATOR, &SUPER_KEY, user_id as u32)
+            })
+            .context("In get_state. Trying to get UserState.")?;
+
+        match state {
+            UserState::Uninitialized => Ok(AidlUserState::UNINITIALIZED),
+            UserState::LskfUnlocked(_) => Ok(AidlUserState::LSKF_UNLOCKED),
+            UserState::LskfLocked => Ok(AidlUserState::LSKF_LOCKED),
+        }
+    }
 }
 
 impl Interface for Maintenance {}
@@ -117,4 +135,8 @@
     fn clearNamespace(&self, domain: Domain, nspace: i64) -> BinderResult<()> {
         map_or_log_err(Self::clear_namespace(domain, nspace), Ok)
     }
+
+    fn getState(&self, user_id: i32) -> binder::public_api::Result<AidlUserState> {
+        map_or_log_err(Self::get_state(user_id), Ok)
+    }
 }