Merge "Deprecate cc_binary aconfigd and the controlling flag" into main
diff --git a/fs_mgr/libfstab/fstab.cpp b/fs_mgr/libfstab/fstab.cpp
index ca35990..01e0e3d 100644
--- a/fs_mgr/libfstab/fstab.cpp
+++ b/fs_mgr/libfstab/fstab.cpp
@@ -39,10 +39,6 @@
 #include "fstab_priv.h"
 #include "logging_macros.h"
 
-#if !defined(MS_LAZYTIME)
-#define MS_LAZYTIME (1 << 25)
-#endif
-
 using android::base::EndsWith;
 using android::base::ParseByteCount;
 using android::base::ParseInt;
diff --git a/fs_mgr/tests/fs_mgr_test.cpp b/fs_mgr/tests/fs_mgr_test.cpp
index 6e050cf..8004977 100644
--- a/fs_mgr/tests/fs_mgr_test.cpp
+++ b/fs_mgr/tests/fs_mgr_test.cpp
@@ -37,10 +37,6 @@
 using namespace android::fs_mgr;
 using namespace testing;
 
-#if !defined(MS_LAZYTIME)
-#define MS_LAZYTIME (1 << 25)
-#endif
-
 namespace {
 
 const std::string cmdline =
diff --git a/init/libprefetch/prefetch/prefetch.rc b/init/libprefetch/prefetch/prefetch.rc
index 9f2cb7f..fb3fb3b 100644
--- a/init/libprefetch/prefetch/prefetch.rc
+++ b/init/libprefetch/prefetch/prefetch.rc
@@ -1,3 +1,16 @@
+on init && property:ro.prefetch_boot.enabled=true
+    start prefetch
+
+service prefetch /system/bin/prefetch start
+    class main
+    user root
+    group root system
+    disabled
+    oneshot
+
+on property:ro.prefetch_boot.record=true
+    start prefetch_record
+
 service prefetch_record /system/bin/prefetch record --duration ${ro.prefetch_boot.duration_s:-0}
     class main
     user root
@@ -5,6 +18,9 @@
     disabled
     oneshot
 
+on property:ro.prefetch_boot.replay=true
+    start prefetch_replay
+
 service prefetch_replay /system/bin/prefetch replay --io-depth ${ro.prefetch_boot.io_depth:-2} --max-fds ${ro.prefetch_boot.max_fds:-128}
     class main
     user root
diff --git a/init/libprefetch/prefetch/src/arch/android.rs b/init/libprefetch/prefetch/src/arch/android.rs
new file mode 100644
index 0000000..3404e42
--- /dev/null
+++ b/init/libprefetch/prefetch/src/arch/android.rs
@@ -0,0 +1,118 @@
+use crate::Error;
+use crate::RecordArgs;
+use crate::StartArgs;
+use log::info;
+use log::warn;
+use std::fs::File;
+use std::fs::OpenOptions;
+use std::io::Write;
+use std::time::Duration;
+
+use rustutils::system_properties::error::PropertyWatcherError;
+use rustutils::system_properties::PropertyWatcher;
+
+const PREFETCH_RECORD_PROPERTY: &str = "prefetch_boot.record";
+const PREFETCH_REPLAY_PROPERTY: &str = "prefetch_boot.replay";
+const PREFETCH_RECORD_PROPERTY_STOP: &str = "ro.prefetch_boot.record_stop";
+
+fn wait_for_property_true(
+    property_name: &str,
+    timeout: Option<Duration>,
+) -> Result<(), PropertyWatcherError> {
+    let mut prop = PropertyWatcher::new(property_name)?;
+    prop.wait_for_value("1", timeout)?;
+    Ok(())
+}
+
+/// Wait for record to stop
+pub fn wait_for_record_stop() {
+    wait_for_property_true(PREFETCH_RECORD_PROPERTY_STOP, None).unwrap_or_else(|e| {
+        warn!("failed to wait for {} with error: {}", PREFETCH_RECORD_PROPERTY_STOP, e)
+    });
+}
+
+fn start_prefetch_service(property_name: &str) -> Result<(), Error> {
+    match rustutils::system_properties::write(property_name, "true") {
+        Ok(_) => {}
+        Err(_) => {
+            return Err(Error::Custom { error: "Failed to start prefetch service".to_string() });
+        }
+    }
+    Ok(())
+}
+
+/// Start prefetch service
+///
+/// 1: Check the presence of the file 'prefetch_ready'. If it doesn't
+/// exist then the device is booting for the first time after wipe.
+/// Thus, we would just create the file and exit as we do not want
+/// to initiate the record after data wipe primiarly because boot
+/// after data wipe is long and the I/O pattern during first boot may not actually match
+/// with subsequent boot.
+///
+/// 2: If the file 'prefetch_ready' is present:
+///
+///   a: Compare the build-finger-print of the device with the one record format
+///   is associated with by reading the file 'build_finger_print'. If they match,
+///   start the prefetch_replay.
+///
+///   b: If they don't match, then the device was updated through OTA. Hence, start
+///   a fresh record and delete the build-finger-print file. This should also cover
+///   the case of device rollback.
+///
+///   c: If the build-finger-print file doesn't exist, then just restart the record
+///   from scratch.
+pub fn start_prefetch(args: &StartArgs) -> Result<(), Error> {
+    if !args.path.exists() {
+        match File::create(args.path.clone()) {
+            Ok(_) => {}
+            Err(_) => {
+                return Err(Error::Custom { error: "File Creation failed".to_string() });
+            }
+        }
+        return Ok(());
+    }
+
+    if args.build_fingerprint_path.exists() {
+        let device_build_fingerprint = rustutils::system_properties::read("ro.build.fingerprint")
+            .map_err(|e| Error::Custom {
+            error: format!("Failed to read ro.build.fingerprint: {}", e),
+        })?;
+        let pack_build_fingerprint = std::fs::read_to_string(&args.build_fingerprint_path)?;
+        if pack_build_fingerprint.trim() == device_build_fingerprint.as_deref().unwrap_or_default()
+        {
+            info!("Start replay");
+            start_prefetch_service(PREFETCH_REPLAY_PROPERTY)?;
+        } else {
+            info!("Start record");
+            std::fs::remove_file(&args.build_fingerprint_path)?;
+            start_prefetch_service(PREFETCH_RECORD_PROPERTY)?;
+        }
+    } else {
+        info!("Start record");
+        start_prefetch_service(PREFETCH_RECORD_PROPERTY)?;
+    }
+    Ok(())
+}
+
+/// Write build finger print to associate prefetch pack file
+pub fn write_build_fingerprint(args: &RecordArgs) -> Result<(), Error> {
+    let mut build_fingerprint_file = OpenOptions::new()
+        .write(true)
+        .create(true)
+        .truncate(true)
+        .open(&args.build_fingerprint_path)
+        .map_err(|source| Error::Create {
+            source,
+            path: args.build_fingerprint_path.to_str().unwrap().to_owned(),
+        })?;
+
+    let device_build_fingerprint =
+        rustutils::system_properties::read("ro.build.fingerprint").unwrap_or_default();
+    let device_build_fingerprint = device_build_fingerprint.unwrap_or_default();
+
+    build_fingerprint_file.write_all(device_build_fingerprint.as_bytes())?;
+    build_fingerprint_file.sync_all()?;
+
+    Ok(())
+}
diff --git a/init/libprefetch/prefetch/src/args.rs b/init/libprefetch/prefetch/src/args.rs
index 4c1e689..e534210 100644
--- a/init/libprefetch/prefetch/src/args.rs
+++ b/init/libprefetch/prefetch/src/args.rs
@@ -25,6 +25,8 @@
 
 pub use args_internal::OutputFormat;
 pub use args_internal::ReplayArgs;
+#[cfg(target_os = "android")]
+pub use args_internal::StartArgs;
 pub use args_internal::TracerType;
 pub use args_internal::{DumpArgs, MainArgs, RecordArgs, SubCommands};
 use serde::Deserialize;
@@ -66,6 +68,8 @@
         SubCommands::Dump(arg) => {
             ensure_path_exists(&arg.path)?;
         }
+        #[cfg(target_os = "android")]
+        SubCommands::Start(_arg) => return Ok(()),
     }
     Ok(())
 }
