summaryrefslogtreecommitdiffstats
path: root/widget/android/jni/Conversions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'widget/android/jni/Conversions.cpp')
-rw-r--r--widget/android/jni/Conversions.cpp115
1 files changed, 115 insertions, 0 deletions
diff --git a/widget/android/jni/Conversions.cpp b/widget/android/jni/Conversions.cpp
new file mode 100644
index 0000000000..f7742b9535
--- /dev/null
+++ b/widget/android/jni/Conversions.cpp
@@ -0,0 +1,115 @@
+/* -*- 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/. */
+
+#include "Conversions.h"
+#include "JavaBuiltins.h"
+
+#include "mozilla/ipc/GeckoChildProcessHost.h"
+
+namespace mozilla {
+namespace jni {
+
+template <class T>
+jfieldID GetValueFieldID(JNIEnv* aEnv, const char* aType) {
+ const jfieldID id = aEnv->GetFieldID(
+ typename T::Context(aEnv, nullptr).ClassRef(), "value", aType);
+ aEnv->ExceptionClear();
+ return id;
+}
+
+// Cached locations of the primitive types within their standard boxed objects
+// to skip doing that lookup on every get.
+static jfieldID gBooleanValueField;
+static jfieldID gIntValueField;
+static jfieldID gDoubleValueField;
+
+void InitConversionStatics() {
+ MOZ_ASSERT(NS_IsMainThread());
+ JNIEnv* const env = jni::GetGeckoThreadEnv();
+ gBooleanValueField = GetValueFieldID<java::sdk::Boolean>(env, "Z");
+ gIntValueField = GetValueFieldID<java::sdk::Integer>(env, "I");
+ gDoubleValueField = GetValueFieldID<java::sdk::Double>(env, "D");
+}
+
+template <>
+bool Java2Native(mozilla::jni::Object::Param aData, JNIEnv* aEnv) {
+ MOZ_ASSERT(aData.IsInstanceOf<jni::Boolean>());
+
+ bool result = false;
+ if (gBooleanValueField) {
+ if (!aEnv) {
+ aEnv = jni::GetEnvForThread();
+ }
+ result =
+ aEnv->GetBooleanField(aData.Get(), gBooleanValueField) != JNI_FALSE;
+ MOZ_CATCH_JNI_EXCEPTION(aEnv);
+ } else {
+ result = java::sdk::Boolean::Ref::From(aData)->BooleanValue();
+ }
+
+ return result;
+}
+
+template <>
+int Java2Native(mozilla::jni::Object::Param aData, JNIEnv* aEnv) {
+ MOZ_ASSERT(aData.IsInstanceOf<jni::Integer>());
+
+ int result = 0;
+ if (gIntValueField) {
+ if (!aEnv) {
+ aEnv = jni::GetEnvForThread();
+ }
+ result = aEnv->GetIntField(aData.Get(), gIntValueField);
+ MOZ_CATCH_JNI_EXCEPTION(aEnv);
+ } else {
+ result = java::sdk::Number::Ref::From(aData)->IntValue();
+ }
+
+ return result;
+}
+
+template <>
+double Java2Native(mozilla::jni::Object::Param aData, JNIEnv* aEnv) {
+ MOZ_ASSERT(aData.IsInstanceOf<jni::Double>());
+
+ double result = 0;
+ if (gDoubleValueField) {
+ if (!aEnv) {
+ aEnv = jni::GetEnvForThread();
+ }
+ result = aEnv->GetDoubleField(aData.Get(), gDoubleValueField);
+ MOZ_CATCH_JNI_EXCEPTION(aEnv);
+ } else {
+ result = java::sdk::Number::Ref::From(aData)->DoubleValue();
+ }
+
+ return result;
+}
+
+template <>
+ipc::LaunchError Java2Native(mozilla::jni::Object::Param aData, JNIEnv* aEnv) {
+ // Bug 1819311: there is not much we can really catch due to how Android
+ // services are started, so for now we just expose it this way.
+ return ipc::LaunchError("Java2Native");
+}
+
+template <>
+nsString Java2Native(mozilla::jni::Object::Param aData, JNIEnv* aEnv) {
+ nsString result;
+ if (aData != NULL && aData.IsInstanceOf<jni::String>()) {
+ result = jni::String::Ref::From(aData)->ToString();
+ }
+ return result;
+}
+
+template <>
+nsresult Java2Native(mozilla::jni::Object::Param aData, JNIEnv* aEnv) {
+ MOZ_ASSERT(aData.IsInstanceOf<jni::Throwable>());
+ return NS_ERROR_FAILURE;
+}
+
+} // namespace jni
+} // namespace mozilla