summaryrefslogtreecommitdiffstats
path: root/misc/jni.h
blob: 96b293771def8ba9d8e152b1c391485fd245e345 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
 * JNI utility functions
 *
 * Copyright (c) 2015-2016 Matthieu Bouron <matthieu.bouron stupeflix.com>
 *
 * This file is part of mpv.
 *
 * mpv is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * mpv is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with mpv.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef MP_JNI_H
#define MP_JNI_H

#include <stdbool.h>
#include <jni.h>
#include "common/msg.h"

/* Convenience macros */
#define MP_JNI_GET_ENV(obj) mp_jni_get_env((obj)->log)
#define MP_JNI_EXCEPTION_CHECK() mp_jni_exception_check(env, 0, NULL)
#define MP_JNI_EXCEPTION_LOG(obj) mp_jni_exception_check(env, 1, (obj)->log)
#define MP_JNI_DO(what, obj, ...) (*env)->what(env, obj, ##__VA_ARGS__)
#define MP_JNI_NEW(clazz, method, ...) MP_JNI_DO(NewObject, clazz, method, ##__VA_ARGS__)
#define MP_JNI_CALL_INT(obj, method, ...) MP_JNI_DO(CallIntMethod, obj, method, ##__VA_ARGS__)
#define MP_JNI_CALL_BOOL(obj, method, ...) MP_JNI_DO(CallBooleanMethod, obj, method, ##__VA_ARGS__)
#define MP_JNI_CALL_VOID(obj, method, ...) MP_JNI_DO(CallVoidMethod, obj, method, ##__VA_ARGS__)
#define MP_JNI_CALL_STATIC_INT(clazz, method, ...) MP_JNI_DO(CallStaticIntMethod, clazz, method, ##__VA_ARGS__)
#define MP_JNI_CALL_OBJECT(obj, method, ...) MP_JNI_DO(CallObjectMethod, obj, method, ##__VA_ARGS__)
#define MP_JNI_GET_INT(obj, field) MP_JNI_DO(GetIntField, obj, field)
#define MP_JNI_GET_LONG(obj, field) MP_JNI_DO(GetLongField, obj, field)
#define MP_JNI_GET_BOOL(obj, field) MP_JNI_DO(GetBoolField, obj, field)
#define MP_JNI_LOCAL_FREEP(objp) do { \
        if (*(objp)) \
            MP_JNI_DO(DeleteLocalRef, *(objp)); \
        *(objp) = NULL; \
    } while (0)
#define MP_JNI_GLOBAL_FREEP(objp) do { \
        if (*(objp)) \
            MP_JNI_DO(DeleteGlobalRef, *(objp)); \
        *(objp) = NULL; \
    } while (0)

/*
 * Attach permanently a JNI environment to the current thread and retrieve it.
 *
 * If successfully attached, the JNI environment will automatically be detached
 * at thread destruction.
 *
 * @param attached pointer to an integer that will be set to 1 if the
 * environment has been attached to the current thread or 0 if it is
 * already attached.
 * @param log context used for logging
 * @return the JNI environment on success, NULL otherwise
 */
JNIEnv *mp_jni_get_env(struct mp_log *log);

/*
 * Convert a jstring to its utf characters equivalent.
 *
 * @param env JNI environment
 * @param string Java string to convert
 * @param log context used for logging
 * @return a pointer to an array of unicode characters on success, NULL
 * otherwise
 */
char *mp_jni_jstring_to_utf_chars(JNIEnv *env, jstring string, struct mp_log *log);

/*
 * Convert utf chars to its jstring equivalent.
 *
 * @param env JNI environment
 * @param utf_chars a pointer to an array of unicode characters
 * @param log context used for logging
 * @return a Java string object on success, NULL otherwise
 */
jstring mp_jni_utf_chars_to_jstring(JNIEnv *env, const char *utf_chars, struct mp_log *log);

/*
 * Extract the error summary from a jthrowable in the form of "className: errorMessage"
 *
 * @param env JNI environment
 * @param exception exception to get the summary from
 * @param error address pointing to the error, the value is updated if a
 * summary can be extracted
 * @param log context used for logging
 * @return 0 on success, < 0 otherwise
 */
int mp_jni_exception_get_summary(JNIEnv *env, jthrowable exception, char **error, struct mp_log *log);

/*
 * Check if an exception has occurred,log it using av_log and clear it.
 *
 * @param env JNI environment
 * @param value used to enable logging if an exception has occurred,
 * 0 disables logging, != 0 enables logging
 * @param log context used for logging
 */
int mp_jni_exception_check(JNIEnv *env, int logging, struct mp_log *log);

/*
 * Jni field type.
 */
enum MPJniFieldType {

    MP_JNI_CLASS,
    MP_JNI_FIELD,
    MP_JNI_STATIC_FIELD,
    MP_JNI_STATIC_FIELD_AS_INT,
    MP_JNI_METHOD,
    MP_JNI_STATIC_METHOD

};

/*
 * Jni field describing a class, a field or a method to be retrieved using
 * the mp_jni_init_jfields method.
 */
struct MPJniField {

    const char *name;
    const char *signature;
    enum MPJniFieldType type;
    int offset;
    bool mandatory;

};

/*
 * Retrieve class references, field ids and method ids to an arbitrary structure.
 *
 * @param env JNI environment
 * @param jfields a pointer to an arbitrary structure where the different
 * fields are declared and where the MPJNIField mapping table offsets are
 * pointing to
 * @param jfields_mapping null terminated array of MPJNIFields describing
 * the class/field/method to be retrieved
 * @param global make the classes references global. It is the caller
 * responsibility to properly release global references.
 * @param log_ctx context used for logging, can be NULL
 * @return 0 on success, < 0 otherwise
 */
int mp_jni_init_jfields(JNIEnv *env, void *jfields, const struct MPJniField *jfields_mapping, int global, struct mp_log *log);

/*
 * Delete class references, field ids and method ids of an arbitrary structure.
 *
 * @param env JNI environment
 * @param jfields a pointer to an arbitrary structure where the different
 * fields are declared and where the MPJNIField mapping table offsets are
 * pointing to
 * @param jfields_mapping null terminated array of MPJNIFields describing
 * the class/field/method to be deleted
 * @param global treat the classes references as global and delete them
 * accordingly
 * @param log_ctx context used for logging, can be NULL
 * @return 0 on success, < 0 otherwise
 */
int mp_jni_reset_jfields(JNIEnv *env, void *jfields, const struct MPJniField *jfields_mapping, int global, struct mp_log *log);

#endif