Snap for 8285583 from d86dd8b03225cdfa85fbc1e835cc8eb1653c4787 to mainline-extservices-release

Change-Id: If20f4eb033b4d2447d587c6765b8c9038cadf57c
diff --git a/odrefresh/odr_config.h b/odrefresh/odr_config.h
index 4161944..467bb53 100644
--- a/odrefresh/odr_config.h
+++ b/odrefresh/odr_config.h
@@ -17,6 +17,7 @@
 #ifndef ART_ODREFRESH_ODR_CONFIG_H_
 #define ART_ODREFRESH_ODR_CONFIG_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -49,6 +50,7 @@
   std::string dex2oat_;
   std::string dex2oat_boot_classpath_;
   bool dry_run_;
+  std::optional<bool> partial_compilation_;
   InstructionSet isa_;
   std::string program_name_;
   std::string system_server_classpath_;
@@ -115,6 +117,10 @@
   }
 
   bool GetDryRun() const { return dry_run_; }
+  bool GetPartialCompilation() const {
+    return partial_compilation_.value_or(true);
+  }
+
   const std::string& GetSystemServerClasspath() const { return system_server_classpath_; }
   const std::string& GetUpdatableBcpPackagesFile() const { return updatable_bcp_packages_file_; }
 
@@ -126,6 +132,9 @@
   }
 
   void SetDryRun() { dry_run_ = true; }
+  void SetPartialCompilation(bool value) {
+    partial_compilation_ = value;
+  }
   void SetIsa(const InstructionSet isa) { isa_ = isa; }
 
   void SetSystemServerClasspath(const std::string& classpath) {
diff --git a/odrefresh/odrefresh.cc b/odrefresh/odrefresh.cc
index 2cef50d..7ca6cf2 100644
--- a/odrefresh/odrefresh.cc
+++ b/odrefresh/odrefresh.cc
@@ -38,6 +38,7 @@
 #include <memory>
 #include <optional>
 #include <ostream>
+#include <regex>
 #include <sstream>
 #include <string>
 #include <string_view>
@@ -48,7 +49,9 @@
 #include "android-base/file.h"
 #include "android-base/logging.h"
 #include "android-base/macros.h"
+#include "android-base/parseint.h"
 #include "android-base/properties.h"
+#include "android-base/result.h"
 #include "android-base/stringprintf.h"
 #include "android-base/strings.h"
 #include "android/log.h"
@@ -65,14 +68,13 @@
 #include "dexoptanalyzer.h"
 #include "exec_utils.h"
 #include "log/log.h"
-#include "palette/palette.h"
-#include "palette/palette_types.h"
-
 #include "odr_artifacts.h"
 #include "odr_compilation_log.h"
 #include "odr_config.h"
 #include "odr_fs_utils.h"
 #include "odr_metrics.h"
+#include "palette/palette.h"
+#include "palette/palette_types.h"
 
 namespace art {
 namespace odrefresh {
@@ -85,6 +87,8 @@
 // Name of cache info file in the ART Apex artifact cache.
 static constexpr const char* kCacheInfoFile = "cache-info.xml";
 
+using ::android::base::Result;
+
 static void UsageErrorV(const char* fmt, va_list ap) {
   std::string error;
   android::base::StringAppendV(&error, fmt, ap);
@@ -211,6 +215,30 @@
   return true;
 }
 
+Result<int> ParseSecurityPatchStr(const std::string& security_patch_str) {
+  std::regex security_patch_regex(R"re((\d{4})-(\d{2})-(\d{2}))re");
+  std::smatch m;
+  if (!std::regex_match(security_patch_str, m, security_patch_regex)) {
+    return Errorf("Invalid security patch string \"{}\"", security_patch_str);
+  }
+  int year = 0, month = 0, day = 0;
+  if (!android::base::ParseInt(m[1], &year) || !android::base::ParseInt(m[2], &month) ||
+      !android::base::ParseInt(m[3], &day)) {
+    // This should never happen because the string already matches the regex.
+    return Errorf("Unknown error when parsing security patch string \"{}\"", security_patch_str);
+  }
+  return year * 10000 + month * 100 + day;
+}
+
+bool ShouldDisablePartialCompilation(const std::string& security_patch_str) {
+  Result<int> security_patch_value = ParseSecurityPatchStr(security_patch_str);
+  if (!security_patch_value.ok()) {
+    LOG(ERROR) << security_patch_value.error();
+    return false;
+  }
+  return security_patch_value.value() < ParseSecurityPatchStr("2022-03-05").value();
+}
+
 }  // namespace
 
 bool ParseZygoteKind(const char* input, ZygoteKind* zygote_kind) {
@@ -1272,7 +1300,7 @@
     const char* staging_dir = nullptr;
     metrics.SetStage(OdrMetrics::Stage::kPreparation);
     // Clean-up existing files.
-    if (force_compile && !CleanApexdataDirectory()) {
+    if ((force_compile || !config_.GetPartialCompilation()) && !CleanApexdataDirectory()) {
       metrics.SetStatus(OdrMetrics::Status::kIoError);
       return ExitCode::kCleanupFailed;
     }
@@ -1434,6 +1462,11 @@
         android::base::GetProperty("dalvik.vm.dex2oat-updatable-bcp-packages-file", {});
     config->SetUpdatableBcpPackagesFile(updatable_packages);
 
+    if (ShouldDisablePartialCompilation(
+            android::base::GetProperty("ro.build.version.security_patch", /*default_value=*/""))) {
+      config->SetPartialCompilation(false);
+    }
+
     int n = 1;
     for (; n < argc - 1; ++n) {
       if (!InitializeCommonConfig(argv[n], config)) {
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 8b13523..bc079f0 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -3232,7 +3232,7 @@
   }
   self->AssertNoPendingException();
   CHECK(h_new_class != nullptr) << descriptor;
-  CHECK(h_new_class->IsResolved() && !h_new_class->IsErroneousResolved()) << descriptor;
+  CHECK(h_new_class->IsResolved()) << descriptor << " " << h_new_class->GetStatus();
 
   // Instrumentation may have updated entrypoints for all methods of all
   // classes. However it could not update methods of this class while we