diff --git a/init/libprefetch/prefetch/src/args/args_argh.rs b/init/libprefetch/prefetch/src/args/args_argh.rs
index 8ac95fc..65084ee 100644
--- a/init/libprefetch/prefetch/src/args/args_argh.rs
+++ b/init/libprefetch/prefetch/src/args/args_argh.rs
@@ -40,6 +40,38 @@
     Replay(ReplayArgs),
     /// Dump prefetch data in human readable format
     Dump(DumpArgs),
+    /// Start prefetch service if possible
+    /// If the pack file is present, then prefetch replay is started
+    /// If the pack file is absent or if the build fingerprint
+    /// of the current pack file is different, then prefetch record is started.
+    #[cfg(target_os = "android")]
+    Start(StartArgs),
+}
+
+#[cfg(target_os = "android")]
+fn default_ready_path() -> PathBuf {
+    PathBuf::from("/metadata/prefetch/prefetch_ready")
+}
+
+#[cfg(target_os = "android")]
+fn default_build_finger_print_path() -> PathBuf {
+    PathBuf::from("/metadata/prefetch/build_finger_print")
+}
+
+#[cfg(target_os = "android")]
+#[derive(Eq, PartialEq, Debug, Default, FromArgs)]
+/// Start prefetch service based on if pack file is present.
+#[argh(subcommand, name = "start")]
+pub struct StartArgs {
+    /// file path to check if prefetch_ready is present.
+    ///
+    /// A new file is created at the given path if it's not present.
+    #[argh(option, default = "default_ready_path()")]
+    pub path: PathBuf,
+
+    /// file path where build fingerprint is stored
+    #[argh(option, default = "default_build_finger_print_path()")]
+    pub build_fingerprint_path: PathBuf,
 }
 
 impl Default for SubCommands {
@@ -110,6 +142,11 @@
         from_str_fn(parse_tracing_instance)
     )]
     pub tracing_instance: Option<String>,
