summaryrefslogtreecommitdiffstats
path: root/widget/android/jni
diff options
context:
space:
mode:
Diffstat (limited to 'widget/android/jni')
-rw-r--r--widget/android/jni/Accessors.h274
-rw-r--r--widget/android/jni/Natives.h707
-rw-r--r--widget/android/jni/Refs.h953
-rw-r--r--widget/android/jni/Types.h140
-rw-r--r--widget/android/jni/Utils.cpp291
-rw-r--r--widget/android/jni/Utils.h147
-rw-r--r--widget/android/jni/moz.build24
7 files changed, 0 insertions, 2536 deletions
diff --git a/widget/android/jni/Accessors.h b/widget/android/jni/Accessors.h
deleted file mode 100644
index fe2cbc9d4..000000000
--- a/widget/android/jni/Accessors.h
+++ /dev/null
@@ -1,274 +0,0 @@
-#ifndef mozilla_jni_Accessors_h__
-#define mozilla_jni_Accessors_h__
-
-#include <jni.h>
-
-#include "mozilla/jni/Refs.h"
-#include "mozilla/jni/Types.h"
-#include "mozilla/jni/Utils.h"
-#include "AndroidBridge.h"
-
-namespace mozilla {
-namespace jni {
-
-namespace detail {
-
-// Helper class to convert an arbitrary type to a jvalue, e.g. Value(123).val.
-struct Value
-{
- Value(jboolean z) { val.z = z; }
- Value(jbyte b) { val.b = b; }
- Value(jchar c) { val.c = c; }
- Value(jshort s) { val.s = s; }
- Value(jint i) { val.i = i; }
- Value(jlong j) { val.j = j; }
- Value(jfloat f) { val.f = f; }
- Value(jdouble d) { val.d = d; }
- Value(jobject l) { val.l = l; }
-
- jvalue val;
-};
-
-} // namespace detail
-
-using namespace detail;
-
-// Base class for Method<>, Field<>, and Constructor<>.
-class Accessor
-{
- static void GetNsresult(JNIEnv* env, nsresult* rv)
- {
- if (env->ExceptionCheck()) {
-#ifdef MOZ_CHECK_JNI
- env->ExceptionDescribe();
-#endif
- env->ExceptionClear();
- *rv = NS_ERROR_FAILURE;
- } else {
- *rv = NS_OK;
- }
- }
-
-protected:
- // Called after making a JNIEnv call.
- template<class Traits>
- static void EndAccess(const typename Traits::Owner::Context& ctx,
- nsresult* rv)
- {
- if (Traits::exceptionMode == ExceptionMode::ABORT) {
- MOZ_CATCH_JNI_EXCEPTION(ctx.Env());
-
- } else if (Traits::exceptionMode == ExceptionMode::NSRESULT) {
- GetNsresult(ctx.Env(), rv);
- }
- }
-};
-
-
-// Member<> is used to call a JNI method given a traits class.
-template<class Traits, typename ReturnType = typename Traits::ReturnType>
-class Method : public Accessor
-{
- typedef Accessor Base;
- typedef typename Traits::Owner::Context Context;
-
-protected:
- static jmethodID sID;
-
- static void BeginAccess(const Context& ctx)
- {
- MOZ_ASSERT_JNI_THREAD(Traits::callingThread);
- static_assert(Traits::dispatchTarget == DispatchTarget::CURRENT,
- "Dispatching not supported for method call");
-
- if (sID) {
- return;
- }
-
- if (Traits::isStatic) {
- MOZ_ALWAYS_TRUE(sID = AndroidBridge::GetStaticMethodID(
- ctx.Env(), ctx.ClassRef(), Traits::name, Traits::signature));
- } else {
- MOZ_ALWAYS_TRUE(sID = AndroidBridge::GetMethodID(
- ctx.Env(), ctx.ClassRef(), Traits::name, Traits::signature));
- }
- }
-
- static void EndAccess(const Context& ctx, nsresult* rv)
- {
- return Base::EndAccess<Traits>(ctx, rv);
- }
-
-public:
- template<typename... Args>
- static ReturnType Call(const Context& ctx, nsresult* rv, const Args&... args)
- {
- JNIEnv* const env = ctx.Env();
- BeginAccess(ctx);
-
- jvalue jargs[] = {
- Value(TypeAdapter<Args>::FromNative(env, args)).val ...
- };
-
- auto result = TypeAdapter<ReturnType>::ToNative(env,
- Traits::isStatic ?
- (env->*TypeAdapter<ReturnType>::StaticCall)(
- ctx.RawClassRef(), sID, jargs) :
- (env->*TypeAdapter<ReturnType>::Call)(
- ctx.Get(), sID, jargs));
-
- EndAccess(ctx, rv);
- return result;
- }
-};
-
-// Define sID member.
-template<class T, typename R> jmethodID Method<T, R>::sID;
-
-
-// Specialize void because C++ forbids us from
-// using a "void" temporary result variable.
-template<class Traits>
-class Method<Traits, void> : public Method<Traits, bool>
-{
- typedef Method<Traits, bool> Base;
- typedef typename Traits::Owner::Context Context;
-
-public:
- template<typename... Args>
- static void Call(const Context& ctx, nsresult* rv,
- const Args&... args)
- {
- JNIEnv* const env = ctx.Env();
- Base::BeginAccess(ctx);
-
- jvalue jargs[] = {
- Value(TypeAdapter<Args>::FromNative(env, args)).val ...
- };
-
- if (Traits::isStatic) {
- env->CallStaticVoidMethodA(ctx.RawClassRef(), Base::sID, jargs);
- } else {
- env->CallVoidMethodA(ctx.Get(), Base::sID, jargs);
- }
-
- Base::EndAccess(ctx, rv);
- }
-};
-
-
-// Constructor<> is used to construct a JNI instance given a traits class.
-template<class Traits>
-class Constructor : protected Method<Traits, typename Traits::ReturnType> {
- typedef typename Traits::Owner::Context Context;
- typedef typename Traits::ReturnType ReturnType;
- typedef Method<Traits, ReturnType> Base;
-
-public:
- template<typename... Args>
- static ReturnType Call(const Context& ctx, nsresult* rv,
- const Args&... args)
- {
- JNIEnv* const env = ctx.Env();
- Base::BeginAccess(ctx);
-
- jvalue jargs[] = {
- Value(TypeAdapter<Args>::FromNative(env, args)).val ...
- };
-
- auto result = TypeAdapter<ReturnType>::ToNative(
- env, env->NewObjectA(ctx.RawClassRef(), Base::sID, jargs));
-
- Base::EndAccess(ctx, rv);
- return result;
- }
-};
-
-
-// Field<> is used to access a JNI field given a traits class.
-template<class Traits>
-class Field : public Accessor
-{
- typedef Accessor Base;
- typedef typename Traits::Owner::Context Context;
- typedef typename Traits::ReturnType GetterType;
- typedef typename Traits::SetterType SetterType;
-
-private:
-
- static jfieldID sID;
-
- static void BeginAccess(const Context& ctx)
- {
- MOZ_ASSERT_JNI_THREAD(Traits::callingThread);
- static_assert(Traits::dispatchTarget == DispatchTarget::CURRENT,
- "Dispatching not supported for field access");
-
- if (sID) {
- return;
- }
-
- if (Traits::isStatic) {
- MOZ_ALWAYS_TRUE(sID = AndroidBridge::GetStaticFieldID(
- ctx.Env(), ctx.ClassRef(), Traits::name, Traits::signature));
- } else {
- MOZ_ALWAYS_TRUE(sID = AndroidBridge::GetFieldID(
- ctx.Env(), ctx.ClassRef(), Traits::name, Traits::signature));
- }
- }
-
- static void EndAccess(const Context& ctx, nsresult* rv)
- {
- return Base::EndAccess<Traits>(ctx, rv);
- }
-
-public:
- static GetterType Get(const Context& ctx, nsresult* rv)
- {
- JNIEnv* const env = ctx.Env();
- BeginAccess(ctx);
-
- auto result = TypeAdapter<GetterType>::ToNative(
- env, Traits::isStatic ?
-
- (env->*TypeAdapter<GetterType>::StaticGet)
- (ctx.RawClassRef(), sID) :
-
- (env->*TypeAdapter<GetterType>::Get)
- (ctx.Get(), sID));
-
- EndAccess(ctx, rv);
- return result;
- }
-
- static void Set(const Context& ctx, nsresult* rv, SetterType val)
- {
- JNIEnv* const env = ctx.Env();
- BeginAccess(ctx);
-
- if (Traits::isStatic) {
- (env->*TypeAdapter<SetterType>::StaticSet)(
- ctx.RawClassRef(), sID,
- TypeAdapter<SetterType>::FromNative(env, val));
- } else {
- (env->*TypeAdapter<SetterType>::Set)(
- ctx.Get(), sID,
- TypeAdapter<SetterType>::FromNative(env, val));
- }
-
- EndAccess(ctx, rv);
- }
-};
-
-// Define sID member.
-template<class T> jfieldID Field<T>::sID;
-
-
-// Define the sClassRef member declared in Refs.h and
-// used by Method and Field above.
-template<class C, typename T> jclass Context<C, T>::sClassRef;
-
-} // namespace jni
-} // namespace mozilla
-
-#endif // mozilla_jni_Accessors_h__
diff --git a/widget/android/jni/Natives.h b/widget/android/jni/Natives.h
deleted file mode 100644
index 511d96a87..000000000
--- a/widget/android/jni/Natives.h
+++ /dev/null
@@ -1,707 +0,0 @@
-#ifndef mozilla_jni_Natives_h__
-#define mozilla_jni_Natives_h__
-
-#include <jni.h>
-
-#include "mozilla/IndexSequence.h"
-#include "mozilla/Move.h"
-#include "mozilla/Tuple.h"
-#include "mozilla/TypeTraits.h"
-#include "mozilla/UniquePtr.h"
-#include "mozilla/WeakPtr.h"
-#include "mozilla/Unused.h"
-#include "mozilla/jni/Accessors.h"
-#include "mozilla/jni/Refs.h"
-#include "mozilla/jni/Types.h"
-#include "mozilla/jni/Utils.h"
-
-namespace mozilla {
-namespace jni {
-
-/**
- * C++ classes implementing instance (non-static) native methods can choose
- * from one of two ownership models, when associating a C++ object with a Java
- * instance.
- *
- * * If the C++ class inherits from mozilla::SupportsWeakPtr, weak pointers
- * will be used. The Java instance will store and own the pointer to a
- * WeakPtr object. The C++ class itself is otherwise not owned or directly
- * referenced. To attach a Java instance to a C++ instance, pass in a pointer
- * to the C++ class (i.e. MyClass*).
- *
- * class MyClass : public SupportsWeakPtr<MyClass>
- * , public MyJavaClass::Natives<MyClass>
- * {
- * // ...
- *
- * public:
- * MOZ_DECLARE_WEAKREFERENCE_TYPENAME(MyClass)
- * using MyJavaClass::Natives<MyClass>::Dispose;
- *
- * void AttachTo(const MyJavaClass::LocalRef& instance)
- * {
- * MyJavaClass::Natives<MyClass>::AttachInstance(instance, this);
- *
- * // "instance" does NOT own "this", so the C++ object
- * // lifetime is separate from the Java object lifetime.
- * }
- * };
- *
- * * If the C++ class doesn't inherit from mozilla::SupportsWeakPtr, the Java
- * instance will store and own a pointer to the C++ object itself. This
- * pointer must not be stored or deleted elsewhere. To attach a Java instance
- * to a C++ instance, pass in a reference to a UniquePtr of the C++ class
- * (i.e. UniquePtr<MyClass>).
- *
- * class MyClass : public MyJavaClass::Natives<MyClass>
- * {
- * // ...
- *
- * public:
- * using MyJavaClass::Natives<MyClass>::Dispose;
- *
- * static void AttachTo(const MyJavaClass::LocalRef& instance)
- * {
- * MyJavaClass::Natives<MyClass>::AttachInstance(
- * instance, mozilla::MakeUnique<MyClass>());
- *
- * // "instance" owns the newly created C++ object, so the C++
- * // object is destroyed as soon as instance.dispose() is called.
- * }
- * };
- */
-
-namespace detail {
-
-inline uintptr_t CheckNativeHandle(JNIEnv* env, uintptr_t handle)
-{
- if (!handle) {
- if (!env->ExceptionCheck()) {
- ThrowException(env, "java/lang/NullPointerException",
- "Null native pointer");
- }
- return 0;
- }
- return handle;
-}
-
-template<class Impl, bool UseWeakPtr = mozilla::IsBaseOf<
- SupportsWeakPtr<Impl>, Impl>::value /* = false */>
-struct NativePtr
-{
- static Impl* Get(JNIEnv* env, jobject instance)
- {
- return reinterpret_cast<Impl*>(CheckNativeHandle(
- env, GetNativeHandle(env, instance)));
- }
-
- template<class LocalRef>
- static Impl* Get(const LocalRef& instance)
- {
- return Get(instance.Env(), instance.Get());
- }
-
- template<class LocalRef>
- static void Set(const LocalRef& instance, UniquePtr<Impl>&& ptr)
- {
- Clear(instance);
- SetNativeHandle(instance.Env(), instance.Get(),
- reinterpret_cast<uintptr_t>(ptr.release()));
- MOZ_CATCH_JNI_EXCEPTION(instance.Env());
- }
-
- template<class LocalRef>
- static void Clear(const LocalRef& instance)
- {
- UniquePtr<Impl> ptr(reinterpret_cast<Impl*>(
- GetNativeHandle(instance.Env(), instance.Get())));
- MOZ_CATCH_JNI_EXCEPTION(instance.Env());
-
- if (ptr) {
- SetNativeHandle(instance.Env(), instance.Get(), 0);
- MOZ_CATCH_JNI_EXCEPTION(instance.Env());
- }
- }
-};
-
-template<class Impl>
-struct NativePtr<Impl, /* UseWeakPtr = */ true>
-{
- static Impl* Get(JNIEnv* env, jobject instance)
- {
- const auto ptr = reinterpret_cast<WeakPtr<Impl>*>(
- CheckNativeHandle(env, GetNativeHandle(env, instance)));
- if (!ptr) {
- return nullptr;
- }
-
- Impl* const impl = *ptr;
- if (!impl) {
- ThrowException(env, "java/lang/NullPointerException",
- "Native object already released");
- }
- return impl;
- }
-
- template<class LocalRef>
- static Impl* Get(const LocalRef& instance)
- {
- return Get(instance.Env(), instance.Get());
- }
-
- template<class LocalRef>
- static void Set(const LocalRef& instance, Impl* ptr)
- {
- Clear(instance);
- SetNativeHandle(instance.Env(), instance.Get(),
- reinterpret_cast<uintptr_t>(new WeakPtr<Impl>(ptr)));
- MOZ_CATCH_JNI_EXCEPTION(instance.Env());
- }
-
- template<class LocalRef>
- static void Clear(const LocalRef& instance)
- {
- const auto ptr = reinterpret_cast<WeakPtr<Impl>*>(
- GetNativeHandle(instance.Env(), instance.Get()));
- MOZ_CATCH_JNI_EXCEPTION(instance.Env());
-
- if (ptr) {
- SetNativeHandle(instance.Env(), instance.Get(), 0);
- MOZ_CATCH_JNI_EXCEPTION(instance.Env());
- delete ptr;
- }
- }
-};
-
-} // namespace detail
-
-using namespace detail;
-
-/**
- * For JNI native methods that are dispatched to a proxy, i.e. using
- * @WrapForJNI(dispatchTo = "proxy"), the implementing C++ class must provide a
- * OnNativeCall member. Subsequently, every native call is automatically
- * wrapped in a functor object, and the object is passed to OnNativeCall. The
- * OnNativeCall implementation can choose to invoke the call, save it, dispatch
- * it to a different thread, etc. Each copy of functor may only be invoked
- * once.
- *
- * class MyClass : public MyJavaClass::Natives<MyClass>
- * {
- * // ...
- *
- * template<class Functor>
- * class ProxyRunnable final : public Runnable
- * {
- * Functor mCall;
- * public:
- * ProxyRunnable(Functor&& call) : mCall(mozilla::Move(call)) {}
- * virtual void run() override { mCall(); }
- * };
- *
- * public:
- * template<class Functor>
- * static void OnNativeCall(Functor&& call)
- * {
- * RunOnAnotherThread(new ProxyRunnable(mozilla::Move(call)));
- * }
- * };
- */
-
-namespace detail {
-
-// ProxyArg is used to handle JNI ref arguments for proxies. Because a proxied
-// call may happen outside of the original JNI native call, we must save all
-// JNI ref arguments as global refs to avoid the arguments going out of scope.
-template<typename T>
-struct ProxyArg
-{
- static_assert(mozilla::IsPod<T>::value, "T must be primitive type");
-
- // Primitive types can be saved by value.
- typedef T Type;
- typedef typename TypeAdapter<T>::JNIType JNIType;
-
- static void Clear(JNIEnv* env, Type&) {}
-
- static Type From(JNIEnv* env, JNIType val)
- {
- return TypeAdapter<T>::ToNative(env, val);
- }
-};
-
-template<class C, typename T>
-struct ProxyArg<Ref<C, T>>
-{
- // Ref types need to be saved by global ref.
- typedef typename C::GlobalRef Type;
- typedef typename TypeAdapter<Ref<C, T>>::JNIType JNIType;
-
- static void Clear(JNIEnv* env, Type& ref) { ref.Clear(env); }
-
- static Type From(JNIEnv* env, JNIType val)
- {
- return Type(env, C::Ref::From(val));
- }
-};
-
-template<typename C> struct ProxyArg<const C&> : ProxyArg<C> {};
-template<> struct ProxyArg<StringParam> : ProxyArg<String::Ref> {};
-template<class C> struct ProxyArg<LocalRef<C>> : ProxyArg<typename C::Ref> {};
-
-// ProxyNativeCall implements the functor object that is passed to OnNativeCall
-template<class Impl, class Owner, bool IsStatic,
- bool HasThisArg /* has instance/class local ref in the call */,
- typename... Args>
-class ProxyNativeCall : public AbstractCall
-{
- // "this arg" refers to the Class::LocalRef (for static methods) or
- // Owner::LocalRef (for instance methods) that we optionally (as indicated
- // by HasThisArg) pass into the destination C++ function.
- typedef typename mozilla::Conditional<IsStatic,
- Class, Owner>::Type ThisArgClass;
- typedef typename mozilla::Conditional<IsStatic,
- jclass, jobject>::Type ThisArgJNIType;
-
- // Type signature of the destination C++ function, which matches the
- // Method template parameter in NativeStubImpl::Wrap.
- typedef typename mozilla::Conditional<IsStatic,
- typename mozilla::Conditional<HasThisArg,
- void (*) (const Class::LocalRef&, Args...),
- void (*) (Args...)>::Type,
- typename mozilla::Conditional<HasThisArg,
- void (Impl::*) (const typename Owner::LocalRef&, Args...),
- void (Impl::*) (Args...)>::Type>::Type NativeCallType;
-
- // Destination C++ function.
- NativeCallType mNativeCall;
- // Saved this arg.
- typename ThisArgClass::GlobalRef mThisArg;
- // Saved arguments.
- mozilla::Tuple<typename ProxyArg<Args>::Type...> mArgs;
-
- // We cannot use IsStatic and HasThisArg directly (without going through
- // extra hoops) because GCC complains about invalid overloads, so we use
- // another pair of template parameters, Static and ThisArg.
-
- template<bool Static, bool ThisArg, size_t... Indices>
- typename mozilla::EnableIf<Static && ThisArg, void>::Type
- Call(const Class::LocalRef& cls,
- mozilla::IndexSequence<Indices...>) const
- {
- (*mNativeCall)(cls, mozilla::Get<Indices>(mArgs)...);
- }
-
- template<bool Static, bool ThisArg, size_t... Indices>
- typename mozilla::EnableIf<Static && !ThisArg, void>::Type
- Call(const Class::LocalRef& cls,
- mozilla::IndexSequence<Indices...>) const
- {
- (*mNativeCall)(mozilla::Get<Indices>(mArgs)...);
- }
-
- template<bool Static, bool ThisArg, size_t... Indices>
- typename mozilla::EnableIf<!Static && ThisArg, void>::Type
- Call(const typename Owner::LocalRef& inst,
- mozilla::IndexSequence<Indices...>) const
- {
- Impl* const impl = NativePtr<Impl>::Get(inst);
- MOZ_CATCH_JNI_EXCEPTION(inst.Env());
- (impl->*mNativeCall)(inst, mozilla::Get<Indices>(mArgs)...);
- }
-
- template<bool Static, bool ThisArg, size_t... Indices>
- typename mozilla::EnableIf<!Static && !ThisArg, void>::Type
- Call(const typename Owner::LocalRef& inst,
- mozilla::IndexSequence<Indices...>) const
- {
- Impl* const impl = NativePtr<Impl>::Get(inst);
- MOZ_CATCH_JNI_EXCEPTION(inst.Env());
- (impl->*mNativeCall)(mozilla::Get<Indices>(mArgs)...);
- }
-
- template<size_t... Indices>
- void Clear(JNIEnv* env, mozilla::IndexSequence<Indices...>)
- {
- int dummy[] = {
- (ProxyArg<Args>::Clear(env, Get<Indices>(mArgs)), 0)...
- };
- mozilla::Unused << dummy;
- }
-
-public:
- // The class that implements the call target.
- typedef Impl TargetClass;
- typedef typename ThisArgClass::Param ThisArgType;
-
- static const bool isStatic = IsStatic;
-
- ProxyNativeCall(ThisArgJNIType thisArg,
- NativeCallType nativeCall,
- JNIEnv* env,
- typename ProxyArg<Args>::JNIType... args)
- : mNativeCall(nativeCall)
- , mThisArg(env, ThisArgClass::Ref::From(thisArg))
- , mArgs(ProxyArg<Args>::From(env, args)...)
- {}
-
- ProxyNativeCall(ProxyNativeCall&&) = default;
- ProxyNativeCall(const ProxyNativeCall&) = default;
-
- // Get class ref for static calls or object ref for instance calls.
- typename ThisArgClass::Param GetThisArg() const { return mThisArg; }
-
- // Return if target is the given function pointer / pointer-to-member.
- // Because we can only compare pointers of the same type, we use a
- // templated overload that is chosen only if given a different type of
- // pointer than our target pointer type.
- bool IsTarget(NativeCallType call) const { return call == mNativeCall; }
- template<typename T> bool IsTarget(T&&) const { return false; }
-
- // Redirect the call to another function / class member with the same
- // signature as the original target. Crash if given a wrong signature.
- void SetTarget(NativeCallType call) { mNativeCall = call; }
- template<typename T> void SetTarget(T&&) const { MOZ_CRASH(); }
-
- void operator()() override
- {
- JNIEnv* const env = GetEnvForThread();
- typename ThisArgClass::LocalRef thisArg(env, mThisArg);
- Call<IsStatic, HasThisArg>(
- thisArg, typename IndexSequenceFor<Args...>::Type());
-
- // Clear all saved global refs. We do this after the call is invoked,
- // and not inside the destructor because we already have a JNIEnv here,
- // so it's more efficient to clear out the saved args here. The
- // downside is that the call can only be invoked once.
- Clear(env, typename IndexSequenceFor<Args...>::Type());
- mThisArg.Clear(env);
- }
-};
-
-template<class Impl, bool HasThisArg, typename... Args>
-struct Dispatcher
-{
- template<class Traits, bool IsStatic = Traits::isStatic,
- typename... ProxyArgs>
- static typename EnableIf<
- Traits::dispatchTarget == DispatchTarget::PROXY, void>::Type
- Run(ProxyArgs&&... args)
- {
- Impl::OnNativeCall(ProxyNativeCall<
- Impl, typename Traits::Owner, IsStatic,
- HasThisArg, Args...>(Forward<ProxyArgs>(args)...));
- }
-
- template<class Traits, bool IsStatic = Traits::isStatic,
- typename ThisArg, typename... ProxyArgs>
- static typename EnableIf<
- Traits::dispatchTarget == DispatchTarget::GECKO, void>::Type
- Run(ThisArg thisArg, ProxyArgs&&... args)
- {
- // For a static method, do not forward the "this arg" (i.e. the class
- // local ref) if the implementation does not request it. This saves us
- // a pair of calls to add/delete global ref.
- DispatchToGeckoThread(MakeUnique<ProxyNativeCall<
- Impl, typename Traits::Owner, IsStatic, HasThisArg,
- Args...>>(HasThisArg || !IsStatic ? thisArg : nullptr,
- Forward<ProxyArgs>(args)...));
- }
-
- template<class Traits, bool IsStatic = false, typename... ProxyArgs>
- static typename EnableIf<
- Traits::dispatchTarget == DispatchTarget::CURRENT, void>::Type
- Run(ProxyArgs&&... args) {}
-};
-
-} // namespace detail
-
-// Wrapper methods that convert arguments from the JNI types to the native
-// types, e.g. from jobject to jni::Object::Ref. For instance methods, the
-// wrapper methods also convert calls to calls on objects.
-//
-// We need specialization for static/non-static because the two have different
-// signatures (jobject vs jclass and Impl::*Method vs *Method).
-// We need specialization for return type, because void return type requires
-// us to not deal with the return value.
-
-// Bug 1207642 - Work around Dalvik bug by realigning stack on JNI entry
-#ifdef __i386__
-#define MOZ_JNICALL JNICALL __attribute__((force_align_arg_pointer))
-#else
-#define MOZ_JNICALL JNICALL
-#endif
-
-template<class Traits, class Impl, class Args = typename Traits::Args>
-class NativeStub;
-
-template<class Traits, class Impl, typename... Args>
-class NativeStub<Traits, Impl, jni::Args<Args...>>
-{
- using Owner = typename Traits::Owner;
- using ReturnType = typename Traits::ReturnType;
-
- static constexpr bool isStatic = Traits::isStatic;
- static constexpr bool isVoid = mozilla::IsVoid<ReturnType>::value;
-
- struct VoidType { using JNIType = void; };
- using ReturnJNIType = typename Conditional<
- isVoid, VoidType, TypeAdapter<ReturnType>>::Type::JNIType;
-
- using ReturnTypeForNonVoidInstance = typename Conditional<
- !isStatic && !isVoid, ReturnType, VoidType>::Type;
- using ReturnTypeForVoidInstance = typename Conditional<
- !isStatic && isVoid, ReturnType, VoidType&>::Type;
- using ReturnTypeForNonVoidStatic = typename Conditional<
- isStatic && !isVoid, ReturnType, VoidType>::Type;
- using ReturnTypeForVoidStatic = typename Conditional<
- isStatic && isVoid, ReturnType, VoidType&>::Type;
-
- static_assert(Traits::dispatchTarget == DispatchTarget::CURRENT || isVoid,
- "Dispatched calls must have void return type");
-
-public:
- // Non-void instance method
- template<ReturnTypeForNonVoidInstance (Impl::*Method) (Args...)>
- static MOZ_JNICALL ReturnJNIType
- Wrap(JNIEnv* env, jobject instance,
- typename TypeAdapter<Args>::JNIType... args)
- {
- MOZ_ASSERT_JNI_THREAD(Traits::callingThread);
-
- Impl* const impl = NativePtr<Impl>::Get(env, instance);
- if (!impl) {
- // There is a pending JNI exception at this point.
- return ReturnJNIType();
- }
- return TypeAdapter<ReturnType>::FromNative(env,
- (impl->*Method)(TypeAdapter<Args>::ToNative(env, args)...));
- }
-
- // Non-void instance method with instance reference
- template<ReturnTypeForNonVoidInstance (Impl::*Method)
- (const typename Owner::LocalRef&, Args...)>
- static MOZ_JNICALL ReturnJNIType
- Wrap(JNIEnv* env, jobject instance,
- typename TypeAdapter<Args>::JNIType... args)
- {
- MOZ_ASSERT_JNI_THREAD(Traits::callingThread);
-
- Impl* const impl = NativePtr<Impl>::Get(env, instance);
- if (!impl) {
- // There is a pending JNI exception at this point.
- return ReturnJNIType();
- }
- auto self = Owner::LocalRef::Adopt(env, instance);
- const auto res = TypeAdapter<ReturnType>::FromNative(env,
- (impl->*Method)(self, TypeAdapter<Args>::ToNative(env, args)...));
- self.Forget();
- return res;
- }
-
- // Void instance method
- template<ReturnTypeForVoidInstance (Impl::*Method) (Args...)>
- static MOZ_JNICALL void
- Wrap(JNIEnv* env, jobject instance,
- typename TypeAdapter<Args>::JNIType... args)
- {
- MOZ_ASSERT_JNI_THREAD(Traits::callingThread);
-
- if (Traits::dispatchTarget != DispatchTarget::CURRENT) {
- Dispatcher<Impl, /* HasThisArg */ false, Args...>::
- template Run<Traits>(instance, Method, env, args...);
- return;
- }
-
- Impl* const impl = NativePtr<Impl>::Get(env, instance);
- if (!impl) {
- // There is a pending JNI exception at this point.
- return;
- }
- (impl->*Method)(TypeAdapter<Args>::ToNative(env, args)...);
- }
-
- // Void instance method with instance reference
- template<ReturnTypeForVoidInstance (Impl::*Method)
- (const typename Owner::LocalRef&, Args...)>
- static MOZ_JNICALL void
- Wrap(JNIEnv* env, jobject instance,
- typename TypeAdapter<Args>::JNIType... args)
- {
- MOZ_ASSERT_JNI_THREAD(Traits::callingThread);
-
- if (Traits::dispatchTarget != DispatchTarget::CURRENT) {
- Dispatcher<Impl, /* HasThisArg */ true, Args...>::
- template Run<Traits>(instance, Method, env, args...);
- return;
- }
-
- Impl* const impl = NativePtr<Impl>::Get(env, instance);
- if (!impl) {
- // There is a pending JNI exception at this point.
- return;
- }
- auto self = Owner::LocalRef::Adopt(env, instance);
- (impl->*Method)(self, TypeAdapter<Args>::ToNative(env, args)...);
- self.Forget();
- }
-
- // Overload for DisposeNative
- template<ReturnTypeForVoidInstance (*DisposeNative)
- (const typename Owner::LocalRef&)>
- static MOZ_JNICALL void
- Wrap(JNIEnv* env, jobject instance)
- {
- MOZ_ASSERT_JNI_THREAD(Traits::callingThread);
-
- if (Traits::dispatchTarget != DispatchTarget::CURRENT) {
- using LocalRef = typename Owner::LocalRef;
- Dispatcher<Impl, /* HasThisArg */ false, const LocalRef&>::
- template Run<Traits, /* IsStatic */ true>(
- /* ThisArg */ nullptr, DisposeNative, env, instance);
- return;
- }
-
- auto self = Owner::LocalRef::Adopt(env, instance);
- (Impl::DisposeNative)(self);
- self.Forget();
- }
-
- // Non-void static method
- template<ReturnTypeForNonVoidStatic (*Method) (Args...)>
- static MOZ_JNICALL ReturnJNIType
- Wrap(JNIEnv* env, jclass, typename TypeAdapter<Args>::JNIType... args)
- {
- MOZ_ASSERT_JNI_THREAD(Traits::callingThread);
-
- return TypeAdapter<ReturnType>::FromNative(env,
- (*Method)(TypeAdapter<Args>::ToNative(env, args)...));
- }
-
- // Non-void static method with class reference
- template<ReturnTypeForNonVoidStatic (*Method)
- (const Class::LocalRef&, Args...)>
- static MOZ_JNICALL ReturnJNIType
- Wrap(JNIEnv* env, jclass cls, typename TypeAdapter<Args>::JNIType... args)
- {
- MOZ_ASSERT_JNI_THREAD(Traits::callingThread);
-
- auto clazz = Class::LocalRef::Adopt(env, cls);
- const auto res = TypeAdapter<ReturnType>::FromNative(env,
- (*Method)(clazz, TypeAdapter<Args>::ToNative(env, args)...));
- clazz.Forget();
- return res;
- }
-
- // Void static method
- template<ReturnTypeForVoidStatic (*Method) (Args...)>
- static MOZ_JNICALL void
- Wrap(JNIEnv* env, jclass cls, typename TypeAdapter<Args>::JNIType... args)
- {
- MOZ_ASSERT_JNI_THREAD(Traits::callingThread);
-
- if (Traits::dispatchTarget != DispatchTarget::CURRENT) {
- Dispatcher<Impl, /* HasThisArg */ false, Args...>::
- template Run<Traits>(cls, Method, env, args...);
- return;
- }
-
- (*Method)(TypeAdapter<Args>::ToNative(env, args)...);
- }
-
- // Void static method with class reference
- template<ReturnTypeForVoidStatic (*Method)
- (const Class::LocalRef&, Args...)>
- static MOZ_JNICALL void
- Wrap(JNIEnv* env, jclass cls, typename TypeAdapter<Args>::JNIType... args)
- {
- MOZ_ASSERT_JNI_THREAD(Traits::callingThread);
-
- if (Traits::dispatchTarget != DispatchTarget::CURRENT) {
- Dispatcher<Impl, /* HasThisArg */ true, Args...>::
- template Run<Traits>(cls, Method, env, args...);
- return;
- }
-
- auto clazz = Class::LocalRef::Adopt(env, cls);
- (*Method)(clazz, TypeAdapter<Args>::ToNative(env, args)...);
- clazz.Forget();
- }
-};
-
-// Generate a JNINativeMethod from a native
-// method's traits class and a wrapped stub.
-template<class Traits, typename Ret, typename... Args>
-constexpr JNINativeMethod MakeNativeMethod(MOZ_JNICALL Ret (*stub)(JNIEnv*, Args...))
-{
- return {
- Traits::name,
- Traits::signature,
- reinterpret_cast<void*>(stub)
- };
-}
-
-// Class inherited by implementing class.
-template<class Cls, class Impl>
-class NativeImpl
-{
- typedef typename Cls::template Natives<Impl> Natives;
-
- static bool sInited;
-
-public:
- static void Init() {
- if (sInited) {
- return;
- }
- const auto& ctx = typename Cls::Context();
- ctx.Env()->RegisterNatives(
- ctx.ClassRef(), Natives::methods,
- sizeof(Natives::methods) / sizeof(Natives::methods[0]));
- MOZ_CATCH_JNI_EXCEPTION(ctx.Env());
- sInited = true;
- }
-
-protected:
-
- // Associate a C++ instance with a Java instance.
- static void AttachNative(const typename Cls::LocalRef& instance,
- SupportsWeakPtr<Impl>* ptr)
- {
- static_assert(mozilla::IsBaseOf<SupportsWeakPtr<Impl>, Impl>::value,
- "Attach with UniquePtr&& when not using WeakPtr");
- return NativePtr<Impl>::Set(instance, static_cast<Impl*>(ptr));
- }
-
- static void AttachNative(const typename Cls::LocalRef& instance,
- UniquePtr<Impl>&& ptr)
- {
- static_assert(!mozilla::IsBaseOf<SupportsWeakPtr<Impl>, Impl>::value,
- "Attach with SupportsWeakPtr* when using WeakPtr");
- return NativePtr<Impl>::Set(instance, mozilla::Move(ptr));
- }
-
- // Get the C++ instance associated with a Java instance.
- // There is always a pending exception if the return value is nullptr.
- static Impl* GetNative(const typename Cls::LocalRef& instance) {
- return NativePtr<Impl>::Get(instance);
- }
-
- static void DisposeNative(const typename Cls::LocalRef& instance) {
- NativePtr<Impl>::Clear(instance);
- }
-
- NativeImpl() {
- // Initialize on creation if not already initialized.
- Init();
- }
-};
-
-// Define static member.
-template<class C, class I>
-bool NativeImpl<C, I>::sInited;
-
-} // namespace jni
-} // namespace mozilla
-
-#endif // mozilla_jni_Natives_h__
diff --git a/widget/android/jni/Refs.h b/widget/android/jni/Refs.h
deleted file mode 100644
index 9f54ee5cd..000000000
--- a/widget/android/jni/Refs.h
+++ /dev/null
@@ -1,953 +0,0 @@
-#ifndef mozilla_jni_Refs_h__
-#define mozilla_jni_Refs_h__
-
-#include <jni.h>
-
-#include "mozilla/Move.h"
-#include "mozilla/jni/Utils.h"
-
-#include "nsError.h" // for nsresult
-#include "nsString.h"
-#include "nsTArray.h"
-
-namespace mozilla {
-namespace jni {
-
-// Wrapped object reference (e.g. jobject, jclass, etc...)
-template<class Cls, typename JNIType> class Ref;
-// Represents a calling context for JNI methods.
-template<class Cls, typename JNIType> class Context;
-// Wrapped local reference that inherits from Ref.
-template<class Cls> class LocalRef;
-// Wrapped global reference that inherits from Ref.
-template<class Cls> class GlobalRef;
-// Wrapped dangling reference that's owned by someone else.
-template<class Cls> class DependentRef;
-
-
-// Class to hold the native types of a method's arguments.
-// For example, if a method has signature (ILjava/lang/String;)V,
-// its arguments class would be jni::Args<int32_t, jni::String::Param>
-template<typename...>
-struct Args {};
-
-
-class Object;
-
-// Base class for Ref and its specializations.
-template<class Cls, typename Type>
-class Ref
-{
- template<class C, typename T> friend class Ref;
-
- using Self = Ref<Cls, Type>;
- using bool_type = void (Self::*)() const;
- void non_null_reference() const {}
-
- // A Cls-derivative that allows copying
- // (e.g. when acting as a return value).
- struct CopyableCtx : public Context<Cls, Type>
- {
- CopyableCtx(JNIEnv* env, Type instance)
- : Context<Cls, Type>(env, instance)
- {}
-
- CopyableCtx(const CopyableCtx& cls)
- : Context<Cls, Type>(cls.Env(), cls.Get())
- {}
- };
-
- // Private copy constructor so that there's no danger of assigning a
- // temporary LocalRef/GlobalRef to a Ref, and potentially use the Ref
- // after the source had been freed.
- Ref(const Ref&) = default;
-
-protected:
- static JNIEnv* FindEnv()
- {
- return Cls::callingThread == CallingThread::GECKO ?
- GetGeckoThreadEnv() : GetEnvForThread();
- }
-
- Type mInstance;
-
- // Protected jobject constructor because outside code should be using
- // Ref::From. Using Ref::From makes it very easy to see which code is using
- // raw JNI types for future refactoring.
- explicit Ref(Type instance) : mInstance(instance) {}
-
-public:
- using JNIType = Type;
-
- // Construct a Ref form a raw JNI reference.
- static Ref<Cls, Type> From(JNIType obj)
- {
- return Ref<Cls, Type>(obj);
- }
-
- // Construct a Ref form a generic object reference.
- static Ref<Cls, Type> From(const Ref<Object, jobject>& obj)
- {
- return Ref<Cls, Type>(JNIType(obj.Get()));
- }
-
- MOZ_IMPLICIT Ref(decltype(nullptr)) : mInstance(nullptr) {}
-
- // Get the raw JNI reference.
- JNIType Get() const
- {
- return mInstance;
- }
-
- bool operator==(const Ref& other) const
- {
- // Treat two references of the same object as being the same.
- return mInstance == other.mInstance || JNI_FALSE !=
- FindEnv()->IsSameObject(mInstance, other.mInstance);
- }
-
- bool operator!=(const Ref& other) const
- {
- return !operator==(other);
- }
-
- bool operator==(decltype(nullptr)) const
- {
- return !mInstance;
- }
-
- bool operator!=(decltype(nullptr)) const
- {
- return !!mInstance;
- }
-
- CopyableCtx operator->() const
- {
- return CopyableCtx(FindEnv(), mInstance);
- }
-
- // Any ref can be cast to an object ref.
- operator Ref<Object, jobject>() const
- {
- return Ref<Object, jobject>(mInstance);
- }
-
- // Null checking (e.g. !!ref) using the safe-bool idiom.
- operator bool_type() const
- {
- return mInstance ? &Self::non_null_reference : nullptr;
- }
-
- // We don't allow implicit conversion to jobject because that can lead
- // to easy mistakes such as assigning a temporary LocalRef to a jobject,
- // and using the jobject after the LocalRef has been freed.
-
- // We don't allow explicit conversion, to make outside code use Ref::Get.
- // Using Ref::Get makes it very easy to see which code is using raw JNI
- // types to make future refactoring easier.
-
- // operator JNIType() const = delete;
-};
-
-
-// Represents a calling context for JNI methods.
-template<class Cls, typename Type>
-class Context : public Ref<Cls, Type>
-{
- using Ref = jni::Ref<Cls, Type>;
-
- static jclass sClassRef; // global reference
-
-protected:
- JNIEnv* const mEnv;
-
-public:
- static jclass RawClassRef()
- {
- return sClassRef;
- }
-
- Context()
- : Ref(nullptr)
- , mEnv(Ref::FindEnv())
- {}
-
- Context(JNIEnv* env, Type instance)
- : Ref(instance)
- , mEnv(env)
- {}
-
- jclass ClassRef() const
- {
- if (!sClassRef) {
- const jclass cls = GetClassRef(mEnv, Cls::name);
- sClassRef = jclass(mEnv->NewGlobalRef(cls));
- mEnv->DeleteLocalRef(cls);
- }
- return sClassRef;
- }
-
- JNIEnv* Env() const
- {
- return mEnv;
- }
-
- bool operator==(const Ref& other) const
- {
- // Treat two references of the same object as being the same.
- return Ref::mInstance == other.mInstance || JNI_FALSE !=
- mEnv->IsSameObject(Ref::mInstance, other.mInstance);
- }
-
- bool operator!=(const Ref& other) const
- {
- return !operator==(other);
- }
-
- bool operator==(decltype(nullptr)) const
- {
- return !Ref::mInstance;
- }
-
- bool operator!=(decltype(nullptr)) const
- {
- return !!Ref::mInstance;
- }
-
- Cls operator->() const
- {
- MOZ_ASSERT(Ref::mInstance, "Null jobject");
- return Cls(*this);
- }
-};
-
-
-template<class Cls, typename Type = jobject>
-class ObjectBase
-{
-protected:
- const jni::Context<Cls, Type>& mCtx;
-
- jclass ClassRef() const { return mCtx.ClassRef(); }
- JNIEnv* Env() const { return mCtx.Env(); }
- Type Instance() const { return mCtx.Get(); }
-
-public:
- using Ref = jni::Ref<Cls, Type>;
- using Context = jni::Context<Cls, Type>;
- using LocalRef = jni::LocalRef<Cls>;
- using GlobalRef = jni::GlobalRef<Cls>;
- using Param = const Ref&;
-
- static const CallingThread callingThread = CallingThread::ANY;
- static const char name[];
-
- explicit ObjectBase(const Context& ctx) : mCtx(ctx) {}
-
- Cls* operator->()
- {
- return static_cast<Cls*>(this);
- }
-};
-
-// Binding for a plain jobject.
-class Object : public ObjectBase<Object, jobject>
-{
-public:
- explicit Object(const Context& ctx) : ObjectBase<Object, jobject>(ctx) {}
-};
-
-// Binding for a built-in object reference other than jobject.
-template<typename T>
-class TypedObject : public ObjectBase<TypedObject<T>, T>
-{
-public:
- explicit TypedObject(const Context<TypedObject<T>, T>& ctx)
- : ObjectBase<TypedObject<T>, T>(ctx)
- {}
-};
-
-
-// Define bindings for built-in types.
-using String = TypedObject<jstring>;
-using Class = TypedObject<jclass>;
-using Throwable = TypedObject<jthrowable>;
-
-using BooleanArray = TypedObject<jbooleanArray>;
-using ByteArray = TypedObject<jbyteArray>;
-using CharArray = TypedObject<jcharArray>;
-using ShortArray = TypedObject<jshortArray>;
-using IntArray = TypedObject<jintArray>;
-using LongArray = TypedObject<jlongArray>;
-using FloatArray = TypedObject<jfloatArray>;
-using DoubleArray = TypedObject<jdoubleArray>;
-using ObjectArray = TypedObject<jobjectArray>;
-
-
-namespace detail {
-
-// See explanation in LocalRef.
-template<class Cls> struct GenericObject { using Type = Object; };
-template<> struct GenericObject<Object>
-{
- struct Type {
- using Ref = jni::Ref<Type, jobject>;
- using Context = jni::Context<Type, jobject>;
- };
-};
-template<class Cls> struct GenericLocalRef
-{
- template<class C> struct Type : jni::Object {};
-};
-template<> struct GenericLocalRef<Object>
-{
- template<class C> using Type = jni::LocalRef<C>;
-};
-
-} // namespace
-
-template<class Cls>
-class LocalRef : public Cls::Context
-{
- template<class C> friend class LocalRef;
-
- using Ctx = typename Cls::Context;
- using Ref = typename Cls::Ref;
- using JNIType = typename Ref::JNIType;
-
- // In order to be able to convert LocalRef<Object> to LocalRef<Cls>, we
- // need constructors and copy assignment operators that take in a
- // LocalRef<Object> argument. However, if Cls *is* Object, we would have
- // duplicated constructors and operators with LocalRef<Object> arguments. To
- // avoid this conflict, we use GenericObject, which is defined as Object for
- // LocalRef<non-Object> and defined as a dummy class for LocalRef<Object>.
- using GenericObject = typename detail::GenericObject<Cls>::Type;
-
- // Similarly, GenericLocalRef is useed to convert LocalRef<Cls> to,
- // LocalRef<Object>. It's defined as LocalRef<C> for Cls == Object,
- // and defined as a dummy template class for Cls != Object.
- template<class C> using GenericLocalRef
- = typename detail::GenericLocalRef<Cls>::template Type<C>;
-
- static JNIType NewLocalRef(JNIEnv* env, JNIType obj)
- {
- return JNIType(obj ? env->NewLocalRef(obj) : nullptr);
- }
-
- LocalRef(JNIEnv* env, JNIType instance) : Ctx(env, instance) {}
-
- LocalRef& swap(LocalRef& other)
- {
- auto instance = other.mInstance;
- other.mInstance = Ctx::mInstance;
- Ctx::mInstance = instance;
- return *this;
- }
-
-public:
- // Construct a LocalRef from a raw JNI local reference. Unlike Ref::From,
- // LocalRef::Adopt returns a LocalRef that will delete the local reference
- // when going out of scope.
- static LocalRef Adopt(JNIType instance)
- {
- return LocalRef(Ref::FindEnv(), instance);
- }
-
- static LocalRef Adopt(JNIEnv* env, JNIType instance)
- {
- return LocalRef(env, instance);
- }
-
- // Copy constructor.
- LocalRef(const LocalRef<Cls>& ref)
- : Ctx(ref.mEnv, NewLocalRef(ref.mEnv, ref.mInstance))
- {}
-
- // Move constructor.
- LocalRef(LocalRef<Cls>&& ref)
- : Ctx(ref.mEnv, ref.mInstance)
- {
- ref.mInstance = nullptr;
- }
-
- explicit LocalRef(JNIEnv* env = Ref::FindEnv())
- : Ctx(env, nullptr)
- {}
-
- // Construct a LocalRef from any Ref,
- // which means creating a new local reference.
- MOZ_IMPLICIT LocalRef(const Ref& ref)
- : Ctx(Ref::FindEnv(), nullptr)
- {
- Ctx::mInstance = NewLocalRef(Ctx::mEnv, ref.Get());
- }
-
- LocalRef(JNIEnv* env, const Ref& ref)
- : Ctx(env, NewLocalRef(env, ref.Get()))
- {}
-
- // Move a LocalRef<Object> into a LocalRef<Cls> without
- // creating/deleting local references.
- MOZ_IMPLICIT LocalRef(LocalRef<GenericObject>&& ref)
- : Ctx(ref.mEnv, JNIType(ref.mInstance))
- {
- ref.mInstance = nullptr;
- }
-
- template<class C>
- MOZ_IMPLICIT LocalRef(GenericLocalRef<C>&& ref)
- : Ctx(ref.mEnv, ref.mInstance)
- {
- ref.mInstance = nullptr;
- }
-
- // Implicitly converts nullptr to LocalRef.
- MOZ_IMPLICIT LocalRef(decltype(nullptr))
- : Ctx(Ref::FindEnv(), nullptr)
- {}
-
- ~LocalRef()
- {
- if (Ctx::mInstance) {
- Ctx::mEnv->DeleteLocalRef(Ctx::mInstance);
- Ctx::mInstance = nullptr;
- }
- }
-
- // Get the raw JNI reference that can be used as a return value.
- // Returns the same JNI type (jobject, jstring, etc.) as the underlying Ref.
- typename Ref::JNIType Forget()
- {
- const auto obj = Ctx::Get();
- Ctx::mInstance = nullptr;
- return obj;
- }
-
- LocalRef<Cls>& operator=(LocalRef<Cls> ref)
- {
- return swap(ref);
- }
-
- LocalRef<Cls>& operator=(const Ref& ref)
- {
- LocalRef<Cls> newRef(Ctx::mEnv, ref);
- return swap(newRef);
- }
-
- LocalRef<Cls>& operator=(LocalRef<GenericObject>&& ref)
- {
- LocalRef<Cls> newRef(mozilla::Move(ref));
- return swap(newRef);
- }
-
- template<class C>
- LocalRef<Cls>& operator=(GenericLocalRef<C>&& ref)
- {
- LocalRef<Cls> newRef(mozilla::Move(ref));
- return swap(newRef);
- }
-
- LocalRef<Cls>& operator=(decltype(nullptr))
- {
- LocalRef<Cls> newRef(Ctx::mEnv, nullptr);
- return swap(newRef);
- }
-};
-
-
-template<class Cls>
-class GlobalRef : public Cls::Ref
-{
- using Ref = typename Cls::Ref;
- using JNIType = typename Ref::JNIType;
-
- static JNIType NewGlobalRef(JNIEnv* env, JNIType instance)
- {
- return JNIType(instance ? env->NewGlobalRef(instance) : nullptr);
- }
-
- GlobalRef& swap(GlobalRef& other)
- {
- auto instance = other.mInstance;
- other.mInstance = Ref::mInstance;
- Ref::mInstance = instance;
- return *this;
- }
-
-public:
- GlobalRef()
- : Ref(nullptr)
- {}
-
- // Copy constructor
- GlobalRef(const GlobalRef& ref)
- : Ref(NewGlobalRef(GetEnvForThread(), ref.mInstance))
- {}
-
- // Move constructor
- GlobalRef(GlobalRef&& ref)
- : Ref(ref.mInstance)
- {
- ref.mInstance = nullptr;
- }
-
- MOZ_IMPLICIT GlobalRef(const Ref& ref)
- : Ref(NewGlobalRef(GetEnvForThread(), ref.Get()))
- {}
-
- GlobalRef(JNIEnv* env, const Ref& ref)
- : Ref(NewGlobalRef(env, ref.Get()))
- {}
-
- MOZ_IMPLICIT GlobalRef(const LocalRef<Cls>& ref)
- : Ref(NewGlobalRef(ref.Env(), ref.Get()))
- {}
-
- // Implicitly converts nullptr to GlobalRef.
- MOZ_IMPLICIT GlobalRef(decltype(nullptr))
- : Ref(nullptr)
- {}
-
- ~GlobalRef()
- {
- if (Ref::mInstance) {
- Clear(GetEnvForThread());
- }
- }
-
- // Get the raw JNI reference that can be used as a return value.
- // Returns the same JNI type (jobject, jstring, etc.) as the underlying Ref.
- typename Ref::JNIType Forget()
- {
- const auto obj = Ref::Get();
- Ref::mInstance = nullptr;
- return obj;
- }
-
- void Clear(JNIEnv* env)
- {
- if (Ref::mInstance) {
- env->DeleteGlobalRef(Ref::mInstance);
- Ref::mInstance = nullptr;
- }
- }
-
- GlobalRef<Cls>& operator=(GlobalRef<Cls> ref)
- {
- return swap(ref);
- }
-
- GlobalRef<Cls>& operator=(const Ref& ref)
- {
- GlobalRef<Cls> newRef(ref);
- return swap(newRef);
- }
-
- GlobalRef<Cls>& operator=(const LocalRef<Cls>& ref)
- {
- GlobalRef<Cls> newRef(ref);
- return swap(newRef);
- }
-
- GlobalRef<Cls>& operator=(decltype(nullptr))
- {
- GlobalRef<Cls> newRef(nullptr);
- return swap(newRef);
- }
-};
-
-
-template<class Cls>
-class DependentRef : public Cls::Ref
-{
- using Ref = typename Cls::Ref;
-
-public:
- DependentRef(typename Ref::JNIType instance)
- : Ref(instance)
- {}
-
- DependentRef(const DependentRef& ref)
- : Ref(ref.Get())
- {}
-};
-
-
-class StringParam;
-
-template<>
-class TypedObject<jstring> : public ObjectBase<TypedObject<jstring>, jstring>
-{
- using Base = ObjectBase<TypedObject<jstring>, jstring>;
-
-public:
- using Param = const StringParam&;
-
- explicit TypedObject(const Context& ctx) : Base(ctx) {}
-
- size_t Length() const
- {
- const size_t ret = Base::Env()->GetStringLength(Base::Instance());
- MOZ_CATCH_JNI_EXCEPTION(Base::Env());
- return ret;
- }
-
- nsString ToString() const
- {
- const jchar* const str = Base::Env()->GetStringChars(
- Base::Instance(), nullptr);
- const jsize len = Base::Env()->GetStringLength(Base::Instance());
-
- nsString result(reinterpret_cast<const char16_t*>(str), len);
- Base::Env()->ReleaseStringChars(Base::Instance(), str);
- return result;
- }
-
- nsCString ToCString() const
- {
- return NS_ConvertUTF16toUTF8(ToString());
- }
-
- // Convert jstring to a nsString.
- operator nsString() const
- {
- return ToString();
- }
-
- // Convert jstring to a nsCString.
- operator nsCString() const
- {
- return ToCString();
- }
-};
-
-// Define a custom parameter type for String,
-// which accepts both String::Ref and nsAString/nsACString
-class StringParam : public String::Ref
-{
- using Ref = String::Ref;
-
-private:
- // Not null if we should delete ref on destruction.
- JNIEnv* const mEnv;
-
- static jstring GetString(JNIEnv* env, const nsAString& str)
- {
- const jstring result = env->NewString(
- reinterpret_cast<const jchar*>(str.BeginReading()),
- str.Length());
- MOZ_CATCH_JNI_EXCEPTION(env);
- return result;
- }
-
-public:
- MOZ_IMPLICIT StringParam(decltype(nullptr))
- : Ref(nullptr)
- , mEnv(nullptr)
- {}
-
- MOZ_IMPLICIT StringParam(const Ref& ref)
- : Ref(ref.Get())
- , mEnv(nullptr)
- {}
-
- MOZ_IMPLICIT StringParam(const nsAString& str, JNIEnv* env = Ref::FindEnv())
- : Ref(GetString(env, str))
- , mEnv(env)
- {}
-
- MOZ_IMPLICIT StringParam(const char16_t* str, JNIEnv* env = Ref::FindEnv())
- : Ref(GetString(env, nsDependentString(str)))
- , mEnv(env)
- {}
-
- MOZ_IMPLICIT StringParam(const nsACString& str, JNIEnv* env = Ref::FindEnv())
- : Ref(GetString(env, NS_ConvertUTF8toUTF16(str)))
- , mEnv(env)
- {}
-
- MOZ_IMPLICIT StringParam(const char* str, JNIEnv* env = Ref::FindEnv())
- : Ref(GetString(env, NS_ConvertUTF8toUTF16(str)))
- , mEnv(env)
- {}
-
- StringParam(StringParam&& other)
- : Ref(other.Get())
- , mEnv(other.mEnv)
- {
- other.mInstance = nullptr;
- }
-
- ~StringParam()
- {
- if (mEnv && Get()) {
- mEnv->DeleteLocalRef(Get());
- }
- }
-
- operator String::LocalRef() const
- {
- // We can't return our existing ref because the returned
- // LocalRef could be freed first, so we need a new local ref.
- return String::LocalRef(mEnv ? mEnv : Ref::FindEnv(), *this);
- }
-};
-
-
-namespace detail {
- template<typename T> struct TypeAdapter;
-}
-
-// Ref specialization for arrays.
-template<typename JNIType, class ElementType>
-class ArrayRefBase : public ObjectBase<TypedObject<JNIType>, JNIType>
-{
- using Base = ObjectBase<TypedObject<JNIType>, JNIType>;
-
-public:
- explicit ArrayRefBase(const Context<TypedObject<JNIType>, JNIType>& ctx)
- : Base(ctx)
- {}
-
- static typename Base::LocalRef New(const ElementType* data, size_t length) {
- using JNIElemType = typename detail::TypeAdapter<ElementType>::JNIType;
- static_assert(sizeof(ElementType) == sizeof(JNIElemType),
- "Size of native type must match size of JNI type");
- JNIEnv* const jenv = mozilla::jni::GetEnvForThread();
- auto result =
- (jenv->*detail::TypeAdapter<ElementType>::NewArray)(length);
- MOZ_CATCH_JNI_EXCEPTION(jenv);
- (jenv->*detail::TypeAdapter<ElementType>::SetArray)(
- result, jsize(0), length,
- reinterpret_cast<const JNIElemType*>(data));
- MOZ_CATCH_JNI_EXCEPTION(jenv);
- return Base::LocalRef::Adopt(jenv, result);
- }
-
- size_t Length() const
- {
- const size_t ret = Base::Env()->GetArrayLength(Base::Instance());
- MOZ_CATCH_JNI_EXCEPTION(Base::Env());
- return ret;
- }
-
- ElementType GetElement(size_t index) const
- {
- using JNIElemType = typename detail::TypeAdapter<ElementType>::JNIType;
- static_assert(sizeof(ElementType) == sizeof(JNIElemType),
- "Size of native type must match size of JNI type");
-
- ElementType ret;
- (Base::Env()->*detail::TypeAdapter<ElementType>::GetArray)(
- Base::Instance(), jsize(index), 1,
- reinterpret_cast<JNIElemType*>(&ret));
- MOZ_CATCH_JNI_EXCEPTION(Base::Env());
- return ret;
- }
-
- nsTArray<ElementType> GetElements() const
- {
- using JNIElemType = typename detail::TypeAdapter<ElementType>::JNIType;
- static_assert(sizeof(ElementType) == sizeof(JNIElemType),
- "Size of native type must match size of JNI type");
-
- const jsize len = size_t(Base::Env()->GetArrayLength(Base::Instance()));
-
- nsTArray<ElementType> array((size_t(len)));
- array.SetLength(size_t(len));
- (Base::Env()->*detail::TypeAdapter<ElementType>::GetArray)(
- Base::Instance(), 0, len,
- reinterpret_cast<JNIElemType*>(array.Elements()));
- return array;
- }
-
- ElementType operator[](size_t index) const
- {
- return GetElement(index);
- }
-
- operator nsTArray<ElementType>() const
- {
- return GetElements();
- }
-};
-
-#define DEFINE_PRIMITIVE_ARRAY_REF(JNIType, ElementType) \
- template<> \
- class TypedObject<JNIType> : public ArrayRefBase<JNIType, ElementType> \
- { \
- public: \
- explicit TypedObject(const Context& ctx) \
- : ArrayRefBase<JNIType, ElementType>(ctx) \
- {} \
- }
-
-DEFINE_PRIMITIVE_ARRAY_REF(jbooleanArray, bool);
-DEFINE_PRIMITIVE_ARRAY_REF(jbyteArray, int8_t);
-DEFINE_PRIMITIVE_ARRAY_REF(jcharArray, char16_t);
-DEFINE_PRIMITIVE_ARRAY_REF(jshortArray, int16_t);
-DEFINE_PRIMITIVE_ARRAY_REF(jintArray, int32_t);
-DEFINE_PRIMITIVE_ARRAY_REF(jlongArray, int64_t);
-DEFINE_PRIMITIVE_ARRAY_REF(jfloatArray, float);
-DEFINE_PRIMITIVE_ARRAY_REF(jdoubleArray, double);
-
-#undef DEFINE_PRIMITIVE_ARRAY_REF
-
-
-class ByteBuffer : public ObjectBase<ByteBuffer, jobject>
-{
-public:
- explicit ByteBuffer(const Context& ctx)
- : ObjectBase<ByteBuffer, jobject>(ctx)
- {}
-
- static LocalRef New(void* data, size_t capacity)
- {
- JNIEnv* const env = GetEnvForThread();
- const auto ret = LocalRef::Adopt(
- env, env->NewDirectByteBuffer(data, jlong(capacity)));
- MOZ_CATCH_JNI_EXCEPTION(env);
- return ret;
- }
-
- void* Address()
- {
- void* const ret = Env()->GetDirectBufferAddress(Instance());
- MOZ_CATCH_JNI_EXCEPTION(Env());
- return ret;
- }
-
- size_t Capacity()
- {
- const size_t ret = size_t(Env()->GetDirectBufferCapacity(Instance()));
- MOZ_CATCH_JNI_EXCEPTION(Env());
- return ret;
- }
-};
-
-
-template<>
-class TypedObject<jobjectArray>
- : public ObjectBase<TypedObject<jobjectArray>, jobjectArray>
-{
- using Base = ObjectBase<TypedObject<jobjectArray>, jobjectArray>;
-
-public:
- explicit TypedObject(const Context& ctx) : Base(ctx) {}
-
- size_t Length() const
- {
- const size_t ret = Base::Env()->GetArrayLength(Base::Instance());
- MOZ_CATCH_JNI_EXCEPTION(Base::Env());
- return ret;
- }
-
- Object::LocalRef GetElement(size_t index) const
- {
- auto ret = Object::LocalRef::Adopt(
- Base::Env(), Base::Env()->GetObjectArrayElement(
- Base::Instance(), jsize(index)));
- MOZ_CATCH_JNI_EXCEPTION(Base::Env());
- return ret;
- }
-
- nsTArray<Object::LocalRef> GetElements() const
- {
- const jsize len = size_t(Base::Env()->GetArrayLength(Base::Instance()));
-
- nsTArray<Object::LocalRef> array((size_t(len)));
- for (jsize i = 0; i < len; i++) {
- array.AppendElement(Object::LocalRef::Adopt(
- Base::Env(), Base::Env()->GetObjectArrayElement(
- Base::Instance(), i)));
- MOZ_CATCH_JNI_EXCEPTION(Base::Env());
- }
- return array;
- }
-
- Object::LocalRef operator[](size_t index) const
- {
- return GetElement(index);
- }
-
- operator nsTArray<Object::LocalRef>() const
- {
- return GetElements();
- }
-
- void SetElement(size_t index, Object::Param element) const
- {
- Base::Env()->SetObjectArrayElement(
- Base::Instance(), jsize(index), element.Get());
- MOZ_CATCH_JNI_EXCEPTION(Base::Env());
- }
-};
-
-
-// Support conversion from LocalRef<T>* to LocalRef<Object>*:
-// LocalRef<Foo> foo;
-// Foo::GetFoo(&foo); // error because parameter type is LocalRef<Object>*.
-// Foo::GetFoo(ReturnTo(&foo)); // OK because ReturnTo converts the argument.
-template<class Cls>
-class ReturnToLocal
-{
-private:
- LocalRef<Cls>* const localRef;
- LocalRef<Object> objRef;
-
-public:
- explicit ReturnToLocal(LocalRef<Cls>* ref) : localRef(ref) {}
- operator LocalRef<Object>*() { return &objRef; }
-
- ~ReturnToLocal()
- {
- if (objRef) {
- *localRef = mozilla::Move(objRef);
- }
- }
-};
-
-template<class Cls>
-ReturnToLocal<Cls> ReturnTo(LocalRef<Cls>* ref)
-{
- return ReturnToLocal<Cls>(ref);
-}
-
-
-// Support conversion from GlobalRef<T>* to LocalRef<Object/T>*:
-// GlobalRef<Foo> foo;
-// Foo::GetFoo(&foo); // error because parameter type is LocalRef<Foo>*.
-// Foo::GetFoo(ReturnTo(&foo)); // OK because ReturnTo converts the argument.
-template<class Cls>
-class ReturnToGlobal
-{
-private:
- GlobalRef<Cls>* const globalRef;
- LocalRef<Object> objRef;
- LocalRef<Cls> clsRef;
-
-public:
- explicit ReturnToGlobal(GlobalRef<Cls>* ref) : globalRef(ref) {}
- operator LocalRef<Object>*() { return &objRef; }
- operator LocalRef<Cls>*() { return &clsRef; }
-
- ~ReturnToGlobal()
- {
- if (objRef) {
- *globalRef = (clsRef = mozilla::Move(objRef));
- } else if (clsRef) {
- *globalRef = clsRef;
- }
- }
-};
-
-template<class Cls>
-ReturnToGlobal<Cls> ReturnTo(GlobalRef<Cls>* ref)
-{
- return ReturnToGlobal<Cls>(ref);
-}
-
-} // namespace jni
-} // namespace mozilla
-
-#endif // mozilla_jni_Refs_h__
diff --git a/widget/android/jni/Types.h b/widget/android/jni/Types.h
deleted file mode 100644
index a083d3e50..000000000
--- a/widget/android/jni/Types.h
+++ /dev/null
@@ -1,140 +0,0 @@
-#ifndef mozilla_jni_Types_h__
-#define mozilla_jni_Types_h__
-
-#include <jni.h>
-
-#include "mozilla/jni/Refs.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.
-
-template<typename T> struct TypeAdapter;
-
-
-// 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
-
-template<class Cls> constexpr jobject
- (JNIEnv::*TypeAdapter<LocalRef<Cls>>::Call)(jobject, jmethodID, jvalue*) MOZ_JNICALL_ABI;
-template<class Cls> constexpr jobject
- (JNIEnv::*TypeAdapter<LocalRef<Cls>>::StaticCall)(jclass, jmethodID, jvalue*) 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>
-{};
-
-
-#define DEFINE_PRIMITIVE_TYPE_ADAPTER(NativeType, JNIType, JNIName) \
- \
- template<> struct TypeAdapter<NativeType> { \
- using JNI##Type = JNIType; \
- \
- static constexpr auto Call = &JNIEnv::Call ## JNIName ## MethodA; \
- static constexpr auto StaticCall = &JNIEnv::CallStatic ## JNIName ## MethodA; \
- static constexpr auto Get = &JNIEnv::Get ## JNIName ## Field; \
- static constexpr auto StaticGet = &JNIEnv::GetStatic ## JNIName ## Field; \
- static constexpr auto Set = &JNIEnv::Set ## JNIName ## Field; \
- static constexpr auto StaticSet = &JNIEnv::SetStatic ## JNIName ## Field; \
- static constexpr auto GetArray = &JNIEnv::Get ## JNIName ## ArrayRegion; \
- static constexpr auto SetArray = &JNIEnv::Set ## JNIName ## ArrayRegion; \
- static constexpr auto NewArray = &JNIEnv::New ## JNIName ## Array; \
- \
- static JNIType FromNative(JNIEnv*, NativeType val) { \
- return static_cast<JNIType>(val); \
- } \
- static NativeType ToNative(JNIEnv*, JNIType val) { \
- return static_cast<NativeType>(val); \
- } \
- }
-
-
-DEFINE_PRIMITIVE_TYPE_ADAPTER(bool, jboolean, Boolean);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(int8_t, jbyte, Byte);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(char16_t, jchar, Char);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(int16_t, jshort, Short);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(int32_t, jint, Int);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(int64_t, jlong, Long);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(float, jfloat, Float);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(double, jdouble, Double);
-
-#undef DEFINE_PRIMITIVE_TYPE_ADAPTER
-
-} // namespace detail
-
-using namespace detail;
-
-} // namespace jni
-} // namespace mozilla
-
-#endif // mozilla_jni_Types_h__
diff --git a/widget/android/jni/Utils.cpp b/widget/android/jni/Utils.cpp
deleted file mode 100644
index 919588851..000000000
--- a/widget/android/jni/Utils.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-#include "Utils.h"
-#include "Types.h"
-
-#include <android/log.h>
-#include <pthread.h>
-
-#include "mozilla/Assertions.h"
-
-#include "GeneratedJNIWrappers.h"
-#include "nsAppShell.h"
-
-namespace mozilla {
-namespace jni {
-
-namespace detail {
-
-#define DEFINE_PRIMITIVE_TYPE_ADAPTER(NativeType, JNIType, JNIName, ABIName) \
- \
- constexpr JNIType (JNIEnv::*TypeAdapter<NativeType>::Call) \
- (jobject, jmethodID, jvalue*) MOZ_JNICALL_ABI; \
- constexpr JNIType (JNIEnv::*TypeAdapter<NativeType>::StaticCall) \
- (jclass, jmethodID, jvalue*) MOZ_JNICALL_ABI; \
- constexpr JNIType (JNIEnv::*TypeAdapter<NativeType>::Get) \
- (jobject, jfieldID) ABIName; \
- constexpr JNIType (JNIEnv::*TypeAdapter<NativeType>::StaticGet) \
- (jclass, jfieldID) ABIName; \
- constexpr void (JNIEnv::*TypeAdapter<NativeType>::Set) \
- (jobject, jfieldID, JNIType) ABIName; \
- constexpr void (JNIEnv::*TypeAdapter<NativeType>::StaticSet) \
- (jclass, jfieldID, JNIType) ABIName; \
- constexpr void (JNIEnv::*TypeAdapter<NativeType>::GetArray) \
- (JNIType ## Array, jsize, jsize, JNIType*)
-
-DEFINE_PRIMITIVE_TYPE_ADAPTER(bool, jboolean, Boolean, /*nothing*/);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(int8_t, jbyte, Byte, /*nothing*/);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(char16_t, jchar, Char, /*nothing*/);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(int16_t, jshort, Short, /*nothing*/);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(int32_t, jint, Int, /*nothing*/);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(int64_t, jlong, Long, /*nothing*/);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(float, jfloat, Float, MOZ_JNICALL_ABI);
-DEFINE_PRIMITIVE_TYPE_ADAPTER(double, jdouble, Double, MOZ_JNICALL_ABI);
-
-#undef DEFINE_PRIMITIVE_TYPE_ADAPTER
-
-} // namespace detail
-
-template<> const char ObjectBase<Object, jobject>::name[] = "java/lang/Object";
-template<> const char ObjectBase<TypedObject<jstring>, jstring>::name[] = "java/lang/String";
-template<> const char ObjectBase<TypedObject<jclass>, jclass>::name[] = "java/lang/Class";
-template<> const char ObjectBase<TypedObject<jthrowable>, jthrowable>::name[] = "java/lang/Throwable";
-template<> const char ObjectBase<TypedObject<jbooleanArray>, jbooleanArray>::name[] = "[Z";
-template<> const char ObjectBase<TypedObject<jbyteArray>, jbyteArray>::name[] = "[B";
-template<> const char ObjectBase<TypedObject<jcharArray>, jcharArray>::name[] = "[C";
-template<> const char ObjectBase<TypedObject<jshortArray>, jshortArray>::name[] = "[S";
-template<> const char ObjectBase<TypedObject<jintArray>, jintArray>::name[] = "[I";
-template<> const char ObjectBase<TypedObject<jlongArray>, jlongArray>::name[] = "[J";
-template<> const char ObjectBase<TypedObject<jfloatArray>, jfloatArray>::name[] = "[F";
-template<> const char ObjectBase<TypedObject<jdoubleArray>, jdoubleArray>::name[] = "[D";
-template<> const char ObjectBase<TypedObject<jobjectArray>, jobjectArray>::name[] = "[Ljava/lang/Object;";
-template<> const char ObjectBase<ByteBuffer, jobject>::name[] = "java/nio/ByteBuffer";
-
-
-JNIEnv* sGeckoThreadEnv;
-
-namespace {
-
-JavaVM* sJavaVM;
-pthread_key_t sThreadEnvKey;
-jclass sOOMErrorClass;
-jobject sClassLoader;
-jmethodID sClassLoaderLoadClass;
-bool sIsFennec;
-
-void UnregisterThreadEnv(void* env)
-{
- if (!env) {
- // We were never attached.
- return;
- }
- // The thread may have already been detached. In that case, it's still
- // okay to call DetachCurrentThread(); it'll simply return an error.
- // However, we must not access | env | because it may be invalid.
- MOZ_ASSERT(sJavaVM);
- sJavaVM->DetachCurrentThread();
-}
-
-} // namespace
-
-void SetGeckoThreadEnv(JNIEnv* aEnv)
-{
- MOZ_ASSERT(aEnv);
- MOZ_ASSERT(!sGeckoThreadEnv || sGeckoThreadEnv == aEnv);
-
- if (!sGeckoThreadEnv
- && pthread_key_create(&sThreadEnvKey, UnregisterThreadEnv)) {
- MOZ_CRASH("Failed to initialize required TLS");
- }
-
- sGeckoThreadEnv = aEnv;
- MOZ_ALWAYS_TRUE(!pthread_setspecific(sThreadEnvKey, aEnv));
-
- MOZ_ALWAYS_TRUE(!aEnv->GetJavaVM(&sJavaVM));
- MOZ_ASSERT(sJavaVM);
-
- sOOMErrorClass = Class::GlobalRef(Class::LocalRef::Adopt(
- aEnv->FindClass("java/lang/OutOfMemoryError"))).Forget();
- aEnv->ExceptionClear();
-
- sClassLoader = Object::GlobalRef(java::GeckoThread::ClsLoader()).Forget();
- sClassLoaderLoadClass = aEnv->GetMethodID(
- Class::LocalRef::Adopt(aEnv->GetObjectClass(sClassLoader)).Get(),
- "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
- MOZ_ASSERT(sClassLoader && sClassLoaderLoadClass);
-
- auto geckoAppClass = Class::LocalRef::Adopt(
- aEnv->FindClass("org/mozilla/gecko/GeckoApp"));
- aEnv->ExceptionClear();
- sIsFennec = !!geckoAppClass;
-}
-
-JNIEnv* GetEnvForThread()
-{
- MOZ_ASSERT(sGeckoThreadEnv);
-
- JNIEnv* env = static_cast<JNIEnv*>(pthread_getspecific(sThreadEnvKey));
- if (env) {
- return env;
- }
-
- // We don't have a saved JNIEnv, so try to get one.
- // AttachCurrentThread() does the same thing as GetEnv() when a thread is
- // already attached, so we don't have to call GetEnv() at all.
- if (!sJavaVM->AttachCurrentThread(&env, nullptr)) {
- MOZ_ASSERT(env);
- MOZ_ALWAYS_TRUE(!pthread_setspecific(sThreadEnvKey, env));
- return env;
- }
-
- MOZ_CRASH("Failed to get JNIEnv for thread");
- return nullptr; // unreachable
-}
-
-bool ThrowException(JNIEnv *aEnv, const char *aClass,
- const char *aMessage)
-{
- MOZ_ASSERT(aEnv, "Invalid thread JNI env");
-
- Class::LocalRef cls = Class::LocalRef::Adopt(aEnv->FindClass(aClass));
- MOZ_ASSERT(cls, "Cannot find exception class");
-
- return !aEnv->ThrowNew(cls.Get(), aMessage);
-}
-
-bool HandleUncaughtException(JNIEnv* aEnv)
-{
- MOZ_ASSERT(aEnv, "Invalid thread JNI env");
-
- if (!aEnv->ExceptionCheck()) {
- return false;
- }
-
-#ifdef MOZ_CHECK_JNI
- aEnv->ExceptionDescribe();
-#endif
-
- Throwable::LocalRef e =
- Throwable::LocalRef::Adopt(aEnv, aEnv->ExceptionOccurred());
- MOZ_ASSERT(e);
- aEnv->ExceptionClear();
-
- String::LocalRef stack = java::GeckoAppShell::GetExceptionStackTrace(e);
- if (stack && ReportException(aEnv, e.Get(), stack.Get())) {
- return true;
- }
-
- aEnv->ExceptionClear();
- java::GeckoAppShell::HandleUncaughtException(e);
-
- if (NS_WARN_IF(aEnv->ExceptionCheck())) {
- aEnv->ExceptionDescribe();
- aEnv->ExceptionClear();
- }
-
- return true;
-}
-
-bool ReportException(JNIEnv* aEnv, jthrowable aExc, jstring aStack)
-{
- bool result = true;
-
- if (sOOMErrorClass && aEnv->IsInstanceOf(aExc, sOOMErrorClass)) {
- NS_ABORT_OOM(0); // Unknown OOM size
- }
- return result;
-}
-
-namespace {
-
-jclass sJNIObjectClass;
-jfieldID sJNIObjectHandleField;
-
-bool EnsureJNIObject(JNIEnv* env, jobject instance) {
- if (!sJNIObjectClass) {
- sJNIObjectClass = Class::GlobalRef(Class::LocalRef::Adopt(GetClassRef(
- env, "org/mozilla/gecko/mozglue/JNIObject"))).Forget();
-
- sJNIObjectHandleField = env->GetFieldID(
- sJNIObjectClass, "mHandle", "J");
- }
-
- MOZ_ASSERT(env->IsInstanceOf(instance, sJNIObjectClass));
- return true;
-}
-
-} // namespace
-
-uintptr_t GetNativeHandle(JNIEnv* env, jobject instance)
-{
- if (!EnsureJNIObject(env, instance)) {
- return 0;
- }
-
- return static_cast<uintptr_t>(
- env->GetLongField(instance, sJNIObjectHandleField));
-}
-
-void SetNativeHandle(JNIEnv* env, jobject instance, uintptr_t handle)
-{
- if (!EnsureJNIObject(env, instance)) {
- return;
- }
-
- env->SetLongField(instance, sJNIObjectHandleField,
- static_cast<jlong>(handle));
-}
-
-jclass GetClassRef(JNIEnv* aEnv, const char* aClassName)
-{
- // First try the default class loader.
- auto classRef = Class::LocalRef::Adopt(aEnv, aEnv->FindClass(aClassName));
-
- if (!classRef && sClassLoader) {
- // If the default class loader failed but we have an app class loader, try that.
- // Clear the pending exception from failed FindClass call above.
- aEnv->ExceptionClear();
- classRef = Class::LocalRef::Adopt(aEnv, jclass(
- aEnv->CallObjectMethod(sClassLoader, sClassLoaderLoadClass,
- StringParam(aClassName, aEnv).Get())));
- }
-
- if (classRef) {
- return classRef.Forget();
- }
-
- __android_log_print(
- ANDROID_LOG_ERROR, "Gecko",
- ">>> FATAL JNI ERROR! FindClass(className=\"%s\") failed. "
- "Did ProGuard optimize away something it shouldn't have?",
- aClassName);
- aEnv->ExceptionDescribe();
- MOZ_CRASH("Cannot find JNI class");
- return nullptr;
-}
-
-void DispatchToGeckoThread(UniquePtr<AbstractCall>&& aCall)
-{
- class AbstractCallEvent : public nsAppShell::Event
- {
- UniquePtr<AbstractCall> mCall;
-
- public:
- AbstractCallEvent(UniquePtr<AbstractCall>&& aCall)
- : mCall(Move(aCall))
- {}
-
- void Run() override
- {
- (*mCall)();
- }
- };
-
- nsAppShell::PostEvent(MakeUnique<AbstractCallEvent>(Move(aCall)));
-}
-
-bool IsFennec()
-{
- return sIsFennec;
-}
-
-} // jni
-} // mozilla
diff --git a/widget/android/jni/Utils.h b/widget/android/jni/Utils.h
deleted file mode 100644
index 38e0b6b0c..000000000
--- a/widget/android/jni/Utils.h
+++ /dev/null
@@ -1,147 +0,0 @@
-#ifndef mozilla_jni_Utils_h__
-#define mozilla_jni_Utils_h__
-
-#include <jni.h>
-
-#include "mozilla/UniquePtr.h"
-
-#if defined(DEBUG) || !defined(RELEASE_OR_BETA)
-#define MOZ_CHECK_JNI
-#endif
-
-#ifdef MOZ_CHECK_JNI
-#include <pthread.h>
-#include "mozilla/Assertions.h"
-#include "APKOpen.h"
-#include "MainThreadUtils.h"
-#endif
-
-namespace mozilla {
-namespace jni {
-
-// How exception during a JNI call should be treated.
-enum class ExceptionMode
-{
- // Abort on unhandled excepion (default).
- ABORT,
- // Ignore the exception and return to caller.
- IGNORE,
- // Catch any exception and return a nsresult.
- NSRESULT,
-};
-
-// Thread that a particular JNI call is allowed on.
-enum class CallingThread
-{
- // Can be called from any thread (default).
- ANY,
- // Can be called from the Gecko thread.
- GECKO,
- // Can be called from the Java UI thread.
- UI,
-};
-
-// If and where a JNI call will be dispatched.
-enum class DispatchTarget
-{
- // Call happens synchronously on the calling thread (default).
- CURRENT,
- // Call happens synchronously on the calling thread, but the call is
- // wrapped in a function object and is passed thru UsesNativeCallProxy.
- // Method must return void.
- PROXY,
- // Call is dispatched asynchronously on the Gecko thread. Method must
- // return void.
- GECKO,
-};
-
-
-extern JNIEnv* sGeckoThreadEnv;
-
-inline bool IsAvailable()
-{
- return !!sGeckoThreadEnv;
-}
-
-inline JNIEnv* GetGeckoThreadEnv()
-{
-#ifdef MOZ_CHECK_JNI
- MOZ_RELEASE_ASSERT(NS_IsMainThread(), "Must be on Gecko thread");
- MOZ_RELEASE_ASSERT(sGeckoThreadEnv, "Must have a JNIEnv");
-#endif
- return sGeckoThreadEnv;
-}
-
-void SetGeckoThreadEnv(JNIEnv* aEnv);
-
-JNIEnv* GetEnvForThread();
-
-#ifdef MOZ_CHECK_JNI
-#define MOZ_ASSERT_JNI_THREAD(thread) \
- do { \
- if ((thread) == mozilla::jni::CallingThread::GECKO) { \
- MOZ_RELEASE_ASSERT(::NS_IsMainThread()); \
- } else if ((thread) == mozilla::jni::CallingThread::UI) { \
- const bool isOnUiThread = ::pthread_equal(::pthread_self(), \
- ::getJavaUiThread()); \
- MOZ_RELEASE_ASSERT(isOnUiThread); \
- } \
- } while (0)
-#else
-#define MOZ_ASSERT_JNI_THREAD(thread) do {} while (0)
-#endif
-
-bool ThrowException(JNIEnv *aEnv, const char *aClass,
- const char *aMessage);
-
-inline bool ThrowException(JNIEnv *aEnv, const char *aMessage)
-{
- return ThrowException(aEnv, "java/lang/Exception", aMessage);
-}
-
-inline bool ThrowException(const char *aClass, const char *aMessage)
-{
- return ThrowException(GetEnvForThread(), aClass, aMessage);
-}
-
-inline bool ThrowException(const char *aMessage)
-{
- return ThrowException(GetEnvForThread(), aMessage);
-}
-
-bool HandleUncaughtException(JNIEnv* aEnv);
-
-bool ReportException(JNIEnv* aEnv, jthrowable aExc, jstring aStack);
-
-#define MOZ_CATCH_JNI_EXCEPTION(env) \
- do { \
- if (mozilla::jni::HandleUncaughtException((env))) { \
- MOZ_CRASH("JNI exception"); \
- } \
- } while (0)
-
-
-uintptr_t GetNativeHandle(JNIEnv* env, jobject instance);
-
-void SetNativeHandle(JNIEnv* env, jobject instance, uintptr_t handle);
-
-jclass GetClassRef(JNIEnv* aEnv, const char* aClassName);
-
-struct AbstractCall
-{
- virtual ~AbstractCall() {}
- virtual void operator()() = 0;
-};
-
-void DispatchToGeckoThread(UniquePtr<AbstractCall>&& aCall);
-
-/**
- * Returns whether Gecko is running in a Fennec environment, as determined by
- * the presence of the GeckoApp class.
- */
-bool IsFennec();
-
-} // jni
-} // mozilla
-
-#endif // mozilla_jni_Utils_h__
diff --git a/widget/android/jni/moz.build b/widget/android/jni/moz.build
deleted file mode 100644
index 31d7d32e6..000000000
--- a/widget/android/jni/moz.build
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-EXPORTS.mozilla.jni += [
- 'Accessors.h',
- 'Natives.h',
- 'Refs.h',
- 'Types.h',
- 'Utils.h',
-]
-
-UNIFIED_SOURCES += [
- 'Utils.cpp',
-]
-
-FINAL_LIBRARY = 'xul'
-
-LOCAL_INCLUDES += [
- '/widget',
- '/widget/android',
-]