1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "Conversions.h"
8 #include "JavaBuiltins.h"
9 
10 #include "mozilla/ipc/GeckoChildProcessHost.h"
11 
12 namespace mozilla {
13 namespace jni {
14 
15 template <class T>
GetValueFieldID(JNIEnv * aEnv,const char * aType)16 jfieldID GetValueFieldID(JNIEnv* aEnv, const char* aType) {
17   const jfieldID id = aEnv->GetFieldID(
18       typename T::Context(aEnv, nullptr).ClassRef(), "value", aType);
19   aEnv->ExceptionClear();
20   return id;
21 }
22 
23 // Cached locations of the primitive types within their standard boxed objects
24 // to skip doing that lookup on every get.
25 static jfieldID gBooleanValueField;
26 static jfieldID gIntValueField;
27 static jfieldID gDoubleValueField;
28 
InitConversionStatics()29 void InitConversionStatics() {
30   MOZ_ASSERT(NS_IsMainThread());
31   JNIEnv* const env = jni::GetGeckoThreadEnv();
32   gBooleanValueField = GetValueFieldID<java::sdk::Boolean>(env, "Z");
33   gIntValueField = GetValueFieldID<java::sdk::Integer>(env, "I");
34   gDoubleValueField = GetValueFieldID<java::sdk::Double>(env, "D");
35 }
36 
37 template <>
Java2Native(mozilla::jni::Object::Param aData,JNIEnv * aEnv)38 bool Java2Native(mozilla::jni::Object::Param aData, JNIEnv* aEnv) {
39   MOZ_ASSERT(aData.IsInstanceOf<jni::Boolean>());
40 
41   bool result = false;
42   if (gBooleanValueField) {
43     if (!aEnv) {
44       aEnv = jni::GetEnvForThread();
45     }
46     result =
47         aEnv->GetBooleanField(aData.Get(), gBooleanValueField) != JNI_FALSE;
48     MOZ_CATCH_JNI_EXCEPTION(aEnv);
49   } else {
50     result = java::sdk::Boolean::Ref::From(aData)->BooleanValue();
51   }
52 
53   return result;
54 }
55 
56 template <>
Java2Native(mozilla::jni::Object::Param aData,JNIEnv * aEnv)57 int Java2Native(mozilla::jni::Object::Param aData, JNIEnv* aEnv) {
58   MOZ_ASSERT(aData.IsInstanceOf<jni::Integer>());
59 
60   int result = 0;
61   if (gIntValueField) {
62     if (!aEnv) {
63       aEnv = jni::GetEnvForThread();
64     }
65     result = aEnv->GetIntField(aData.Get(), gIntValueField);
66     MOZ_CATCH_JNI_EXCEPTION(aEnv);
67   } else {
68     result = java::sdk::Number::Ref::From(aData)->IntValue();
69   }
70 
71   return result;
72 }
73 
74 template <>
Java2Native(mozilla::jni::Object::Param aData,JNIEnv * aEnv)75 double Java2Native(mozilla::jni::Object::Param aData, JNIEnv* aEnv) {
76   MOZ_ASSERT(aData.IsInstanceOf<jni::Double>());
77 
78   double result = 0;
79   if (gDoubleValueField) {
80     if (!aEnv) {
81       aEnv = jni::GetEnvForThread();
82     }
83     result = aEnv->GetDoubleField(aData.Get(), gDoubleValueField);
84     MOZ_CATCH_JNI_EXCEPTION(aEnv);
85   } else {
86     result = java::sdk::Number::Ref::From(aData)->DoubleValue();
87   }
88 
89   return result;
90 }
91 
92 template <>
Java2Native(mozilla::jni::Object::Param aData,JNIEnv * aEnv)93 ipc::LaunchError Java2Native(mozilla::jni::Object::Param aData, JNIEnv* aEnv) {
94   return ipc::LaunchError{};
95 }
96 
97 template <>
Java2Native(mozilla::jni::Object::Param aData,JNIEnv * aEnv)98 nsString Java2Native(mozilla::jni::Object::Param aData, JNIEnv* aEnv) {
99   nsString result;
100   if (aData != NULL && aData.IsInstanceOf<jni::String>()) {
101     result = jni::String::Ref::From(aData)->ToString();
102   }
103   return result;
104 }
105 
106 }  // namespace jni
107 }  // namespace mozilla
108