+
+    #[cfg(target_os = "android")]
+    /// store build_finger_print to tie the pack format
+    #[argh(option, default = "default_build_finger_print_path()")]
+    pub build_fingerprint_path: PathBuf,
 }
 
 /// Type of tracing subsystem to use.
diff --git a/init/libprefetch/prefetch/src/lib.rs b/init/libprefetch/prefetch/src/lib.rs
index 4b56b13..6564c4b 100644
--- a/init/libprefetch/prefetch/src/lib.rs
+++ b/init/libprefetch/prefetch/src/lib.rs
@@ -20,6 +20,10 @@
 mod format;
 mod replay;
 mod tracer;
+#[cfg(target_os = "android")]
+mod arch {
+    pub mod android;
+}
 
 use std::fs::File;
 use std::fs::OpenOptions;
@@ -38,6 +42,8 @@
 pub use args::args_from_env;
 use args::OutputFormat;
 pub use args::ReplayArgs;
+#[cfg(target_os = "android")]
+pub use args::StartArgs;
 pub use args::{DumpArgs, MainArgs, RecordArgs, SubCommands};
 pub use error::Error;
 pub use format::FileId;
@@ -45,29 +51,11 @@
 pub use format::Record;
 pub use format::RecordsFile;
 use log::info;
-#[cfg(target_os = "android")]
-use log::warn;
 pub use replay::Replay;
 pub use tracer::nanoseconds_since_boot;
 
 #[cfg(target_os = "android")]
