From 49a757d4882b64f47e9fa6d6c91b43435d55b9c5 Mon Sep 17 00:00:00 2001 From: Prateek Shrivastava Date: Mon, 1 Nov 2021 23:49:52 +0000 Subject: [PATCH] Revert "Remove the implementation of libaapt2_jni in build file" Revert "Remove the reference of libaapt2_jni in build file" Revert submission 16102170-remove_libaapt2_jni Reason for revert: b/204805075 breakages on git_master - BuildMonitor Reverted Changes: I2331fcac1:Remove the reference of libaapt2_jni in build file... I193ff8b5b:Remove the implementation of libaapt2_jni in build... Change-Id: I37384f995bf34df3cc2654e1439ceecc720243ac --- tools/aapt2/Android.bp | 10 ++ tools/aapt2/jni/ScopedUtfChars.h | 84 ++++++++++ tools/aapt2/jni/aapt2_jni.cpp | 143 ++++++++++++++++++ .../jni/com_android_tools_aapt2_Aapt2Jni.h | 37 +++++ 4 files changed, 274 insertions(+) create mode 100644 tools/aapt2/jni/ScopedUtfChars.h create mode 100644 tools/aapt2/jni/aapt2_jni.cpp create mode 100644 tools/aapt2/jni/com_android_tools_aapt2_Aapt2Jni.h diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp index bd0a4bc44e183..740b44e0ce28d 100644 --- a/tools/aapt2/Android.bp +++ b/tools/aapt2/Android.bp @@ -169,6 +169,16 @@ cc_library_host_static { defaults: ["aapt2_defaults"], } +// ========================================================== +// Build the host shared library: aapt2_jni +// ========================================================== +cc_library_host_shared { + name: "libaapt2_jni", + srcs: toolSources + ["jni/aapt2_jni.cpp"], + static_libs: ["libaapt2"], + defaults: ["aapt2_defaults"], +} + // ========================================================== // Build the host tests: aapt2_tests // ========================================================== diff --git a/tools/aapt2/jni/ScopedUtfChars.h b/tools/aapt2/jni/ScopedUtfChars.h new file mode 100644 index 0000000000000..a8c4b136dcf64 --- /dev/null +++ b/tools/aapt2/jni/ScopedUtfChars.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2010 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCOPED_UTF_CHARS_H_included +#define SCOPED_UTF_CHARS_H_included + +#include +#include + +#include "android-base/logging.h" + +// This file was copied with some minor modifications from libnativehelper. +// As soon as libnativehelper can be compiled for Windows, this file should be +// replaced with libnativehelper's implementation. +class ScopedUtfChars { + public: + ScopedUtfChars(JNIEnv* env, jstring s) : env_(env), string_(s) { + CHECK(s != nullptr); + utf_chars_ = env->GetStringUTFChars(s, nullptr); + } + + ScopedUtfChars(ScopedUtfChars&& rhs) : + env_(rhs.env_), string_(rhs.string_), utf_chars_(rhs.utf_chars_) { + rhs.env_ = nullptr; + rhs.string_ = nullptr; + rhs.utf_chars_ = nullptr; + } + + ~ScopedUtfChars() { + if (utf_chars_) { + env_->ReleaseStringUTFChars(string_, utf_chars_); + } + } + + ScopedUtfChars& operator=(ScopedUtfChars&& rhs) { + if (this != &rhs) { + // Delete the currently owned UTF chars. + this->~ScopedUtfChars(); + + // Move the rhs ScopedUtfChars and zero it out. + env_ = rhs.env_; + string_ = rhs.string_; + utf_chars_ = rhs.utf_chars_; + rhs.env_ = nullptr; + rhs.string_ = nullptr; + rhs.utf_chars_ = nullptr; + } + return *this; + } + + const char* c_str() const { + return utf_chars_; + } + + size_t size() const { + return strlen(utf_chars_); + } + + const char& operator[](size_t n) const { + return utf_chars_[n]; + } + + private: + JNIEnv* env_; + jstring string_; + const char* utf_chars_; + + DISALLOW_COPY_AND_ASSIGN(ScopedUtfChars); +}; + +#endif // SCOPED_UTF_CHARS_H_included diff --git a/tools/aapt2/jni/aapt2_jni.cpp b/tools/aapt2/jni/aapt2_jni.cpp new file mode 100644 index 0000000000000..ec3c5431c7a37 --- /dev/null +++ b/tools/aapt2/jni/aapt2_jni.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2015 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "com_android_tools_aapt2_Aapt2Jni.h" + +#include +#include +#include +#include + +#include "android-base/logging.h" +#include "ScopedUtfChars.h" + +#include "Diagnostics.h" +#include "cmd/Compile.h" +#include "cmd/Link.h" +#include "util/Util.h" + +using android::StringPiece; + +/* + * Converts a java List into C++ vector. + */ +static std::vector list_to_utfchars(JNIEnv *env, jobject obj) { + std::vector converted; + + // Call size() method on the list to know how many elements there are. + jclass list_cls = env->GetObjectClass(obj); + jmethodID size_method_id = env->GetMethodID(list_cls, "size", "()I"); + CHECK(size_method_id != 0); + jint size = env->CallIntMethod(obj, size_method_id); + CHECK(size >= 0); + + // Now, iterate all strings in the list + // (note: generic erasure means get() return an Object) + jmethodID get_method_id = env->GetMethodID(list_cls, "get", "(I)Ljava/lang/Object;"); + CHECK(get_method_id != 0); + for (jint i = 0; i < size; i++) { + // Call get(i) to get the string in the ith position. + jobject string_obj_uncast = env->CallObjectMethod(obj, get_method_id, i); + CHECK(string_obj_uncast != nullptr); + jstring string_obj = static_cast(string_obj_uncast); + converted.push_back(ScopedUtfChars(env, string_obj)); + } + + return converted; +} + +/* + * Extracts all StringPiece from the ScopedUtfChars instances. + * + * The returned pieces can only be used while the original ones have not been + * destroyed. + */ +static std::vector extract_pieces(const std::vector &strings) { + std::vector pieces; + + std::for_each( + strings.begin(), strings.end(), + [&pieces](const ScopedUtfChars &p) { pieces.push_back(p.c_str()); }); + + return pieces; +} + +class JniDiagnostics : public aapt::IDiagnostics { + public: + JniDiagnostics(JNIEnv* env, jobject diagnostics_obj) + : env_(env), diagnostics_obj_(diagnostics_obj) { + mid_ = NULL; + } + + void Log(Level level, aapt::DiagMessageActual& actual_msg) override { + jint level_value; + switch (level) { + case Level::Error: + level_value = 3; + break; + + case Level::Warn: + level_value = 2; + break; + + case Level::Note: + level_value = 1; + break; + } + jstring message = env_->NewStringUTF(actual_msg.message.c_str()); + jstring path = env_->NewStringUTF(actual_msg.source.path.c_str()); + jlong line = -1; + if (actual_msg.source.line) { + line = actual_msg.source.line.value(); + } + if (!mid_) { + jclass diagnostics_cls = env_->GetObjectClass(diagnostics_obj_); + mid_ = env_->GetMethodID(diagnostics_cls, "log", "(ILjava/lang/String;JLjava/lang/String;)V"); + } + env_->CallVoidMethod(diagnostics_obj_, mid_, level_value, path, line, message); + } + + private: + JNIEnv* env_; + jobject diagnostics_obj_; + jmethodID mid_; + DISALLOW_COPY_AND_ASSIGN(JniDiagnostics); +}; + +JNIEXPORT jint JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeCompile( + JNIEnv* env, jclass aapt_obj, jobject arguments_obj, jobject diagnostics_obj) { + std::vector compile_args_jni = + list_to_utfchars(env, arguments_obj); + std::vector compile_args = extract_pieces(compile_args_jni); + JniDiagnostics diagnostics(env, diagnostics_obj); + return aapt::CompileCommand(&diagnostics).Execute(compile_args, &std::cerr); +} + +JNIEXPORT jint JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeLink(JNIEnv* env, + jclass aapt_obj, + jobject arguments_obj, + jobject diagnostics_obj) { + std::vector link_args_jni = + list_to_utfchars(env, arguments_obj); + std::vector link_args = extract_pieces(link_args_jni); + JniDiagnostics diagnostics(env, diagnostics_obj); + return aapt::LinkCommand(&diagnostics).Execute(link_args, &std::cerr); +} + +JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_ping( + JNIEnv *env, jclass aapt_obj) { + // This is just a no-op method to see if the library has been loaded. +} diff --git a/tools/aapt2/jni/com_android_tools_aapt2_Aapt2Jni.h b/tools/aapt2/jni/com_android_tools_aapt2_Aapt2Jni.h new file mode 100644 index 0000000000000..3cd98658fab26 --- /dev/null +++ b/tools/aapt2/jni/com_android_tools_aapt2_Aapt2Jni.h @@ -0,0 +1,37 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_android_tools_aapt2_Aapt2Jni */ + +#ifndef _Included_com_android_tools_aapt2_Aapt2Jni +#define _Included_com_android_tools_aapt2_Aapt2Jni +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_android_tools_aapt2_Aapt2Jni + * Method: ping + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_ping + (JNIEnv *, jclass); + +/* + * Class: com_android_tools_aapt2_Aapt2Jni + * Method: nativeCompile + * Signature: (Ljava/util/List;Lcom/android/tools/aapt2/Aapt2JniDiagnostics;)I + */ +JNIEXPORT jint JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeCompile(JNIEnv*, jclass, jobject, + jobject); + +/* + * Class: com_android_tools_aapt2_Aapt2Jni + * Method: nativeLink + * Signature: (Ljava/util/List;Lcom/android/tools/aapt2/Aapt2JniDiagnostics;)I + */ +JNIEXPORT jint JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeLink(JNIEnv*, jclass, jobject, + jobject); + +#ifdef __cplusplus +} +#endif +#endif