save uncrypt status to last_install am: e16e799dfd
am: 4769f209dc

Change-Id: Ic9056d4af518df3747743ec6b2886fa437029395
diff --git a/install.cpp b/install.cpp
index 4a856cd..d8073c5 100644
--- a/install.cpp
+++ b/install.cpp
@@ -30,6 +30,8 @@
 #include <string>
 #include <vector>
 
+#include <android-base/file.h>
+#include <android-base/logging.h>
 #include <android-base/parseint.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
@@ -53,6 +55,7 @@
 static constexpr const char* AB_OTA_PAYLOAD = "payload.bin";
 #define PUBLIC_KEYS_FILE "/res/keys"
 static constexpr const char* METADATA_PATH = "META-INF/com/android/metadata";
+static constexpr const char* UNCRYPT_STATUS = "/cache/recovery/uncrypt_status";
 
 // Default allocation of progress bar segments to operations
 static const int VERIFICATION_PROGRESS_TIME = 60;
@@ -534,6 +537,16 @@
             fprintf(install_log, "%s\n", s.c_str());
         }
 
+        if (ensure_path_mounted(UNCRYPT_STATUS) != 0) {
+            LOG(WARNING) << "Can't mount " << UNCRYPT_STATUS;
+        } else {
+            std::string uncrypt_status;
+            if (!android::base::ReadFileToString(UNCRYPT_STATUS, &uncrypt_status)) {
+                PLOG(WARNING) << "failed to read uncrypt status";
+            } else {
+                fprintf(install_log, "%s\n", android::base::Trim(uncrypt_status).c_str());
+            }
+        }
         fclose(install_log);
     }
     return result;
diff --git a/uncrypt/uncrypt.cpp b/uncrypt/uncrypt.cpp
index b7867ed..21db290 100644
--- a/uncrypt/uncrypt.cpp
+++ b/uncrypt/uncrypt.cpp
@@ -130,6 +130,7 @@
 // devices, on which /cache partitions always exist.
 static const std::string CACHE_BLOCK_MAP = "/cache/recovery/block.map";
 static const std::string UNCRYPT_PATH_FILE = "/cache/recovery/uncrypt_file";
+static const std::string UNCRYPT_STATUS = "/cache/recovery/uncrypt_status";
 static const std::string UNCRYPT_SOCKET = "uncrypt";
 
 static struct fstab* fstab = nullptr;
@@ -461,12 +462,32 @@
         input_path = package.c_str();
     }
     CHECK(map_file != nullptr);
+
+#define UNCRYPT_TIME_HOLDER 0x7FFFFFFF
+    // Intialize the uncrypt time cost to a huge number so that we can tell from
+    // the statistics if an uncrypt fails to finish.
+    if (!android::base::WriteStringToFile(android::base::StringPrintf(
+            "uncrypt_time: %d\n", UNCRYPT_TIME_HOLDER), UNCRYPT_STATUS)) {
+        PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
+    }
+
+    auto start = std::chrono::system_clock::now();
     int status = uncrypt(input_path, map_file, socket);
     if (status != 0) {
         write_status_to_socket(-1, socket);
         return false;
     }
+
+    std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
+    int count = static_cast<int>(duration.count());
+    // Overwrite the uncrypt_time if uncrypt finishes successfully.
+    if (!android::base::WriteStringToFile(
+            android::base::StringPrintf("uncrypt_time: %d\n", count), UNCRYPT_STATUS)) {
+        PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
+    }
+
     write_status_to_socket(100, socket);
+
     return true;
 }