-use rustutils::system_properties;
-#[cfg(target_os = "android")]
-use rustutils::system_properties::error::PropertyWatcherError;
-#[cfg(target_os = "android")]
-use rustutils::system_properties::PropertyWatcher;
-
-#[cfg(target_os = "android")]
-fn wait_for_property_true(property_name: &str) -> Result<(), PropertyWatcherError> {
-    let mut prop = PropertyWatcher::new(property_name)?;
-    loop {
-        prop.wait(None)?;
-        if system_properties::read_bool(property_name, false)? {
-            break;
-        }
-    }
-    Ok(())
-}
+pub use arch::android::*;
 
 /// Records prefetch data for the given configuration
 pub fn record(args: &RecordArgs) -> Result<(), Error> {
@@ -85,11 +73,10 @@
             thread::sleep(duration);
         } else {
             #[cfg(target_os = "android")]
-            wait_for_property_true("sys.boot_completed").unwrap_or_else(|e| {
-                warn!("failed to wait for sys.boot_completed with error: {}", e)
-            });
+            wait_for_record_stop();
         }
 
+        info!("Prefetch record exiting");
         // We want to unwrap here on failure to send this signal. Otherwise
         // tracer will continue generating huge records data.
         exit_tx.send(()).unwrap();
@@ -107,9 +94,16 @@
     std::fs::set_permissions(&args.path, std::fs::Permissions::from_mode(0o644))
         .map_err(|source| Error::Create { source, path: args.path.to_str().unwrap().to_owned() })?;
 
+    // Write the record file
     out_file
         .write_all(&rf.add_checksum_and_serialize()?)
         .map_err(|source| Error::Write { path: args.path.to_str().unwrap().to_owned(), source })?;
+    out_file.sync_all()?;
+
+    // Write build-finger-print file
+    #[cfg(target_os = "android")]
+    write_build_fingerprint(args)?;
+
     Ok(())
 }
 
diff --git a/init/libprefetch/prefetch/src/main.rs b/init/libprefetch/prefetch/src/main.rs
index 046e07e..eab826f 100644
--- a/init/libprefetch/prefetch/src/main.rs
+++ b/init/libprefetch/prefetch/src/main.rs
@@ -22,6 +22,8 @@
 use prefetch_rs::init_logging;
 use prefetch_rs::record;
 use prefetch_rs::replay;
+#[cfg(target_os = "android")]
+use prefetch_rs::start_prefetch;
 use prefetch_rs::LogLevel;
 use prefetch_rs::MainArgs;
 use prefetch_rs::SubCommands;
@@ -33,6 +35,8 @@
         SubCommands::Record(args) => record(args),
         SubCommands::Replay(args) => replay(args),
         SubCommands::Dump(args) => dump(args),
+        #[cfg(target_os = "android")]
+        SubCommands::Start(args) => start_prefetch(args),
     };
 
     if let Err(err) = ret {
diff --git a/libutils/OWNERS b/libutils/OWNERS
index 40164aa..4ce6893 100644
--- a/libutils/OWNERS
+++ b/libutils/OWNERS
@@ -1 +1,2 @@
+shayba@google.com
 smoreland@google.com
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 6f32ccc..060395d 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -609,17 +609,6 @@
 
     mkdir /metadata/staged-install 0770 root system
 
-    mkdir /metadata/aconfig 0775 root system
-    mkdir /metadata/aconfig/flags 0770 root system
-    mkdir /metadata/aconfig/maps 0775 root system
-    mkdir /metadata/aconfig/boot 0775 root system
-
-    mkdir /metadata/aconfig_test_missions 0775 root system
-
-    # See flag enable_system_aconfigd_rust, which toggles these processes.
-    exec_start system_aconfigd_platform_init
-    exec_start aconfigd-platform-init
-
 on late-fs
     # Ensure that tracefs has the correct permissions.
     # This does not work correctly if it is called in post-fs.
@@ -736,7 +725,6 @@
     mkdir /data/apex/active 0755 root system
     mkdir /data/apex/backup 0700 root system
     mkdir /data/apex/decompressed 0755 root system encryption=Require
-    mkdir /data/apex/hashtree 0700 root system
     mkdir /data/apex/sessions 0700 root system
     mkdir /data/app-staging 0751 system system encryption=DeleteIfNecessary
     mkdir /data/apex/ota_reserved 0700 root system encryption=Require
diff --git a/trusty/keymaster/Android.bp b/trusty/keymaster/Android.bp
index 5a1e420..8ebfc1a 100644
--- a/trusty/keymaster/Android.bp
+++ b/trusty/keymaster/Android.bp
@@ -106,11 +106,11 @@
         "keymint/service.cpp",
     ],
     shared_libs: [
-        "android.hardware.security.keymint-V3-ndk",
+        "android.hardware.security.keymint-V4-ndk",
         "android.hardware.security.rkp-V3-ndk",
         "android.hardware.security.secureclock-V1-ndk",
         "android.hardware.security.sharedsecret-V1-ndk",
-        "lib_android_keymaster_keymint_utils_V3",
+        "lib_android_keymaster_keymint_utils",
         "libbase",
         "libbinder_ndk",
         "libhardware",
@@ -120,9 +120,10 @@
         "libtrusty",
         "libutils",
     ],
