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
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_jni_Types_h__
#define mozilla_jni_Types_h__
#include <jni.h>
#include "mozilla/jni/Refs.h"
#include "mozilla/jni/TypeAdapter.h"
namespace mozilla {
namespace jni {
namespace detail {
// TypeAdapter specializations are the interfaces between native/C++ types such
// as int32_t and JNI types such as jint. The template parameter T is the native
// type, and each TypeAdapter specialization can have the following members:
//
// * Call: JNIEnv member pointer for making a method call that returns T.
// * StaticCall: JNIEnv member pointer for making a static call that returns T.
// * Get: JNIEnv member pointer for getting a field of type T.
// * StaticGet: JNIEnv member pointer for getting a static field of type T.
// * Set: JNIEnv member pointer for setting a field of type T.
// * StaticGet: JNIEnv member pointer for setting a static field of type T.
// * ToNative: static function that converts the JNI type to the native type.
// * FromNative: static function that converts the native type to the JNI type.
// TypeAdapter<LocalRef<Cls>> applies when jobject is a return value.
template <class Cls>
struct TypeAdapter<LocalRef<Cls>> {
using JNIType = typename Cls::Ref::JNIType;
static constexpr auto Call = &JNIEnv::CallObjectMethodA;
static constexpr auto StaticCall = &JNIEnv::CallStaticObjectMethodA;
static constexpr auto Get = &JNIEnv::GetObjectField;
static constexpr auto StaticGet = &JNIEnv::GetStaticObjectField;
// Declare instance as jobject because JNI methods return
// jobject even if the return value is really jstring, etc.
static LocalRef<Cls> ToNative(JNIEnv* env, jobject instance) {
return LocalRef<Cls>::Adopt(env, JNIType(instance));
}
static JNIType FromNative(JNIEnv*, LocalRef<Cls>&& instance) {
return instance.Forget();
}
};
// clang is picky about function types, including attributes that modify the
// calling convention, lining up. GCC appears to be somewhat less so.
#ifdef __clang__
# define MOZ_JNICALL_ABI JNICALL
#else
# define MOZ_JNICALL_ABI
#endif
// NDK r18 made jvalue* method parameters const. We detect the change directly
// instead of using ndk-version.h in order to remain compatible with r15 for
// now, which doesn't include those headers.
class CallArgs {
static const jvalue* test(void (JNIEnv::*)(jobject, jmethodID,
const jvalue*));
static jvalue* test(void (JNIEnv::*)(jobject, jmethodID, jvalue*));
public:
using JValueType = decltype(test(&JNIEnv::CallVoidMethodA));
};
template <class Cls>
constexpr jobject (JNIEnv::*TypeAdapter<LocalRef<Cls>>::Call)(
jobject, jmethodID, CallArgs::JValueType) MOZ_JNICALL_ABI;
template <class Cls>
constexpr jobject (JNIEnv::*TypeAdapter<LocalRef<Cls>>::StaticCall)(
jclass, jmethodID, CallArgs::JValueType) MOZ_JNICALL_ABI;
template <class Cls>
constexpr jobject (JNIEnv::*TypeAdapter<LocalRef<Cls>>::Get)(jobject, jfieldID);
template <class Cls>
constexpr jobject (JNIEnv::*TypeAdapter<LocalRef<Cls>>::StaticGet)(jclass,
jfieldID);
// TypeAdapter<Ref<Cls>> applies when jobject is a parameter value.
template <class Cls, typename T>
struct TypeAdapter<Ref<Cls, T>> {
using JNIType = typename Ref<Cls, T>::JNIType;
static constexpr auto Set = &JNIEnv::SetObjectField;
static constexpr auto StaticSet = &JNIEnv::SetStaticObjectField;
static DependentRef<Cls> ToNative(JNIEnv* env, JNIType instance) {
return DependentRef<Cls>(instance);
}
static JNIType FromNative(JNIEnv*, const Ref<Cls, T>& instance) {
return instance.Get();
}
};
template <class Cls, typename T>
constexpr void (JNIEnv::*TypeAdapter<Ref<Cls, T>>::Set)(jobject, jfieldID,
jobject);
template <class Cls, typename T>
constexpr void (JNIEnv::*TypeAdapter<Ref<Cls, T>>::StaticSet)(jclass, jfieldID,
jobject);
// jstring has its own Param type.
template <>
struct TypeAdapter<StringParam> : public TypeAdapter<String::Ref> {};
template <class Cls>
struct TypeAdapter<const Cls&> : public TypeAdapter<Cls> {};
} // namespace detail
using namespace detail;
} // namespace jni
} // namespace mozilla
#endif // mozilla_jni_Types_h__
|