Add compatibility matrices to VintfObject.report()

Test: FrameworksCoreTests
Bug: 36814503
Change-Id: I27eaea136437afb2102581d410b657e810612a0a
diff --git a/core/java/android/os/VintfObject.java b/core/java/android/os/VintfObject.java
index 1ef3916..8302ece 100644
--- a/core/java/android/os/VintfObject.java
+++ b/core/java/android/os/VintfObject.java
@@ -26,17 +26,12 @@
     private static final String LOG_TAG = "VintfObject";
 
     /**
-     * Slurps all device information (both manifests)
-     * and report it.
+     * Slurps all device information (both manifests and both matrices)
+     * and report them.
      * If any error in getting one of the manifests, it is not included in
      * the list.
      */
-    public static String[] report() {
-        ArrayList<String> ret = new ArrayList<>();
-        put(ret, getDeviceManifest(), "device manifest");
-        put(ret, getFrameworkManifest(), "framework manifest");
-        return ret.toArray(new String[0]);
-    }
+    public static native String[] report();
 
     /**
      * Verify that the given metadata for an OTA package is compatible with
@@ -50,15 +45,4 @@
      */
     public static native int verify(String[] packageInfo);
 
-    // return null if any error, otherwise XML string.
-    private static native String getDeviceManifest();
-    private static native String getFrameworkManifest();
-
-    private static void put(ArrayList<String> list, String content, String message) {
-        if (content == null || content.length() == 0) {
-            Log.e(LOG_TAG, "Cannot get;" + message + "; check native logs for details.");
-            return;
-        }
-        list.add(content);
-    }
 }
diff --git a/core/jni/android_os_VintfObject.cpp b/core/jni/android_os_VintfObject.cpp
index 9491a1e..033f2df 100644
--- a/core/jni/android_os_VintfObject.cpp
+++ b/core/jni/android_os_VintfObject.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,6 +16,10 @@
 
 #define LOG_TAG "VintfObject"
 //#define LOG_NDEBUG 0
+#include <android-base/logging.h>
+
+#include <vector>
+#include <string>
 
 #include <JNIHelp.h>
 #include <vintf/VintfObject.h>
@@ -23,31 +27,48 @@
 
 #include "core_jni_helpers.h"
 
+static jclass gString;
+
 namespace android {
 
-using vintf::HalManifest;
-using vintf::RuntimeInfo;
 using vintf::VintfObject;
 using vintf::gHalManifestConverter;
+using vintf::gCompatibilityMatrixConverter;
+using vintf::XmlConverter;
 
-static jstring android_os_VintfObject_getDeviceManifest(JNIEnv* env, jclass clazz)
-{
-    const HalManifest *manifest = VintfObject::GetDeviceHalManifest();
-    if (manifest == nullptr) {
-        return nullptr;
+static inline jobjectArray toJavaStringArray(JNIEnv* env, const std::vector<std::string>& v) {
+    jobjectArray ret = env->NewObjectArray(v.size(), gString, NULL /* init element */);
+    for (size_t i = 0; i < v.size(); ++i) {
+        env->SetObjectArrayElement(ret, i, env->NewStringUTF(v[i].c_str()));
     }
-    std::string xml = gHalManifestConverter(*manifest);
-    return env->NewStringUTF(xml.c_str());
+    return ret;
 }
 
-static jstring android_os_VintfObject_getFrameworkManifest(JNIEnv* env, jclass clazz)
-{
-    const HalManifest *manifest = VintfObject::GetFrameworkHalManifest();
-    if (manifest == nullptr) {
-        return nullptr;
+template<typename T>
+static void tryAddSchema(const T* object, const XmlConverter<T>& converter,
+        const std::string& description,
+        std::vector<std::string>* cStrings) {
+    if (object == nullptr) {
+        LOG(WARNING) << __FUNCTION__ << "Cannot get " << description;
+    } else {
+        cStrings->push_back(converter(*object));
     }
-    std::string xml = gHalManifestConverter(*manifest);
-    return env->NewStringUTF(xml.c_str());
+}
+
+static jobjectArray android_os_VintfObject_report(JNIEnv* env, jclass clazz)
+{
+    std::vector<std::string> cStrings;
+
+    tryAddSchema(VintfObject::GetDeviceHalManifest(), gHalManifestConverter,
+            "device manifest", &cStrings);
+    tryAddSchema(VintfObject::GetFrameworkHalManifest(), gHalManifestConverter,
+            "framework manifest", &cStrings);
+    tryAddSchema(VintfObject::GetDeviceCompatibilityMatrix(), gCompatibilityMatrixConverter,
+            "device compatibility matrix", &cStrings);
+    tryAddSchema(VintfObject::GetFrameworkCompatibilityMatrix(), gCompatibilityMatrixConverter,
+            "framework compatibility matrix", &cStrings);
+
+    return toJavaStringArray(env, cStrings);
 }
 
 static jint android_os_VintfObject_verify(JNIEnv *env, jclass clazz, jobjectArray packageInfo) {
@@ -66,15 +87,18 @@
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod gVintfObjectMethods[] = {
-    {"getDeviceManifest",    "()Ljava/lang/String;",   (void*)android_os_VintfObject_getDeviceManifest},
-    {"getFrameworkManifest", "()Ljava/lang/String;",   (void*)android_os_VintfObject_getFrameworkManifest},
-    {"verify",               "([Ljava/lang/String;)I", (void*)android_os_VintfObject_verify},
+    {"report", "()[Ljava/lang/String;", (void*)android_os_VintfObject_report},
+    {"verify", "([Ljava/lang/String;)I", (void*)android_os_VintfObject_verify},
 };
 
+
 const char* const kVintfObjectPathName = "android/os/VintfObject";
 
 int register_android_os_VintfObject(JNIEnv* env)
 {
+
+    gString = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/String"));
+
     return RegisterMethodsOrDie(env, kVintfObjectPathName, gVintfObjectMethods,
             NELEM(gVintfObjectMethods));
 }
diff --git a/core/tests/coretests/src/android/os/VintfObjectTest.java b/core/tests/coretests/src/android/os/VintfObjectTest.java
index aaaf55c..821ee80 100644
--- a/core/tests/coretests/src/android/os/VintfObjectTest.java
+++ b/core/tests/coretests/src/android/os/VintfObjectTest.java
@@ -26,5 +26,8 @@
         // From /system/manifest.xml
         assertTrue(String.join("", xmls).contains(
                 "<manifest version=\"1.0\" type=\"framework\">"));
+        // From /system/compatibility-matrix.xml
+        assertTrue(String.join("", xmls).contains(
+                "<compatibility-matrix version=\"1.0\" type=\"framework\">"));
     }
 }