From 820d72adc0eccbfe4ac4238cdc89b7680ea03d9e Mon Sep 17 00:00:00 2001 From: Chris Warrington Date: Thu, 27 Apr 2017 15:27:01 +0100 Subject: [PATCH] AAPT2: Error reporting through JNI. Rather than relying on stderr being wired correctly. Test: Tests for JNI integration in studio-master-dev. Change-Id: I1c7e7130bc4e56d61de259a9596bee3a6b3520fb --- tools/aapt2/Main.cpp | 12 ++-- tools/aapt2/cmd/Compile.cpp | 11 ++-- tools/aapt2/cmd/Link.cpp | 11 ++-- tools/aapt2/jni/aapt2_jni.cpp | 61 ++++++++++++++++--- .../jni/com_android_tools_aapt2_Aapt2Jni.h | 12 ++-- 5 files changed, 81 insertions(+), 26 deletions(-) diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp index 87fda16ee956a..1965ad941b2e1 100644 --- a/tools/aapt2/Main.cpp +++ b/tools/aapt2/Main.cpp @@ -19,6 +19,8 @@ #include "androidfw/StringPiece.h" +#include "Diagnostics.h" + namespace aapt { // DO NOT UPDATE, this is more of a marketing version. @@ -33,8 +35,8 @@ int PrintVersion() { return 0; } -extern int Compile(const std::vector& args); -extern int Link(const std::vector& args); +extern int Compile(const std::vector& args, IDiagnostics* diagnostics); +extern int Link(const std::vector& args, IDiagnostics* diagnostics); extern int Dump(const std::vector& args); extern int Diff(const std::vector& args); extern int Optimize(const std::vector& args); @@ -53,9 +55,11 @@ int main(int argc, char** argv) { android::StringPiece command(argv[0]); if (command == "compile" || command == "c") { - return aapt::Compile(args); + aapt::StdErrDiagnostics diagnostics; + return aapt::Compile(args, &diagnostics); } else if (command == "link" || command == "l") { - return aapt::Link(args); + aapt::StdErrDiagnostics diagnostics; + return aapt::Link(args, &diagnostics); } else if (command == "dump" || command == "d") { return aapt::Dump(args); } else if (command == "diff") { diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp index b93c6ecea274a..5413b336ea905 100644 --- a/tools/aapt2/cmd/Compile.cpp +++ b/tools/aapt2/cmd/Compile.cpp @@ -598,6 +598,9 @@ static bool CompileFile(IAaptContext* context, const CompileOptions& options, class CompileContext : public IAaptContext { public: + CompileContext(IDiagnostics* diagnostics) : diagnostics_(diagnostics) { + } + PackageType GetPackageType() override { // Every compilation unit starts as an app and then gets linked as potentially something else. return PackageType::kApp; @@ -612,7 +615,7 @@ class CompileContext : public IAaptContext { } IDiagnostics* GetDiagnostics() override { - return &diagnostics_; + return diagnostics_; } NameMangler* GetNameMangler() override { @@ -639,7 +642,7 @@ class CompileContext : public IAaptContext { } private: - StdErrDiagnostics diagnostics_; + IDiagnostics* diagnostics_; bool verbose_ = false; }; @@ -647,8 +650,8 @@ class CompileContext : public IAaptContext { * Entry point for compilation phase. Parses arguments and dispatches to the * correct steps. */ -int Compile(const std::vector& args) { - CompileContext context; +int Compile(const std::vector& args, IDiagnostics* diagnostics) { + CompileContext context(diagnostics); CompileOptions options; bool verbose = false; diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp index 258516db2ac91..93748d358d7a7 100644 --- a/tools/aapt2/cmd/Link.cpp +++ b/tools/aapt2/cmd/Link.cpp @@ -118,7 +118,8 @@ struct LinkOptions { class LinkContext : public IAaptContext { public: - LinkContext() : name_mangler_({}), symbols_(&name_mangler_) { + LinkContext(IDiagnostics* diagnostics) + : diagnostics_(diagnostics), name_mangler_({}), symbols_(&name_mangler_) { } PackageType GetPackageType() override { @@ -130,7 +131,7 @@ class LinkContext : public IAaptContext { } IDiagnostics* GetDiagnostics() override { - return &diagnostics_; + return diagnostics_; } NameMangler* GetNameMangler() override { @@ -181,7 +182,7 @@ class LinkContext : public IAaptContext { DISALLOW_COPY_AND_ASSIGN(LinkContext); PackageType package_type_ = PackageType::kApp; - StdErrDiagnostics diagnostics_; + IDiagnostics* diagnostics_; NameMangler name_mangler_; std::string compilation_package_; uint8_t package_id_ = 0x0; @@ -1736,8 +1737,8 @@ class LinkCommand { std::map shared_libs_; }; -int Link(const std::vector& args) { - LinkContext context; +int Link(const std::vector& args, IDiagnostics* diagnostics) { + LinkContext context(diagnostics); LinkOptions options; std::vector overlay_arg_list; std::vector extra_java_packages; diff --git a/tools/aapt2/jni/aapt2_jni.cpp b/tools/aapt2/jni/aapt2_jni.cpp index ce3d282e6f9be..ad5ad4c336e5b 100644 --- a/tools/aapt2/jni/aapt2_jni.cpp +++ b/tools/aapt2/jni/aapt2_jni.cpp @@ -24,13 +24,14 @@ #include "android-base/logging.h" #include "ScopedUtfChars.h" +#include "Diagnostics.h" #include "util/Util.h" using android::StringPiece; namespace aapt { -extern int Compile(const std::vector &args); -extern int Link(const std::vector &args); +extern int Compile(const std::vector& args, IDiagnostics* iDiagnostics); +extern int Link(const std::vector& args, IDiagnostics* iDiagnostics); } /* @@ -77,20 +78,66 @@ static std::vector extract_pieces(const std::vector 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) { + 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); - return aapt::Compile(compile_args); + JniDiagnostics diagnostics(env, diagnostics_obj); + return aapt::Compile(compile_args, &diagnostics); } -JNIEXPORT jint JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeLink( - JNIEnv *env, jclass aapt_obj, jobject arguments_obj) { +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); - return aapt::Link(link_args); + JniDiagnostics diagnostics(env, diagnostics_obj); + return aapt::Link(link_args, &diagnostics); } JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_ping( diff --git a/tools/aapt2/jni/com_android_tools_aapt2_Aapt2Jni.h b/tools/aapt2/jni/com_android_tools_aapt2_Aapt2Jni.h index 90150b4d731e9..3cd98658fab26 100644 --- a/tools/aapt2/jni/com_android_tools_aapt2_Aapt2Jni.h +++ b/tools/aapt2/jni/com_android_tools_aapt2_Aapt2Jni.h @@ -18,18 +18,18 @@ JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_ping /* * Class: com_android_tools_aapt2_Aapt2Jni * Method: nativeCompile - * Signature: (Ljava/util/List;)I + * Signature: (Ljava/util/List;Lcom/android/tools/aapt2/Aapt2JniDiagnostics;)I */ -JNIEXPORT jint JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeCompile - (JNIEnv *, jclass, jobject); +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;)I + * Signature: (Ljava/util/List;Lcom/android/tools/aapt2/Aapt2JniDiagnostics;)I */ -JNIEXPORT jint JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeLink - (JNIEnv *, jclass, jobject); +JNIEXPORT jint JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeLink(JNIEnv*, jclass, jobject, + jobject); #ifdef __cplusplus }