Keystore2: Wait for statsd to be available before calling statsd_write()

This is to avoid errors being printed at keystore2 startup due to
statsd not being available.
(refer b/185844285#comment13 for other options for avoiding this)

Also, removed watch dog watch point in async_task since waiting for
boot completion takes a lot of time, triggering watch dog.

Also changed register_pull_metrics_callbacks to use
wait_for_boot_completed and be called in async_task.

Bug: 188441750
Test: statsd Test Drive script for all three types of atoms.
keystore2 startup logs.
Merged-In: I41b48526aad9702dd29f93d139e5f2afba89be3a

Change-Id: I41b48526aad9702dd29f93d139e5f2afba89be3a
diff --git a/keystore2/src/metrics.rs b/keystore2/src/metrics.rs
index 07c3d64..10a465c 100644
--- a/keystore2/src/metrics.rs
+++ b/keystore2/src/metrics.rs
@@ -23,7 +23,7 @@
     KeyParameter::KeyParameter, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
     SecurityLevel::SecurityLevel,
 };
-use anyhow::Result;
+use anyhow::{anyhow, Result};
 use keystore2_system_property::PropertyWatcher;
 use statslog_rust::{
     keystore2_key_creation_event_reported::{
@@ -40,6 +40,47 @@
 use statslog_rust_header::Atoms;
 use statspull_rust::{set_pull_atom_callback, StatsPullResult};
 
+// Waits and returns Ok if boot is completed.
+fn wait_for_boot_completed() -> Result<()> {
+    let watcher = PropertyWatcher::new("sys.boot_completed");
+    match watcher {
+        Ok(mut watcher) => {
+            loop {
+                let wait_result = watcher.wait();
+                match wait_result {
+                    Ok(_) => {
+                        let value_result =
+                            watcher.read(|_name, value| Ok(value.trim().to_string()));
+                        match value_result {
+                            Ok(value) => {
+                                if value == "1" {
+                                    break;
+                                }
+                            }
+                            Err(e) => {
+                                log::error!(
+                                    "In wait_for_boot_completed: Failed while reading property. {}",
+                                    e
+                                );
+                                return Err(anyhow!("Error in waiting for boot completion."));
+                            }
+                        }
+                    }
+                    Err(e) => {
+                        log::error!("In wait_for_boot_completed: Failed while waiting. {}", e);
+                        return Err(anyhow!("Error in waiting for boot completion."));
+                    }
+                }
+            }
+            Ok(())
+        }
+        Err(e) => {
+            log::error!("In wait_for_boot_completed: Failed to create PropertyWatcher. {}", e);
+            Err(anyhow!("Error in waiting for boot completion."))
+        }
+    }
+}
+
 fn create_default_key_creation_atom() -> Keystore2KeyCreationEventReported {
     // If a value is not present, fields represented by bitmaps and i32 fields
     // will take 0, except error_code which defaults to 1 indicating NO_ERROR and key_size,
@@ -89,10 +130,10 @@
         construct_key_creation_event_stats(sec_level, key_params, result);
 
     LOGS_HANDLER.queue_lo(move |_| {
-        let logging_result = key_creation_event_stats.stats_write();
-
-        if let Err(e) = logging_result {
-            log::error!("Error in logging key creation event in the async task. {:?}", e);
+        if let Ok(()) = wait_for_boot_completed() {
+            if let Err(e) = key_creation_event_stats.stats_write() {
+                log::error!("Error in logging key creation event in the async task. {:?}", e);
+            }
         }
     });
 }
@@ -114,10 +155,10 @@
     );
 
     LOGS_HANDLER.queue_lo(move |_| {
-        let logging_result = key_operation_event_stats.stats_write();
-
-        if let Err(e) = logging_result {
-            log::error!("Error in logging key operation event in the async task. {:?}", e);
+        if let Ok(()) = wait_for_boot_completed() {
+            if let Err(e) = key_operation_event_stats.stats_write() {
+                log::error!("Error in logging key operation event in the async task. {:?}", e);
+            }
         }
     });
 }
@@ -383,21 +424,17 @@
 }
 
 /// Registers pull metrics callbacks
-pub fn register_pull_metrics_callbacks() -> Result<()> {
+pub fn register_pull_metrics_callbacks() {
     // Before registering the callbacks with statsd, we have to wait for the system to finish
     // booting up. This avoids possible races that may occur at startup. For example, statsd
     // depends on a companion service, and if registration happens too soon it will fail since
     // the companion service isn't up yet.
-    let mut watcher = PropertyWatcher::new("sys.boot_completed")?;
-    loop {
-        watcher.wait()?;
-        let value = watcher.read(|_name, value| Ok(value.trim().to_string()));
-        if value? == "1" {
+    LOGS_HANDLER.queue_lo(move |_| {
+        if let Ok(()) = wait_for_boot_completed() {
             set_pull_atom_callback(Atoms::Keystore2StorageStats, None, pull_metrics_callback);
-            break;
+            log::info!("Pull metrics callbacks successfully registered.")
         }
-    }
-    Ok(())
+    });
 }
 
 fn pull_metrics_callback() -> StatsPullResult {