Merge changes I98272fb0,I1ce8ca51

* changes:
  Keystore 2.0: No longer transition to database directory.
  Keystore 2.0: Make per boot database an in memory db.
diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
index 8e5507e..0e7a2d2 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -671,26 +671,39 @@
     }
 }
 
+/// Shared in-memory databases get destroyed as soon as the last connection to them gets closed.
+/// This object does not allow access to the database connection. But it keeps a database
+/// connection alive in order to keep the in memory per boot database alive.
+pub struct PerBootDbKeepAlive(Connection);
+
 impl KeystoreDB {
+    const PERBOOT_DB_FILE_NAME: &'static str = &"file:perboot.sqlite?mode=memory&cache=shared";
+
+    /// This creates a PerBootDbKeepAlive object to keep the per boot database alive.
+    pub fn keep_perboot_db_alive() -> Result<PerBootDbKeepAlive> {
+        let conn = Connection::open_in_memory()
+            .context("In keep_perboot_db_alive: Failed to initialize SQLite connection.")?;
+
+        conn.execute("ATTACH DATABASE ? as perboot;", params![Self::PERBOOT_DB_FILE_NAME])
+            .context("In keep_perboot_db_alive: Failed to attach database perboot.")?;
+        Ok(PerBootDbKeepAlive(conn))
+    }
+
     /// This will create a new database connection connecting the two
     /// files persistent.sqlite and perboot.sqlite in the given directory.
     /// It also attempts to initialize all of the tables.
     /// KeystoreDB cannot be used by multiple threads.
     /// Each thread should open their own connection using `thread_local!`.
     pub fn new(db_root: &Path) -> Result<Self> {
-        // Build the path to the sqlite files.
+        // Build the path to the sqlite file.
         let mut persistent_path = db_root.to_path_buf();
         persistent_path.push("persistent.sqlite");
-        let mut perboot_path = db_root.to_path_buf();
-        perboot_path.push("perboot.sqlite");
 
         // Now convert them to strings prefixed with "file:"
         let mut persistent_path_str = "file:".to_owned();
         persistent_path_str.push_str(&persistent_path.to_string_lossy());
-        let mut perboot_path_str = "file:".to_owned();
-        perboot_path_str.push_str(&perboot_path.to_string_lossy());
 
-        let conn = Self::make_connection(&persistent_path_str, &perboot_path_str)?;
+        let conn = Self::make_connection(&persistent_path_str, &Self::PERBOOT_DB_FILE_NAME)?;
         conn.busy_handler(Some(|_| {
             std::thread::sleep(std::time::Duration::from_micros(50));
             true
diff --git a/keystore2/src/globals.rs b/keystore2/src/globals.rs
index c488a18..cfaa28c 100644
--- a/keystore2/src/globals.rs
+++ b/keystore2/src/globals.rs
@@ -34,9 +34,9 @@
 use android_security_compat::aidl::android::security::compat::IKeystoreCompatService::IKeystoreCompatService;
 use anyhow::{Context, Result};
 use lazy_static::lazy_static;
-use std::collections::HashMap;
 use std::sync::Mutex;
 use std::{cell::RefCell, sync::Once};
+use std::{collections::HashMap, path::Path, path::PathBuf};
 
 static DB_INIT: Once = Once::new();
 
@@ -45,12 +45,8 @@
 /// we also call KeystoreDB::cleanup_leftovers to restore the key lifecycle invariant. See the
 /// documentation of cleanup_leftovers for more details.
 fn create_thread_local_db() -> KeystoreDB {
-    let mut db = KeystoreDB::new(
-        // Keystore changes to the database directory on startup
-        // (see keystore2_main.rs).
-        &std::env::current_dir().expect("Could not get the current working directory."),
-    )
-    .expect("Failed to open database.");
+    let mut db = KeystoreDB::new(&DB_PATH.lock().expect("Could not get the database directory."))
+        .expect("Failed to open database.");
     DB_INIT.call_once(|| {
         log::info!("Touching Keystore 2.0 database for this first time since boot.");
         db.insert_last_off_body(MonotonicRawTime::now())
@@ -113,6 +109,9 @@
 }
 
 lazy_static! {
+    /// The path where keystore stores all its keys.
+    pub static ref DB_PATH: Mutex<PathBuf> = Mutex::new(
+        Path::new("/data/misc/keystore").to_path_buf());
     /// Runtime database of unwrapped super keys.
     pub static ref SUPER_KEY: SuperKeyManager = Default::default();
     /// Map of KeyMint devices.
@@ -127,7 +126,7 @@
     /// LegacyBlobLoader is initialized and exists globally.
     /// The same directory used by the database is used by the LegacyBlobLoader as well.
     pub static ref LEGACY_BLOB_LOADER: LegacyBlobLoader = LegacyBlobLoader::new(
-        &std::env::current_dir().expect("Could not get the current working directory."));
+        &DB_PATH.lock().expect("Could not get the database path for legacy blob loader."));
 }
 
 static KEYMINT_SERVICE_NAME: &str = "android.hardware.security.keymint.IKeyMintDevice";
diff --git a/keystore2/src/keystore2_main.rs b/keystore2/src/keystore2_main.rs
index 2ea41aa..f8dba07 100644
--- a/keystore2/src/keystore2_main.rs
+++ b/keystore2/src/keystore2_main.rs
@@ -19,7 +19,7 @@
 use keystore2::authorization::AuthorizationManager;
 use keystore2::service::KeystoreService;
 use log::{error, info};
-use std::panic;
+use std::{panic, path::Path};
 
 static KS2_SERVICE_NAME: &str = "android.system.keystore2";
 static APC_SERVICE_NAME: &str = "android.security.apc";
@@ -39,15 +39,20 @@
     // Saying hi.
     info!("Keystore2 is starting.");
 
+    // Initialize the per boot database.
+    let _keep_me_alive = keystore2::database::KeystoreDB::keep_perboot_db_alive()
+        .expect("Failed to initialize the perboot database.");
+
     let mut args = std::env::args();
     args.next().expect("That's odd. How is there not even a first argument?");
 
-    // Keystore changes to the database directory on startup (typically /data/misc/keystore).
+    // Keystore 2.0 cannot change to the database directory (typically /data/misc/keystore) on
+    // startup as Keystore 1.0 did because Keystore 2.0 is intended to run much earlier than
+    // Keystore 1.0. Instead we set a global variable to the database path.
     // For the ground truth check the service startup rule for init (typically in keystore2.rc).
     if let Some(dir) = args.next() {
-        if std::env::set_current_dir(dir.clone()).is_err() {
-            panic!("Failed to set working directory {}.", dir)
-        }
+        *keystore2::globals::DB_PATH.lock().expect("Could not lock DB_PATH.") =
+            Path::new(&dir).to_path_buf();
     } else {
         panic!("Must specify a working directory.");
     }