Log an event on hidden API accesses.

The new event consists of:
- The type of access (reflection, JNI, etc.)
- The action taken (warn or deny)
- The type of member accessed (field or method)
- Name of the class which defined the member accessed
- The name of the member
- The type signature of the member (type of field, or method signature)

The fully qualified member name is also not included to avoid the overhead
of building the string. It can be build from the information included.

Similarly, the package name, version, etc. are not included as they can
be inferred from the context when analyzing the event log.

The event is sampled, according to a sampling rate that can be set by a
configuration option, to reduce log spam.

Test: $ m
Test: $ adb shell settings put global hidden_api_access_log_sampling_rate 65536
Test: $ adb lolcat -b events | grep art_hidden_api_access

Sample output:
16796 16796 I art_hidden_api_access: [1,0,Ldalvik/system/VMRuntime;,getRuntime,()Ldalvik/system/VMRuntime;]
16796 16796 I art_hidden_api_access: [1,2,Ldalvik/system/VMRuntime;,setHiddenApiExemptions,([Ljava/lang/String;)V]
16796 16796 I art_hidden_api_access: [1,3,Landroid/app/Activity;,mDoReportFullyDrawn,Z]
(Timestamps have been elided)

Bug: 64382372
Bug: 77517571
Merged-In: I012b2c9fbffbd00ed3219918e7a736a4f7435ec8
Change-Id: I012b2c9fbffbd00ed3219918e7a736a4f7435ec8
(cherry picked from commit 73ddda4403c8088a730b8d456de46bb8e0307ed8)
diff --git a/runtime/hidden_api.h b/runtime/hidden_api.h
index d2c71a7..4325496 100644
--- a/runtime/hidden_api.h
+++ b/runtime/hidden_api.h
@@ -52,11 +52,22 @@
   kDeny
 };
 
+// Do not change the values of items in this enum, as they are written to the
+// event log for offline analysis. Any changes will interfere with that analysis.
 enum AccessMethod {
-  kNone,  // internal test that does not correspond to an actual access by app
-  kReflection,
-  kJNI,
-  kLinking,
+  kNone = 0,  // internal test that does not correspond to an actual access by app
+  kReflection = 1,
+  kJNI = 2,
+  kLinking = 3,
+};
+
+// Do not change the values of items in this enum, as they are written to the
+// event log for offline analysis. Any changes will interfere with that analysis.
+enum AccessContextFlags {
+  // Accessed member is a field if this bit is set, else a method
+  kMemberIsField = 1 << 0,
+  // Indicates if access was denied to the member, instead of just printing a warning.
+  kAccessDenied  = 1 << 1,
 };
 
 inline Action GetActionFromAccessFlags(uint32_t access_flags) {
@@ -93,9 +104,18 @@
 // is used as a helper when matching prefixes, and when logging the signature.
 class MemberSignature {
  private:
-  std::string member_type_;
-  std::vector<std::string> signature_parts_;
+  enum MemberType {
+    kField,
+    kMethod,
+  };
+
+  std::string class_name_;
+  std::string member_name_;
+  std::string type_signature_;
   std::string tmp_;
+  MemberType type_;
+
+  inline std::vector<const char*> GetSignatureParts() const;
 
  public:
   explicit MemberSignature(ArtField* field) REQUIRES_SHARED(Locks::mutator_lock_);
@@ -111,6 +131,8 @@
   bool IsExempted(const std::vector<std::string>& exemptions);
 
   void WarnAboutAccess(AccessMethod access_method, HiddenApiAccessFlags::ApiList list);
+
+  void LogAccessToEventLog(AccessMethod access_method, Action action_taken);
 };
 
 template<typename T>