Limit hidden api logcat logging.

Several signature tests are randomly failing due to adb timing out.
Because these tests try accessing all nonsdk APIs, they generate a lot
of output to logcat.
This change reduces the number of logged APIs to a maximum of 100. For
most use cases, this should be sufficient - and will reduce the amount
of spam in the signature tests, hopefully addressing them randomly
failing.

Test: atest CtsHiddenApiBlocklistDebugClassTestCases
Bug: 176156645
Change-Id: I0218c9fca651653d3d9a1036296f4cc3186427c6
diff --git a/runtime/hidden_api.cc b/runtime/hidden_api.cc
index 1ad59ff..e31a832 100644
--- a/runtime/hidden_api.cc
+++ b/runtime/hidden_api.cc
@@ -17,6 +17,7 @@
 #include "hidden_api.h"
 
 #include <nativehelper/scoped_local_ref.h>
+#include <atomic>
 
 #include "art_field-inl.h"
 #include "art_method-inl.h"
@@ -42,6 +43,8 @@
 static constexpr uint64_t kHideMaxtargetsdkQHiddenApis = 149994052;
 static constexpr uint64_t kAllowTestApiAccess = 166236554;
 
+static constexpr uint64_t kMaxLogWarnings = 100;
+
 // Set to true if we should always print a warning in logcat for all hidden API accesses, not just
 // conditionally and unconditionally blocked. This can be set to true for developer preview / beta
 // builds, but should be false for public release builds.
@@ -244,9 +247,17 @@
 void MemberSignature::WarnAboutAccess(AccessMethod access_method,
                                       hiddenapi::ApiList list,
                                       bool access_denied) {
+  static std::atomic<uint64_t> log_warning_count_ = 0;
+  if (log_warning_count_ > kMaxLogWarnings) {
+    return;
+  }
   LOG(WARNING) << "Accessing hidden " << (type_ == kField ? "field " : "method ")
                << Dumpable<MemberSignature>(*this) << " (" << list << ", " << access_method
                << (access_denied ? ", denied)" : ", allowed)");
+  if (log_warning_count_ >= kMaxLogWarnings) {
+    LOG(WARNING) << "Reached maximum number of hidden api access warnings.";
+  }
+  ++log_warning_count_;
 }
 
 bool MemberSignature::Equals(const MemberSignature& other) {