1becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong/* 275ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong * Copyright (C) 2017 The Android Open Source Project 3becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong * 4becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong * Licensed under the Apache License, Version 2.0 (the "License"); 5becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong * you may not use this file except in compliance with the License. 6becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong * You may obtain a copy of the License at 7becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong * 8becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong * http://www.apache.org/licenses/LICENSE-2.0 9becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong * 10becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong * Unless required by applicable law or agreed to in writing, software 11becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong * distributed under the License is distributed on an "AS IS" BASIS, 12becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong * See the License for the specific language governing permissions and 14becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong * limitations under the License. 15becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong */ 16becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong 17becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong#define LOG_TAG "VintfObject" 18becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong//#define LOG_NDEBUG 0 1975ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong#include <android-base/logging.h> 2075ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong 2175ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong#include <vector> 2275ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong#include <string> 23becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong 24becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong#include <JNIHelp.h> 25becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong#include <vintf/VintfObject.h> 26687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong#include <vintf/parse_string.h> 27becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong#include <vintf/parse_xml.h> 28becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong 29becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong#include "core_jni_helpers.h" 30becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong 3175ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hongstatic jclass gString; 32687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hongstatic jclass gHashMapClazz; 33687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hongstatic jmethodID gHashMapInit; 34687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hongstatic jmethodID gHashMapPut; 3575ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong 36becc56d7ea523aa153219446232cbf5e561726f4Yifan Hongnamespace android { 37becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong 38687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hongusing vintf::HalManifest; 39687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hongusing vintf::SchemaType; 40becc56d7ea523aa153219446232cbf5e561726f4Yifan Hongusing vintf::VintfObject; 41687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hongusing vintf::XmlConverter; 42687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hongusing vintf::Vndk; 43becc56d7ea523aa153219446232cbf5e561726f4Yifan Hongusing vintf::gHalManifestConverter; 4475ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hongusing vintf::gCompatibilityMatrixConverter; 45687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hongusing vintf::to_string; 46becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong 47687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hongtemplate<typename V> 48687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hongstatic inline jobjectArray toJavaStringArray(JNIEnv* env, const V& v) { 49687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong size_t i; 50687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong typename V::const_iterator it; 5175ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong jobjectArray ret = env->NewObjectArray(v.size(), gString, NULL /* init element */); 52687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong for (i = 0, it = v.begin(); it != v.end(); ++i, ++it) { 53687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong env->SetObjectArrayElement(ret, i, env->NewStringUTF(it->c_str())); 54becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong } 5575ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong return ret; 56becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong} 57becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong 5875ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hongtemplate<typename T> 5975ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hongstatic void tryAddSchema(const T* object, const XmlConverter<T>& converter, 6075ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong const std::string& description, 6175ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong std::vector<std::string>* cStrings) { 6275ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong if (object == nullptr) { 6375ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong LOG(WARNING) << __FUNCTION__ << "Cannot get " << description; 6475ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong } else { 6575ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong cStrings->push_back(converter(*object)); 66becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong } 6775ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong} 6875ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong 69687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hongstatic void tryAddHalNamesAndVersions(const HalManifest *manifest, 70687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong const std::string& description, 71687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong std::set<std::string> *output) { 72687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong if (manifest == nullptr) { 73687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong LOG(WARNING) << __FUNCTION__ << "Cannot get " << description; 74687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong } else { 75687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong auto names = manifest->getHalNamesAndVersions(); 76687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong output->insert(names.begin(), names.end()); 77687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong } 78687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong} 79687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong 80687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hongstatic jobjectArray android_os_VintfObject_report(JNIEnv* env, jclass) 8175ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong{ 8275ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong std::vector<std::string> cStrings; 8375ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong 8475ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong tryAddSchema(VintfObject::GetDeviceHalManifest(), gHalManifestConverter, 8575ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong "device manifest", &cStrings); 8675ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong tryAddSchema(VintfObject::GetFrameworkHalManifest(), gHalManifestConverter, 8775ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong "framework manifest", &cStrings); 8875ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong tryAddSchema(VintfObject::GetDeviceCompatibilityMatrix(), gCompatibilityMatrixConverter, 8975ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong "device compatibility matrix", &cStrings); 9075ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong tryAddSchema(VintfObject::GetFrameworkCompatibilityMatrix(), gCompatibilityMatrixConverter, 9175ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong "framework compatibility matrix", &cStrings); 9275ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong 9375ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong return toJavaStringArray(env, cStrings); 94becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong} 95becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong 96687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hongstatic jint android_os_VintfObject_verify(JNIEnv* env, jclass, jobjectArray packageInfo) { 97becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong size_t count = env->GetArrayLength(packageInfo); 98becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong std::vector<std::string> cPackageInfo{count}; 99becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong for (size_t i = 0; i < count; ++i) { 100becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong jstring element = (jstring)env->GetObjectArrayElement(packageInfo, i); 101becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong const char *cString = env->GetStringUTFChars(element, NULL /* isCopy */); 102becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong cPackageInfo[i] = cString; 103becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong env->ReleaseStringUTFChars(element, cString); 104becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong } 105585ffd1cb3497eda590e4da48a8bec5726af1d3aYifan Hong int32_t status = VintfObject::CheckCompatibility(cPackageInfo); 106becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong return status; 107becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong} 108becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong 109687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hongstatic jobjectArray android_os_VintfObject_getHalNamesAndVersions(JNIEnv* env, jclass) { 110687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong std::set<std::string> halNames; 111687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong tryAddHalNamesAndVersions(VintfObject::GetDeviceHalManifest(), 112687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong "device manifest", &halNames); 113687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong tryAddHalNamesAndVersions(VintfObject::GetFrameworkHalManifest(), 114687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong "framework manifest", &halNames); 115687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong return toJavaStringArray(env, halNames); 116687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong} 117687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong 118687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hongstatic jstring android_os_VintfObject_getSepolicyVersion(JNIEnv* env, jclass) { 119687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong const HalManifest *manifest = VintfObject::GetDeviceHalManifest(); 120687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong if (manifest == nullptr || manifest->type() != SchemaType::DEVICE) { 121687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong LOG(WARNING) << __FUNCTION__ << "Cannot get device manifest"; 122687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong return nullptr; 123687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong } 124687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong std::string cString = to_string(manifest->sepolicyVersion()); 125687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong return env->NewStringUTF(cString.c_str()); 126687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong} 127687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong 128687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hongstatic jobject android_os_VintfObject_getVndkSnapshots(JNIEnv* env, jclass) { 129687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong const HalManifest *manifest = VintfObject::GetFrameworkHalManifest(); 130687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong if (manifest == nullptr || manifest->type() != SchemaType::FRAMEWORK) { 131687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong LOG(WARNING) << __FUNCTION__ << "Cannot get framework manifest"; 132687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong return nullptr; 133687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong } 134687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong jobject jMap = env->NewObject(gHashMapClazz, gHashMapInit); 135687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong for (const Vndk &vndk : manifest->vndks()) { 136687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong std::string key = to_string(vndk.versionRange()); 137687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong env->CallObjectMethod(jMap, gHashMapPut, 138687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong env->NewStringUTF(key.c_str()), toJavaStringArray(env, vndk.libraries())); 139687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong } 140687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong return jMap; 141687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong} 142687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong 143becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong// ---------------------------------------------------------------------------- 144becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong 145becc56d7ea523aa153219446232cbf5e561726f4Yifan Hongstatic const JNINativeMethod gVintfObjectMethods[] = { 14675ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong {"report", "()[Ljava/lang/String;", (void*)android_os_VintfObject_report}, 14775ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong {"verify", "([Ljava/lang/String;)I", (void*)android_os_VintfObject_verify}, 148687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong {"getHalNamesAndVersions", "()[Ljava/lang/String;", (void*)android_os_VintfObject_getHalNamesAndVersions}, 149687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong {"getSepolicyVersion", "()Ljava/lang/String;", (void*)android_os_VintfObject_getSepolicyVersion}, 150687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong {"getVndkSnapshots", "()Ljava/util/Map;", (void*)android_os_VintfObject_getVndkSnapshots}, 151becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong}; 152becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong 153becc56d7ea523aa153219446232cbf5e561726f4Yifan Hongconst char* const kVintfObjectPathName = "android/os/VintfObject"; 154becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong 155becc56d7ea523aa153219446232cbf5e561726f4Yifan Hongint register_android_os_VintfObject(JNIEnv* env) 156becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong{ 15775ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong 15875ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong gString = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/String")); 159687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong gHashMapClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/util/HashMap")); 160687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong gHashMapInit = GetMethodIDOrDie(env, gHashMapClazz, "<init>", "()V"); 161687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong gHashMapPut = GetMethodIDOrDie(env, gHashMapClazz, 162687113a082c7ffd8e9a29301e24c8935322d0d2dYifan Hong "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); 16375ffd667a97f3b8adc83b2c214472b31c8f85249Yifan Hong 164becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong return RegisterMethodsOrDie(env, kVintfObjectPathName, gVintfObjectMethods, 165becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong NELEM(gVintfObjectMethods)); 166becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong} 167becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong 168becc56d7ea523aa153219446232cbf5e561726f4Yifan Hong}; 169