diff --git a/fsverity/fsverity_manifest_generator.py b/fsverity/fsverity_manifest_generator.py
index ca7ac5c..1a2fba2 100644
--- a/fsverity/fsverity_manifest_generator.py
+++ b/fsverity/fsverity_manifest_generator.py
@@ -31,7 +31,7 @@
   cmd = [fsverity_path, 'digest', input_file]
   cmd.extend(['--compact'])
   cmd.extend(['--hash-alg', HASH_ALGORITHM])
-  out = subprocess.check_output(cmd, universal_newlines=True).strip()
+  out = subprocess.check_output(cmd, text=True).strip()
   return bytes(bytearray.fromhex(out))
 
 if __name__ == '__main__':
@@ -46,20 +46,46 @@
       required=True)
   p.add_argument(
       '--base-dir',
-      help='directory to use as a relative root for the inputs',
-      required=True)
+      help='directory to use as a relative root for the inputs. Also see the documentation of '
+      'inputs')
   p.add_argument(
       'inputs',
       nargs='*',
-      help='input file for the build manifest')
+      help='input file for the build manifest. It can be in either of two forms: <file> or '
+      '<file>,<path_on_device>. If the first form is used, --base-dir must be provided, and the '
+      'path on device will be the filepath relative to the base dir')
   args = p.parse_args()
 
+  links = {}
   digests = FSVerityDigests()
   for f in sorted(args.inputs):
-    # f is a full path for now; make it relative so it starts with {mount_point}/
-    digest = digests.digests[os.path.relpath(f, args.base_dir)]
-    digest.digest = _digest(args.fsverity_path, f)
-    digest.hash_alg = HASH_ALGORITHM
+    if args.base_dir:
+      # f is a full path for now; make it relative so it starts with {mount_point}/
+      rel = os.path.relpath(f, args.base_dir)
+    else:
+      parts = f.split(',')
+      if len(parts) != 2 or not parts[0] or not parts[1]:
+        sys.exit("Since --base-path wasn't provided, all inputs must be pairs separated by commas "
+          "but this input wasn't: " + f)
+      f, rel = parts
+
+    # Some fsv_meta files are links to other ones. Don't read through the link, because the
+    # layout of files in the build system may not match the layout of files on the device.
+    # Instead, read its target and use it to copy the digest from the real file after all files
+    # are processed.
+    if os.path.islink(f):
+      links[rel] = os.path.normpath(os.path.join(os.path.dirname(rel), os.readlink(f)))
+    else:
+      digest = digests.digests[rel]
+      digest.digest = _digest(args.fsverity_path, f)
+      digest.hash_alg = HASH_ALGORITHM
+
+  for link_rel, real_rel in links.items():
+    if real_rel not in digests.digests:
+      sys.exit(f'There was a fsv_meta symlink to {real_rel}, but that file was not a fsv_meta file')
+    link_digest = digests.digests[link_rel]
+    real_digest = digests.digests[real_rel]
+    link_digest.CopyFrom(real_digest)
 
   manifest = digests.SerializeToString()
 
diff --git a/keystore2/postprocessor_client/src/lib.rs b/keystore2/postprocessor_client/src/lib.rs
index 8b347f9..beeb5f5 100644
--- a/keystore2/postprocessor_client/src/lib.rs
+++ b/keystore2/postprocessor_client/src/lib.rs
@@ -77,7 +77,7 @@
             ]
         }
         Err(err) => {
-            error!("Failed to replace certificates ({err:#?}), falling back to original chain.");
+            warn!("Failed to replace certificates ({err:#?}), falling back to original chain.");
             certificates.push(Certificate { encodedCertificate: attestation_certs });
             certificates
         }
diff --git a/keystore2/src/metrics_store.rs b/keystore2/src/metrics_store.rs
index 72bbfe2..30c5973 100644
--- a/keystore2/src/metrics_store.rs
+++ b/keystore2/src/metrics_store.rs
@@ -48,6 +48,9 @@
 use std::collections::HashMap;
 use std::sync::{LazyLock, Mutex};
 
