blob: ec3c5431c7a379aabedd761d90ce62c90b2f2ad2 [file] [log] [blame]
Paulo Casanova25596082016-10-07 12:00:26 +01001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Paulo Casanovaa2564082016-11-04 11:28:44 +000017#include "com_android_tools_aapt2_Aapt2Jni.h"
Adam Lesinskice5e56e2016-10-21 17:56:45 -070018
Paulo Casanova25596082016-10-07 12:00:26 +010019#include <algorithm>
Paulo Casanova25596082016-10-07 12:00:26 +010020#include <memory>
21#include <utility>
22#include <vector>
23
Adam Lesinskice5e56e2016-10-21 17:56:45 -070024#include "android-base/logging.h"
Steven Morelandfe028b02017-08-11 21:38:39 +000025#include "ScopedUtfChars.h"
Paulo Casanova25596082016-10-07 12:00:26 +010026
Chris Warrington820d72a2017-04-27 15:27:01 +010027#include "Diagnostics.h"
Ryan Mitchell833a1a62018-07-10 13:51:36 -070028#include "cmd/Compile.h"
29#include "cmd/Link.h"
Paulo Casanova25596082016-10-07 12:00:26 +010030#include "util/Util.h"
31
Adam Lesinskid5083f62017-01-16 15:07:21 -080032using android::StringPiece;
33
Paulo Casanova25596082016-10-07 12:00:26 +010034/*
35 * Converts a java List<String> into C++ vector<ScopedUtfChars>.
36 */
37static std::vector<ScopedUtfChars> list_to_utfchars(JNIEnv *env, jobject obj) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -070038 std::vector<ScopedUtfChars> converted;
Paulo Casanova25596082016-10-07 12:00:26 +010039
Adam Lesinskice5e56e2016-10-21 17:56:45 -070040 // Call size() method on the list to know how many elements there are.
41 jclass list_cls = env->GetObjectClass(obj);
42 jmethodID size_method_id = env->GetMethodID(list_cls, "size", "()I");
43 CHECK(size_method_id != 0);
44 jint size = env->CallIntMethod(obj, size_method_id);
45 CHECK(size >= 0);
Paulo Casanova25596082016-10-07 12:00:26 +010046
Adam Lesinskice5e56e2016-10-21 17:56:45 -070047 // Now, iterate all strings in the list
48 // (note: generic erasure means get() return an Object)
Paulo Casanovab555b592016-11-01 14:50:46 +000049 jmethodID get_method_id = env->GetMethodID(list_cls, "get", "(I)Ljava/lang/Object;");
50 CHECK(get_method_id != 0);
Adam Lesinskice5e56e2016-10-21 17:56:45 -070051 for (jint i = 0; i < size; i++) {
52 // Call get(i) to get the string in the ith position.
53 jobject string_obj_uncast = env->CallObjectMethod(obj, get_method_id, i);
54 CHECK(string_obj_uncast != nullptr);
55 jstring string_obj = static_cast<jstring>(string_obj_uncast);
56 converted.push_back(ScopedUtfChars(env, string_obj));
57 }
Paulo Casanova25596082016-10-07 12:00:26 +010058
Adam Lesinskice5e56e2016-10-21 17:56:45 -070059 return converted;
Paulo Casanova25596082016-10-07 12:00:26 +010060}
61
62/*
63 * Extracts all StringPiece from the ScopedUtfChars instances.
Adam Lesinskice5e56e2016-10-21 17:56:45 -070064 *
Paulo Casanova25596082016-10-07 12:00:26 +010065 * The returned pieces can only be used while the original ones have not been
66 * destroyed.
67 */
Adam Lesinskid5083f62017-01-16 15:07:21 -080068static std::vector<StringPiece> extract_pieces(const std::vector<ScopedUtfChars> &strings) {
69 std::vector<StringPiece> pieces;
Adam Lesinskice5e56e2016-10-21 17:56:45 -070070
71 std::for_each(
72 strings.begin(), strings.end(),
73 [&pieces](const ScopedUtfChars &p) { pieces.push_back(p.c_str()); });
74
75 return pieces;
Paulo Casanova25596082016-10-07 12:00:26 +010076}
77
Chris Warrington820d72a2017-04-27 15:27:01 +010078class JniDiagnostics : public aapt::IDiagnostics {
79 public:
80 JniDiagnostics(JNIEnv* env, jobject diagnostics_obj)
81 : env_(env), diagnostics_obj_(diagnostics_obj) {
82 mid_ = NULL;
83 }
84
85 void Log(Level level, aapt::DiagMessageActual& actual_msg) override {
86 jint level_value;
87 switch (level) {
88 case Level::Error:
89 level_value = 3;
90 break;
91
92 case Level::Warn:
93 level_value = 2;
94 break;
95
96 case Level::Note:
97 level_value = 1;
98 break;
99 }
100 jstring message = env_->NewStringUTF(actual_msg.message.c_str());
101 jstring path = env_->NewStringUTF(actual_msg.source.path.c_str());
102 jlong line = -1;
103 if (actual_msg.source.line) {
104 line = actual_msg.source.line.value();
105 }
106 if (!mid_) {
107 jclass diagnostics_cls = env_->GetObjectClass(diagnostics_obj_);
108 mid_ = env_->GetMethodID(diagnostics_cls, "log", "(ILjava/lang/String;JLjava/lang/String;)V");
109 }
110 env_->CallVoidMethod(diagnostics_obj_, mid_, level_value, path, line, message);
111 }
112
113 private:
114 JNIEnv* env_;
115 jobject diagnostics_obj_;
116 jmethodID mid_;
117 DISALLOW_COPY_AND_ASSIGN(JniDiagnostics);
118};
119
Chris Warrington014d3152017-04-10 11:49:59 +0100120JNIEXPORT jint JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeCompile(
Chris Warrington820d72a2017-04-27 15:27:01 +0100121 JNIEnv* env, jclass aapt_obj, jobject arguments_obj, jobject diagnostics_obj) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700122 std::vector<ScopedUtfChars> compile_args_jni =
123 list_to_utfchars(env, arguments_obj);
Adam Lesinskid5083f62017-01-16 15:07:21 -0800124 std::vector<StringPiece> compile_args = extract_pieces(compile_args_jni);
Chris Warrington820d72a2017-04-27 15:27:01 +0100125 JniDiagnostics diagnostics(env, diagnostics_obj);
Ryan Mitchell833a1a62018-07-10 13:51:36 -0700126 return aapt::CompileCommand(&diagnostics).Execute(compile_args, &std::cerr);
Paulo Casanova25596082016-10-07 12:00:26 +0100127}
128
Chris Warrington820d72a2017-04-27 15:27:01 +0100129JNIEXPORT jint JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeLink(JNIEnv* env,
130 jclass aapt_obj,
131 jobject arguments_obj,
132 jobject diagnostics_obj) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700133 std::vector<ScopedUtfChars> link_args_jni =
134 list_to_utfchars(env, arguments_obj);
Adam Lesinskid5083f62017-01-16 15:07:21 -0800135 std::vector<StringPiece> link_args = extract_pieces(link_args_jni);
Chris Warrington820d72a2017-04-27 15:27:01 +0100136 JniDiagnostics diagnostics(env, diagnostics_obj);
Ryan Mitchell833a1a62018-07-10 13:51:36 -0700137 return aapt::LinkCommand(&diagnostics).Execute(link_args, &std::cerr);
Paulo Casanova25596082016-10-07 12:00:26 +0100138}
Paulo Casanovab555b592016-11-01 14:50:46 +0000139
Paulo Casanovaa2564082016-11-04 11:28:44 +0000140JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_ping(
Paulo Casanovab555b592016-11-01 14:50:46 +0000141 JNIEnv *env, jclass aapt_obj) {
Ryan Mitchell4ea90752020-07-31 08:21:43 -0700142 // This is just a no-op method to see if the library has been loaded.
Paulo Casanovab555b592016-11-01 14:50:46 +0000143}