-    required: [
-        "android.hardware.hardware_keystore_V3.xml",
-    ],
+    required: select(release_flag("RELEASE_AIDL_USE_UNFROZEN"), {
+        true: ["android.hardware.hardware_keystore.xml"],
+        default: ["android.hardware.hardware_keystore_V3.xml"],
+    }),
 }
 
 prebuilt_etc {
diff --git a/trusty/keymaster/TrustyKeymaster.cpp b/trusty/keymaster/TrustyKeymaster.cpp
index b118a20..723229d 100644
--- a/trusty/keymaster/TrustyKeymaster.cpp
+++ b/trusty/keymaster/TrustyKeymaster.cpp
@@ -295,6 +295,13 @@
     return response;
 }
 
+SetAdditionalAttestationInfoResponse TrustyKeymaster::SetAdditionalAttestationInfo(
+        const SetAdditionalAttestationInfoRequest& request) {
+    SetAdditionalAttestationInfoResponse response(message_version());
+    ForwardCommand(KM_SET_ADDITIONAL_ATTESTATION_INFO, request, &response);
+    return response;
+}
+
 GetHwInfoResponse TrustyKeymaster::GetHwInfo() {
     GetHwInfoResponse response(message_version());
     ForwardCommand(KM_GET_HW_INFO, GetHwInfoRequest(message_version()), &response);
diff --git a/trusty/keymaster/include/trusty_keymaster/TrustyKeyMintDevice.h b/trusty/keymaster/include/trusty_keymaster/TrustyKeyMintDevice.h
index c8d8932..5e876d3 100644
--- a/trusty/keymaster/include/trusty_keymaster/TrustyKeyMintDevice.h
+++ b/trusty/keymaster/include/trusty_keymaster/TrustyKeyMintDevice.h
@@ -85,6 +85,7 @@
     ScopedAStatus getRootOfTrust(const array<uint8_t, 16>& challenge,
                                  vector<uint8_t>* rootOfTrust) override;
     ScopedAStatus sendRootOfTrust(const vector<uint8_t>& rootOfTrust) override;
+    ScopedAStatus setAdditionalAttestationInfo(const vector<KeyParameter>& info) override;
 
   protected:
     std::shared_ptr<TrustyKeymaster> impl_;
diff --git a/trusty/keymaster/include/trusty_keymaster/TrustyKeymaster.h b/trusty/keymaster/include/trusty_keymaster/TrustyKeymaster.h
index c50178b..65d7217 100644
--- a/trusty/keymaster/include/trusty_keymaster/TrustyKeymaster.h
+++ b/trusty/keymaster/include/trusty_keymaster/TrustyKeymaster.h
@@ -70,6 +70,8 @@
     ConfigureVendorPatchlevelResponse ConfigureVendorPatchlevel(
             const ConfigureVendorPatchlevelRequest& request);
     GetRootOfTrustResponse GetRootOfTrust(const GetRootOfTrustRequest& request);
+    SetAdditionalAttestationInfoResponse SetAdditionalAttestationInfo(
+            const SetAdditionalAttestationInfoRequest& request);
     GetHwInfoResponse GetHwInfo();
 
     uint32_t message_version() const { return message_version_; }
diff --git a/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h b/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h
index 822e933..721315d 100644
--- a/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h
+++ b/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h
@@ -62,6 +62,7 @@
     KM_GET_ROOT_OF_TRUST            = (34 << KEYMASTER_REQ_SHIFT),
     KM_GET_HW_INFO                  = (35 << KEYMASTER_REQ_SHIFT),
     KM_GENERATE_CSR_V2              = (36 << KEYMASTER_REQ_SHIFT),
+    KM_SET_ADDITIONAL_ATTESTATION_INFO = (37 << KEYMASTER_REQ_SHIFT),
 
     // Bootloader/provisioning calls.
     KM_SET_BOOT_PARAMS = (0x1000 << KEYMASTER_REQ_SHIFT),
diff --git a/trusty/keymaster/keymint/TrustyKeyMintDevice.cpp b/trusty/keymaster/keymint/TrustyKeyMintDevice.cpp
index fec4c60..154597f 100644
--- a/trusty/keymaster/keymint/TrustyKeyMintDevice.cpp
+++ b/trusty/keymaster/keymint/TrustyKeyMintDevice.cpp
@@ -349,4 +349,18 @@
     return kmError2ScopedAStatus(KM_ERROR_UNIMPLEMENTED);
 }
 
