Add JVMTI DDMS extension method and event.

Add a new jvmti extension method
'com.android.art.internal.ddm.process_chunk' that can be used to
request that the system process a DDMS chunk with a given type and
data payload. It returns the processed chunk type and data. Agents can
use this to interact with DDMS.

Also add a new jvmti extension event
'com.android.art.internal.ddm.publish_chunk' that will be called
whenever the system wishes to send an unrequested chunk of data to be
processed. This is triggered by code executing 'DdmServer#sendChunk'
or by other internal mechanisms.

Both of these extensions are provided mainly to aid in the maintenence
of backwards compatibility with existing DDMS applications.  Generally
agents should prefer to use the normal JVMTI events and controls over
interpreting DDMS data or calling DDMS functions.

Bug: 62821960
Test: ./test.py --host -j50
Test: ./art/tools/run-jdwp-tests.sh --mode=host \
            --test org.apache.harmony.jpda.tests.jdwp.DDM.DDMTest
Change-Id: I39f22d3d096d12b59713ec7b8b0c08d0d68ff422
diff --git a/openjdkjvmti/events.h b/openjdkjvmti/events.h
index aed24e5..a99ed7b 100644
--- a/openjdkjvmti/events.h
+++ b/openjdkjvmti/events.h
@@ -28,13 +28,14 @@
 
 struct ArtJvmTiEnv;
 class JvmtiAllocationListener;
+class JvmtiDdmChunkListener;
 class JvmtiGcPauseListener;
 class JvmtiMethodTraceListener;
 class JvmtiMonitorListener;
 
 // an enum for ArtEvents. This differs from the JVMTI events only in that we distinguish between
 // retransformation capable and incapable loading
-enum class ArtJvmtiEvent {
+enum class ArtJvmtiEvent : jint {
     kMinEventTypeVal = JVMTI_MIN_EVENT_TYPE_VAL,
     kVmInit = JVMTI_EVENT_VM_INIT,
     kVmDeath = JVMTI_EVENT_VM_DEATH,
@@ -68,9 +69,33 @@
     kObjectFree = JVMTI_EVENT_OBJECT_FREE,
     kVmObjectAlloc = JVMTI_EVENT_VM_OBJECT_ALLOC,
     kClassFileLoadHookRetransformable = JVMTI_MAX_EVENT_TYPE_VAL + 1,
-    kMaxEventTypeVal = kClassFileLoadHookRetransformable,
+    kDdmPublishChunk = JVMTI_MAX_EVENT_TYPE_VAL + 2,
+    kMaxEventTypeVal = kDdmPublishChunk,
 };
 
+using ArtJvmtiEventDdmPublishChunk = void (*)(jvmtiEnv *jvmti_env,
+                                              JNIEnv* jni_env,
+                                              jint data_type,
+                                              jint data_len,
+                                              const jbyte* data);
+
+struct ArtJvmtiEventCallbacks : jvmtiEventCallbacks {
+  ArtJvmtiEventCallbacks() : DdmPublishChunk(nullptr) {
+    memset(this, 0, sizeof(jvmtiEventCallbacks));
+  }
+
+  // Copies extension functions from other callback struct if it exists. There must not have been
+  // any modifications to this struct when it is called.
+  void CopyExtensionsFrom(const ArtJvmtiEventCallbacks* cb);
+
+  jvmtiError Set(jint index, jvmtiExtensionEvent cb);
+
+  ArtJvmtiEventDdmPublishChunk DdmPublishChunk;
+};
+
+bool IsExtensionEvent(jint e);
+bool IsExtensionEvent(ArtJvmtiEvent e);
+
 // Convert a jvmtiEvent into a ArtJvmtiEvent
 ALWAYS_INLINE static inline ArtJvmtiEvent GetArtJvmtiEvent(ArtJvmTiEnv* env, jvmtiEvent e);
 
@@ -245,6 +270,7 @@
   EventMask global_mask;
 
   std::unique_ptr<JvmtiAllocationListener> alloc_listener_;
+  std::unique_ptr<JvmtiDdmChunkListener> ddm_listener_;
   std::unique_ptr<JvmtiGcPauseListener> gc_pause_listener_;
   std::unique_ptr<JvmtiMethodTraceListener> method_trace_listener_;
   std::unique_ptr<JvmtiMonitorListener> monitor_listener_;