Loading core/java/android/os/VintfObject.java +30 −21 Original line number Diff line number Diff line Loading @@ -16,27 +16,25 @@ package android.os; import java.util.ArrayList; import java.util.Map; import android.util.Log; /** @hide */ /** * Java API for libvintf. * @hide */ public class VintfObject { private static final String LOG_TAG = "VintfObject"; /// ---------- OTA /** * 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 Loading @@ -50,15 +48,26 @@ public class VintfObject { */ 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(); /// ---------- CTS Device Info 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); } /** * @return a list of HAL names and versions that is supported by this * device as stated in device and framework manifests. For example, * ["android.hidl.manager@1.0", "android.hardware.camera.device@1.0", * "android.hardware.camera.device@3.2"]. There are no duplicates. */ public static native String[] getHalNamesAndVersions(); /** * @return the BOARD_SEPOLICY_VERS build flag available in device manifest. */ public static native String getSepolicyVersion(); /** * @return a list of VNDK snapshots supported by the framework, as * specified in framework manifest. For example, * [("25.0.5", ["libjpeg.so", "libbase.so"]), * ("25.1.3", ["libjpeg.so", "libbase.so"])] */ public static native Map<String, String[]> getVndkSnapshots(); } core/jni/android_os_VintfObject.cpp +105 −19 Original line number Diff line number Diff line /* * 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. Loading @@ -16,41 +16,84 @@ #define LOG_TAG "VintfObject" //#define LOG_NDEBUG 0 #include <android-base/logging.h> #include <vector> #include <string> #include <JNIHelp.h> #include <vintf/VintfObject.h> #include <vintf/parse_string.h> #include <vintf/parse_xml.h> #include "core_jni_helpers.h" static jclass gString; static jclass gHashMapClazz; static jmethodID gHashMapInit; static jmethodID gHashMapPut; namespace android { using vintf::HalManifest; using vintf::RuntimeInfo; using vintf::SchemaType; using vintf::VintfObject; using vintf::XmlConverter; using vintf::Vndk; using vintf::gHalManifestConverter; using vintf::gCompatibilityMatrixConverter; using vintf::to_string; static jstring android_os_VintfObject_getDeviceManifest(JNIEnv* env, jclass clazz) { const HalManifest *manifest = VintfObject::GetDeviceHalManifest(); if (manifest == nullptr) { return nullptr; template<typename V> static inline jobjectArray toJavaStringArray(JNIEnv* env, const V& v) { size_t i; typename V::const_iterator it; jobjectArray ret = env->NewObjectArray(v.size(), gString, NULL /* init element */); for (i = 0, it = v.begin(); it != v.end(); ++i, ++it) { env->SetObjectArrayElement(ret, i, env->NewStringUTF(it->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(); 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)); } } static void tryAddHalNamesAndVersions(const HalManifest *manifest, const std::string& description, std::set<std::string> *output) { if (manifest == nullptr) { return nullptr; LOG(WARNING) << __FUNCTION__ << "Cannot get " << description; } else { auto names = manifest->getHalNamesAndVersions(); output->insert(names.begin(), names.end()); } std::string xml = gHalManifestConverter(*manifest); return env->NewStringUTF(xml.c_str()); } static jint android_os_VintfObject_verify(JNIEnv *env, jclass clazz, jobjectArray packageInfo) { static jobjectArray android_os_VintfObject_report(JNIEnv* env, jclass) { 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, jobjectArray packageInfo) { size_t count = env->GetArrayLength(packageInfo); std::vector<std::string> cPackageInfo{count}; for (size_t i = 0; i < count; ++i) { Loading @@ -63,18 +106,61 @@ static jint android_os_VintfObject_verify(JNIEnv *env, jclass clazz, jobjectArra return status; } static jobjectArray android_os_VintfObject_getHalNamesAndVersions(JNIEnv* env, jclass) { std::set<std::string> halNames; tryAddHalNamesAndVersions(VintfObject::GetDeviceHalManifest(), "device manifest", &halNames); tryAddHalNamesAndVersions(VintfObject::GetFrameworkHalManifest(), "framework manifest", &halNames); return toJavaStringArray(env, halNames); } static jstring android_os_VintfObject_getSepolicyVersion(JNIEnv* env, jclass) { const HalManifest *manifest = VintfObject::GetDeviceHalManifest(); if (manifest == nullptr || manifest->type() != SchemaType::DEVICE) { LOG(WARNING) << __FUNCTION__ << "Cannot get device manifest"; return nullptr; } std::string cString = to_string(manifest->sepolicyVersion()); return env->NewStringUTF(cString.c_str()); } static jobject android_os_VintfObject_getVndkSnapshots(JNIEnv* env, jclass) { const HalManifest *manifest = VintfObject::GetFrameworkHalManifest(); if (manifest == nullptr || manifest->type() != SchemaType::FRAMEWORK) { LOG(WARNING) << __FUNCTION__ << "Cannot get framework manifest"; return nullptr; } jobject jMap = env->NewObject(gHashMapClazz, gHashMapInit); for (const Vndk &vndk : manifest->vndks()) { std::string key = to_string(vndk.versionRange()); env->CallObjectMethod(jMap, gHashMapPut, env->NewStringUTF(key.c_str()), toJavaStringArray(env, vndk.libraries())); } return jMap; } // ---------------------------------------------------------------------------- static const JNINativeMethod gVintfObjectMethods[] = { {"getDeviceManifest", "()Ljava/lang/String;", (void*)android_os_VintfObject_getDeviceManifest}, {"getFrameworkManifest", "()Ljava/lang/String;", (void*)android_os_VintfObject_getFrameworkManifest}, {"report", "()[Ljava/lang/String;", (void*)android_os_VintfObject_report}, {"verify", "([Ljava/lang/String;)I", (void*)android_os_VintfObject_verify}, {"getHalNamesAndVersions", "()[Ljava/lang/String;", (void*)android_os_VintfObject_getHalNamesAndVersions}, {"getSepolicyVersion", "()Ljava/lang/String;", (void*)android_os_VintfObject_getSepolicyVersion}, {"getVndkSnapshots", "()Ljava/util/Map;", (void*)android_os_VintfObject_getVndkSnapshots}, }; const char* const kVintfObjectPathName = "android/os/VintfObject"; int register_android_os_VintfObject(JNIEnv* env) { gString = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/String")); gHashMapClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/util/HashMap")); gHashMapInit = GetMethodIDOrDie(env, gHashMapClazz, "<init>", "()V"); gHashMapPut = GetMethodIDOrDie(env, gHashMapClazz, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); return RegisterMethodsOrDie(env, kVintfObjectPathName, gVintfObjectMethods, NELEM(gVintfObjectMethods)); } Loading core/tests/coretests/src/android/os/VintfObjectTest.java +3 −0 Original line number Diff line number Diff line Loading @@ -26,5 +26,8 @@ public class VintfObjectTest extends TestCase { // 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\">")); } } Loading
core/java/android/os/VintfObject.java +30 −21 Original line number Diff line number Diff line Loading @@ -16,27 +16,25 @@ package android.os; import java.util.ArrayList; import java.util.Map; import android.util.Log; /** @hide */ /** * Java API for libvintf. * @hide */ public class VintfObject { private static final String LOG_TAG = "VintfObject"; /// ---------- OTA /** * 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 Loading @@ -50,15 +48,26 @@ public class VintfObject { */ 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(); /// ---------- CTS Device Info 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); } /** * @return a list of HAL names and versions that is supported by this * device as stated in device and framework manifests. For example, * ["android.hidl.manager@1.0", "android.hardware.camera.device@1.0", * "android.hardware.camera.device@3.2"]. There are no duplicates. */ public static native String[] getHalNamesAndVersions(); /** * @return the BOARD_SEPOLICY_VERS build flag available in device manifest. */ public static native String getSepolicyVersion(); /** * @return a list of VNDK snapshots supported by the framework, as * specified in framework manifest. For example, * [("25.0.5", ["libjpeg.so", "libbase.so"]), * ("25.1.3", ["libjpeg.so", "libbase.so"])] */ public static native Map<String, String[]> getVndkSnapshots(); }
core/jni/android_os_VintfObject.cpp +105 −19 Original line number Diff line number Diff line /* * 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. Loading @@ -16,41 +16,84 @@ #define LOG_TAG "VintfObject" //#define LOG_NDEBUG 0 #include <android-base/logging.h> #include <vector> #include <string> #include <JNIHelp.h> #include <vintf/VintfObject.h> #include <vintf/parse_string.h> #include <vintf/parse_xml.h> #include "core_jni_helpers.h" static jclass gString; static jclass gHashMapClazz; static jmethodID gHashMapInit; static jmethodID gHashMapPut; namespace android { using vintf::HalManifest; using vintf::RuntimeInfo; using vintf::SchemaType; using vintf::VintfObject; using vintf::XmlConverter; using vintf::Vndk; using vintf::gHalManifestConverter; using vintf::gCompatibilityMatrixConverter; using vintf::to_string; static jstring android_os_VintfObject_getDeviceManifest(JNIEnv* env, jclass clazz) { const HalManifest *manifest = VintfObject::GetDeviceHalManifest(); if (manifest == nullptr) { return nullptr; template<typename V> static inline jobjectArray toJavaStringArray(JNIEnv* env, const V& v) { size_t i; typename V::const_iterator it; jobjectArray ret = env->NewObjectArray(v.size(), gString, NULL /* init element */); for (i = 0, it = v.begin(); it != v.end(); ++i, ++it) { env->SetObjectArrayElement(ret, i, env->NewStringUTF(it->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(); 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)); } } static void tryAddHalNamesAndVersions(const HalManifest *manifest, const std::string& description, std::set<std::string> *output) { if (manifest == nullptr) { return nullptr; LOG(WARNING) << __FUNCTION__ << "Cannot get " << description; } else { auto names = manifest->getHalNamesAndVersions(); output->insert(names.begin(), names.end()); } std::string xml = gHalManifestConverter(*manifest); return env->NewStringUTF(xml.c_str()); } static jint android_os_VintfObject_verify(JNIEnv *env, jclass clazz, jobjectArray packageInfo) { static jobjectArray android_os_VintfObject_report(JNIEnv* env, jclass) { 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, jobjectArray packageInfo) { size_t count = env->GetArrayLength(packageInfo); std::vector<std::string> cPackageInfo{count}; for (size_t i = 0; i < count; ++i) { Loading @@ -63,18 +106,61 @@ static jint android_os_VintfObject_verify(JNIEnv *env, jclass clazz, jobjectArra return status; } static jobjectArray android_os_VintfObject_getHalNamesAndVersions(JNIEnv* env, jclass) { std::set<std::string> halNames; tryAddHalNamesAndVersions(VintfObject::GetDeviceHalManifest(), "device manifest", &halNames); tryAddHalNamesAndVersions(VintfObject::GetFrameworkHalManifest(), "framework manifest", &halNames); return toJavaStringArray(env, halNames); } static jstring android_os_VintfObject_getSepolicyVersion(JNIEnv* env, jclass) { const HalManifest *manifest = VintfObject::GetDeviceHalManifest(); if (manifest == nullptr || manifest->type() != SchemaType::DEVICE) { LOG(WARNING) << __FUNCTION__ << "Cannot get device manifest"; return nullptr; } std::string cString = to_string(manifest->sepolicyVersion()); return env->NewStringUTF(cString.c_str()); } static jobject android_os_VintfObject_getVndkSnapshots(JNIEnv* env, jclass) { const HalManifest *manifest = VintfObject::GetFrameworkHalManifest(); if (manifest == nullptr || manifest->type() != SchemaType::FRAMEWORK) { LOG(WARNING) << __FUNCTION__ << "Cannot get framework manifest"; return nullptr; } jobject jMap = env->NewObject(gHashMapClazz, gHashMapInit); for (const Vndk &vndk : manifest->vndks()) { std::string key = to_string(vndk.versionRange()); env->CallObjectMethod(jMap, gHashMapPut, env->NewStringUTF(key.c_str()), toJavaStringArray(env, vndk.libraries())); } return jMap; } // ---------------------------------------------------------------------------- static const JNINativeMethod gVintfObjectMethods[] = { {"getDeviceManifest", "()Ljava/lang/String;", (void*)android_os_VintfObject_getDeviceManifest}, {"getFrameworkManifest", "()Ljava/lang/String;", (void*)android_os_VintfObject_getFrameworkManifest}, {"report", "()[Ljava/lang/String;", (void*)android_os_VintfObject_report}, {"verify", "([Ljava/lang/String;)I", (void*)android_os_VintfObject_verify}, {"getHalNamesAndVersions", "()[Ljava/lang/String;", (void*)android_os_VintfObject_getHalNamesAndVersions}, {"getSepolicyVersion", "()Ljava/lang/String;", (void*)android_os_VintfObject_getSepolicyVersion}, {"getVndkSnapshots", "()Ljava/util/Map;", (void*)android_os_VintfObject_getVndkSnapshots}, }; const char* const kVintfObjectPathName = "android/os/VintfObject"; int register_android_os_VintfObject(JNIEnv* env) { gString = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/String")); gHashMapClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/util/HashMap")); gHashMapInit = GetMethodIDOrDie(env, gHashMapClazz, "<init>", "()V"); gHashMapPut = GetMethodIDOrDie(env, gHashMapClazz, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); return RegisterMethodsOrDie(env, kVintfObjectPathName, gVintfObjectMethods, NELEM(gVintfObjectMethods)); } Loading
core/tests/coretests/src/android/os/VintfObjectTest.java +3 −0 Original line number Diff line number Diff line Loading @@ -26,5 +26,8 @@ public class VintfObjectTest extends TestCase { // 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\">")); } }