+#[cfg(test)]
+mod tests;
+
 // Note: Crash events are recorded at keystore restarts, based on the assumption that keystore only
 // gets restarted after a crash, during a boot cycle.
 const KEYSTORE_CRASH_COUNT_PROPERTY: &str = "keystore.crash_count";
@@ -980,31 +983,3 @@
         }
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn test_enum_show() {
-        let algo = MetricsAlgorithm::RSA;
-        assert_eq!("RSA ", algo.show());
-        let algo = MetricsAlgorithm(42);
-        assert_eq!("Unknown(42)", algo.show());
-    }
-
-    #[test]
-    fn test_enum_bitmask_show() {
-        let mut modes = 0i32;
-        compute_block_mode_bitmap(&mut modes, BlockMode::ECB);
-        compute_block_mode_bitmap(&mut modes, BlockMode::CTR);
-
-        assert_eq!(show_blockmode(modes), "-T-E");
-
-        // Add some bits not covered by the enum of valid bit positions.
-        modes |= 0xa0;
-        assert_eq!(show_blockmode(modes), "-T-E(full:0x000000aa)");
-        modes |= 0x300;
-        assert_eq!(show_blockmode(modes), "-T-E(full:0x000003aa)");
-    }
-}
diff --git a/keystore2/src/metrics_store/tests.rs b/keystore2/src/metrics_store/tests.rs
new file mode 100644
index 0000000..95d4a01
--- /dev/null
+++ b/keystore2/src/metrics_store/tests.rs
@@ -0,0 +1,160 @@
+// Copyright 2020, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use crate::metrics_store::*;
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    HardwareAuthenticatorType::HardwareAuthenticatorType as AuthType, KeyParameter::KeyParameter,
+    KeyParameterValue::KeyParameterValue, SecurityLevel::SecurityLevel, Tag::Tag,
+};
+use android_security_metrics::aidl::android::security::metrics::{
+    HardwareAuthenticatorType::HardwareAuthenticatorType as MetricsAuthType,
+    SecurityLevel::SecurityLevel as MetricsSecurityLevel,
+};
+
+#[test]
+fn test_enum_show() {
+    let algo = MetricsAlgorithm::RSA;
+    assert_eq!("RSA ", algo.show());
+    let algo = MetricsAlgorithm(42);
+    assert_eq!("Unknown(42)", algo.show());
+}
+
+#[test]
+fn test_enum_bitmask_show() {
+    let mut modes = 0i32;
+    compute_block_mode_bitmap(&mut modes, BlockMode::ECB);
+    compute_block_mode_bitmap(&mut modes, BlockMode::CTR);
+
+    assert_eq!(show_blockmode(modes), "-T-E");
+
+    // Add some bits not covered by the enum of valid bit positions.
+    modes |= 0xa0;
+    assert_eq!(show_blockmode(modes), "-T-E(full:0x000000aa)");
+    modes |= 0x300;
+    assert_eq!(show_blockmode(modes), "-T-E(full:0x000003aa)");
+}
+
+fn create_key_param_with_auth_type(auth_type: AuthType) -> KeyParameter {
+    KeyParameter {
+        tag: Tag::USER_AUTH_TYPE,
+        value: KeyParameterValue::HardwareAuthenticatorType(auth_type),
+    }
+}
+
+#[test]
+fn test_user_auth_type() {
+    let test_cases = [
+        (vec![], MetricsAuthType::NO_AUTH_TYPE),
+        (vec![AuthType::NONE], MetricsAuthType::NONE),
+        (vec![AuthType::PASSWORD], MetricsAuthType::PASSWORD),
+        (vec![AuthType::FINGERPRINT], MetricsAuthType::FINGERPRINT),
+        (
+            vec![AuthType(AuthType::PASSWORD.0 | AuthType::FINGERPRINT.0)],
+            MetricsAuthType::PASSWORD_OR_FINGERPRINT,
+        ),
+        (vec![AuthType::ANY], MetricsAuthType::ANY),
+        // 7 is the "next" undefined HardwareAuthenticatorType enum tag number, so
+        // force this test to fail and be updated if someone adds a new enum value.
+        (vec![AuthType(7)], MetricsAuthType::AUTH_TYPE_UNSPECIFIED),
+        (vec![AuthType(123)], MetricsAuthType::AUTH_TYPE_UNSPECIFIED),
+        (
+            // In practice, Tag::USER_AUTH_TYPE isn't a repeatable tag. It's allowed
+            // to appear once for auth-bound keys and contains the binary OR of the
+            // applicable auth types. However, this test case repeats the tag more
+            // than once in order to unit test the logic that constructs the atom.
+            vec![AuthType::ANY, AuthType(123), AuthType::PASSWORD],
+            // The last auth type wins.
+            MetricsAuthType::PASSWORD,
+        ),
+    ];
+    for (auth_types, expected) in test_cases {
+        let key_params: Vec<_> =
+            auth_types.iter().map(|a| create_key_param_with_auth_type(*a)).collect();
+        let (_, atom_with_auth_info, _) = process_key_creation_event_stats(
+            SecurityLevel::TRUSTED_ENVIRONMENT,
+            &key_params,
+            &Ok(()),
+        );
+        assert!(matches!(
+            atom_with_auth_info,
+            KeystoreAtomPayload::KeyCreationWithAuthInfo(a) if a.user_auth_type == expected
+        ));
+    }
+}
+
+fn create_key_param_with_auth_timeout(timeout: i32) -> KeyParameter {
+    KeyParameter { tag: Tag::AUTH_TIMEOUT, value: KeyParameterValue::Integer(timeout) }
+}
+
+#[test]
+fn test_log_auth_timeout_seconds() {
+    let test_cases = [
+        (vec![], -1),
+        (vec![-1], 0),
+        // The metrics code computes the value of this field for a timeout `t` with
+        // `f32::log10(t as f32) as i32`. The result of f32::log10(0 as f32) is `-inf`.
+        // Casting this to i32 means it gets "rounded" to i32::MIN, which is -2147483648.
+        (vec![0], -2147483648),
+        (vec![1], 0),
+        (vec![9], 0),
+        (vec![10], 1),
+        (vec![999], 2),
+        (
+            // In practice, Tag::AUTH_TIMEOUT isn't a repeatable tag. It's allowed to
+            // appear once for auth-bound keys. However, this test case repeats the
+            // tag more than once in order to unit test the logic that constructs the
+            // atom.
+            vec![1, 0, 10],
+            // The last timeout wins.
+            1,
+        ),
+    ];
+    for (timeouts, expected) in test_cases {
+        let key_params: Vec<_> =
+            timeouts.iter().map(|t| create_key_param_with_auth_timeout(*t)).collect();
+        let (_, atom_with_auth_info, _) = process_key_creation_event_stats(
+            SecurityLevel::TRUSTED_ENVIRONMENT,
+            &key_params,
+            &Ok(()),
+        );
+        assert!(matches!(
+            atom_with_auth_info,
+            KeystoreAtomPayload::KeyCreationWithAuthInfo(a)
+                if a.log10_auth_key_timeout_seconds == expected
+        ));
+    }
+}
+
+#[test]
+fn test_security_level() {
+    let test_cases = [
+        (SecurityLevel::SOFTWARE, MetricsSecurityLevel::SECURITY_LEVEL_SOFTWARE),
+        (
+            SecurityLevel::TRUSTED_ENVIRONMENT,
+            MetricsSecurityLevel::SECURITY_LEVEL_TRUSTED_ENVIRONMENT,
+        ),
+        (SecurityLevel::STRONGBOX, MetricsSecurityLevel::SECURITY_LEVEL_STRONGBOX),
+        (SecurityLevel::KEYSTORE, MetricsSecurityLevel::SECURITY_LEVEL_KEYSTORE),
+        (SecurityLevel(123), MetricsSecurityLevel::SECURITY_LEVEL_UNSPECIFIED),
+    ];
+    for (security_level, expected) in test_cases {
+        let (_, atom_with_auth_info, _) =
+            process_key_creation_event_stats(security_level, &[], &Ok(()));
+        assert!(matches!(
+            atom_with_auth_info,
+            KeystoreAtomPayload::KeyCreationWithAuthInfo(a)
+                if a.security_level == expected
+        ));
+    }
+}