+ScopedAStatus TrustyKeyMintDevice::setAdditionalAttestationInfo(const vector<KeyParameter>& info) {
+    keymaster::SetAdditionalAttestationInfoRequest request(impl_->message_version());
+    request.info.Reinitialize(KmParamSet(info));
+
+    keymaster::SetAdditionalAttestationInfoResponse response =
+            impl_->SetAdditionalAttestationInfo(request);
+
+    if (response.error != KM_ERROR_OK) {
+        return kmError2ScopedAStatus(response.error);
+    } else {
+        return ScopedAStatus::ok();
+    }
+}
+
 }  // namespace aidl::android::hardware::security::keymint::trusty
diff --git a/trusty/keymaster/keymint/android.hardware.security.keymint-service.trusty.xml b/trusty/keymaster/keymint/android.hardware.security.keymint-service.trusty.xml
index 3dc9c88..f74d212 100644
--- a/trusty/keymaster/keymint/android.hardware.security.keymint-service.trusty.xml
+++ b/trusty/keymaster/keymint/android.hardware.security.keymint-service.trusty.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.security.keymint</name>
-        <version>3</version>
+        <version>4</version>
         <fqname>IKeyMintDevice/default</fqname>
     </hal>
     <hal format="aidl">
diff --git a/trusty/keymint/android.hardware.security.keymint-service.rust.trusty.system.nonsecure.rc b/trusty/keymint/android.hardware.security.keymint-service.rust.trusty.system.nonsecure.rc
index 410e10a..e580651 100644
--- a/trusty/keymint/android.hardware.security.keymint-service.rust.trusty.system.nonsecure.rc
+++ b/trusty/keymint/android.hardware.security.keymint-service.rust.trusty.system.nonsecure.rc
@@ -11,7 +11,7 @@
 # Only starts the non-secure KeyMint HALs when the KeyMint VM feature is enabled
 # TODO(b/357821690): Start the KeyMint HALs when the KeyMint VM is ready once the Trusty VM
 # has a mechanism to notify the host.
-on late-fs && property:ro.hardware.trusty.security_vm.keymint.enabled=1 && \
+on late-fs && property:trusty.security_vm.keymint.enabled=1 && \
    property:trusty.security_vm.vm_cid=*
     setprop system.keymint.trusty_ipc_dev VSOCK:${trusty.security_vm.vm_cid}:1
     start system.keymint.rust-trusty.nonsecure