Make CompatFramework::ReportChange thread safe

Guard accesses to reported_compat_changes_ with
reported_compat_changes_lock_. Guarding disabled_compat_changes_ should
not be necessary, as it's initialized synchronously early after zygote
fork, never to be changed afterwards.

Bug: 174843201
Test: manual
Change-Id: I73b5dadf0576c2bc163602f566486172c35dd78d
diff --git a/runtime/compat_framework.cc b/runtime/compat_framework.cc
index 40c4540..17d423b 100644
--- a/runtime/compat_framework.cc
+++ b/runtime/compat_framework.cc
@@ -16,10 +16,12 @@
 
 #include "compat_framework.h"
 
-#include "android-base/logging.h"
 #include <sys/types.h>
 #include <unistd.h>
 
+#include "android-base/logging.h"
+#include "thread-current-inl.h"
+
 namespace art {
 
 // Compat change states as strings.
@@ -28,6 +30,11 @@
 static constexpr char kDisabledChangeState[] = "DISABLED";
 static constexpr char kLoggedState[] = "LOGGED";
 
+CompatFramework::CompatFramework()
+    : reported_compat_changes_lock_("reported compat changes lock") {}
+
+CompatFramework::~CompatFramework() {}
+
 bool CompatFramework::IsChangeEnabled(uint64_t change_id) {
   const auto enabled = disabled_compat_changes_.count(change_id) == 0;
   ReportChange(change_id, enabled ? ChangeState::kEnabled : ChangeState::kDisabled);
@@ -39,6 +46,7 @@
 }
 
 void CompatFramework::ReportChange(uint64_t change_id, ChangeState state) {
+  MutexLock mu(Thread::Current(), reported_compat_changes_lock_);
   bool already_reported = reported_compat_changes_.count(change_id) != 0;
   if (already_reported) {
     return;
diff --git a/runtime/compat_framework.h b/runtime/compat_framework.h
index bc628d2..99a9215 100644
--- a/runtime/compat_framework.h
+++ b/runtime/compat_framework.h
@@ -19,6 +19,8 @@
 
 #include <set>
 
+#include "base/macros.h"
+#include "base/mutex.h"
 #include "base/string_view_cpp20.h"
 
 namespace art {
@@ -37,6 +39,9 @@
     kLogged
   };
 
+  CompatFramework();
+  ~CompatFramework();
+
   void SetDisabledCompatChanges(const std::set<uint64_t>& disabled_changes) {
     disabled_compat_changes_ = disabled_changes;
   }
@@ -64,8 +69,9 @@
   // A set of disabled compat changes for the running app, all other changes are enabled.
   std::set<uint64_t> disabled_compat_changes_;
 
-  // A set of repoted compat changes for the running app.
-  std::set<uint64_t> reported_compat_changes_;
+  // A set of reported compat changes for the running app.
+  std::set<uint64_t> reported_compat_changes_ GUARDED_BY(reported_compat_changes_lock_);
+  Mutex reported_compat_changes_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
 };
 
 }  // namespace art