1 /*
2  * Copyright (C) 2020 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 
17 #include <iterator>
18 
19 #include <dlfcn.h>
20 #include <jni.h>
21 
22 #include <android/log.h>
23 #include <nativehelper/jni_macros.h>
24 #include <nativehelper/scoped_local_ref.h>
25 #include <nativehelper/scoped_string_chars.h>
26 #include <nativehelper/scoped_utf_chars.h>
27 #include <nativehelper/JNIPlatformHelp.h>
28 
29 #include "libnativehelper_test.h"
30 
31 namespace {
32 
33 static void throwException(JNIEnv* env, jclass /*clazz*/, jstring className, jstring message) {
34     ScopedUtfChars c(env, className);
35     ScopedUtfChars m(env, message);
36     jniThrowException(env, c.c_str(), m.c_str());
37 }
38 
39 static void throwExceptionWithIntFormat(JNIEnv* env,
40                                         jclass /*clazz*/,
41                                         jstring className,
42                                         jstring format,
43                                         jint value) {
44     ScopedUtfChars c(env, className);
45     ScopedUtfChars f(env, format);
46     jniThrowExceptionFmt(env, c.c_str(), f.c_str(), value);
47 }
48 
49 static void throwNullPointerException(JNIEnv* env,
50                                       jclass /*clazz*/,
51                                       jstring message) {
52     ScopedUtfChars m(env, message);
53     jniThrowNullPointerException(env, m.c_str());
54 }
55 
56 static void throwRuntimeException(JNIEnv* env, jclass /*clazz*/, jstring message) {
57     ScopedUtfChars m(env, message);
58     jniThrowRuntimeException(env, m.c_str());
59 }
60 
61 static void throwIOException(JNIEnv* env, jclass /*clazz*/, jint cause) {
62     jniThrowIOException(env, cause);
63 }
64 
65 static void throwErrnoException(JNIEnv* env, jclass /*clazz*/, jstring functionName, jint cause) {
66     ScopedUtfChars m(env, functionName);
67     jniThrowErrnoException(env, m.c_str(), cause);
68 }
69 
70 static void logException(JNIEnv* env, jclass /*clazz*/, jthrowable throwable) {
71     jniLogException(env, ANDROID_LOG_VERBOSE, __FILE__, throwable);
72 }
73 
74 static jobject fileDescriptorCreate(JNIEnv* env, jclass /*clazz*/, jint unix_fd) {
75     return jniCreateFileDescriptor(env, unix_fd);
76 }
77 
78 static jint fileDescriptorGetFD(JNIEnv* env, jclass /*clazz*/, jobject jiofd) {
79     return jniGetFDFromFileDescriptor(env, jiofd);
80 }
81 
82 static void fileDescriptorSetFD(JNIEnv* env, jclass /*clazz*/, jobject jiofd, jint unix_fd) {
83     jniSetFileDescriptorOfFD(env, jiofd, unix_fd);
84 }
85 
86 static jstring createString(JNIEnv* env, jclass /*clazz*/, jstring value) {
87     ScopedStringChars ssc(env, value);
88     return jniCreateString(env, ssc.get(), ssc.size());
89 }
90 
91 }  // namespace
92 
93 JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
94     JNIEnv* env;
95     if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
96         return JNI_ERR;
97     }
98 
99     static const JNINativeMethod methods[] = {
100         MAKE_JNI_NATIVE_METHOD("throwException",
101                                "(Ljava/lang/String;Ljava/lang/String;)V",
102                                throwException),
103         MAKE_JNI_NATIVE_METHOD("throwExceptionWithIntFormat",
104                                "(Ljava/lang/String;Ljava/lang/String;I)V",
105                                throwExceptionWithIntFormat),
106         MAKE_JNI_NATIVE_METHOD("throwNullPointerException",
107                                "(Ljava/lang/String;)V",
108                                throwNullPointerException),
109         MAKE_JNI_NATIVE_METHOD("throwRuntimeException",
110                                "(Ljava/lang/String;)V",
111                                throwRuntimeException),
112         MAKE_JNI_NATIVE_METHOD("throwIOException",
113                                "(I)V",
114                                throwIOException),
115         MAKE_JNI_NATIVE_METHOD("throwErrnoException",
116                                "(Ljava/lang/String;I)V",
117                                throwErrnoException),
118         MAKE_JNI_NATIVE_METHOD("logException",
119                                "(Ljava/lang/Throwable;)V",
120                                logException),
121         MAKE_JNI_NATIVE_METHOD("fileDescriptorCreate",
122                                "(I)Ljava/io/FileDescriptor;",
123                                fileDescriptorCreate),
124         MAKE_JNI_NATIVE_METHOD("fileDescriptorGetFD",
125                                "(Ljava/io/FileDescriptor;)I",
126                                fileDescriptorGetFD),
127         MAKE_JNI_NATIVE_METHOD("fileDescriptorSetFD",
128                                "(Ljava/io/FileDescriptor;I)V",
129                                fileDescriptorSetFD),
130         MAKE_JNI_NATIVE_METHOD("createString",
131                                "(Ljava/lang/String;)Ljava/lang/String;",
132                                createString),
133     };
134     int rc = jniRegisterNativeMethods(env,
135                                       "com/android/art/libnativehelper/JniHelpTest",
136                                       methods,
137                                       std::size(methods));
138     if (rc != JNI_OK) return rc;
139 
140     return JNI_VERSION_1_6;
141 }
142