diff options
Diffstat (limited to 'widget/android')
73 files changed, 24526 insertions, 0 deletions
diff --git a/widget/android/ANRReporter.cpp b/widget/android/ANRReporter.cpp new file mode 100644 index 000000000..30d9b3d76 --- /dev/null +++ b/widget/android/ANRReporter.cpp @@ -0,0 +1,89 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 "ANRReporter.h" +#include "GeckoProfiler.h" + +#include <unistd.h> + +namespace mozilla { + +bool +ANRReporter::RequestNativeStack(bool aUnwind) +{ + if (profiler_is_active()) { + // Don't proceed if profiler is already running + return false; + } + // WARNING: we are on the ANR reporter thread at this point and it is + // generally unsafe to use the profiler from off the main thread. However, + // the risk here is limited because for most users, the profiler is not run + // elsewhere. See the discussion in Bug 863777, comment 13 + const char *NATIVE_STACK_FEATURES[] = + {"leaf", "threads", "privacy"}; + const char *NATIVE_STACK_UNWIND_FEATURES[] = + {"leaf", "threads", "privacy", "stackwalk"}; + + const char **features = NATIVE_STACK_FEATURES; + size_t features_size = sizeof(NATIVE_STACK_FEATURES); + if (aUnwind) { + features = NATIVE_STACK_UNWIND_FEATURES; + features_size = sizeof(NATIVE_STACK_UNWIND_FEATURES); + // We want the new unwinder if the unwind mode has not been set yet + putenv("MOZ_PROFILER_NEW=1"); + } + + const char *NATIVE_STACK_THREADS[] = + {"GeckoMain", "Compositor"}; + // Buffer one sample and let the profiler wait a long time + profiler_start(100, 10000, features, features_size / sizeof(char*), + NATIVE_STACK_THREADS, sizeof(NATIVE_STACK_THREADS) / sizeof(char*)); + return true; +} + +jni::String::LocalRef +ANRReporter::GetNativeStack() +{ + if (!profiler_is_active()) { + // Maybe profiler support is disabled? + return nullptr; + } + + // Timeout if we don't get a profiler sample after 5 seconds. + const PRIntervalTime timeout = PR_SecondsToInterval(5); + const PRIntervalTime startTime = PR_IntervalNow(); + + // Pointer to a profile JSON string + typedef mozilla::UniquePtr<char[]> ProfilePtr; + + ProfilePtr profile(profiler_get_profile()); + + while (profile && !strstr(profile.get(), "\"samples\":[{")) { + // no sample yet? + if (PR_IntervalNow() - startTime >= timeout) { + return nullptr; + } + usleep(100000ul); // Sleep for 100ms + profile = ProfilePtr(profiler_get_profile()); + } + + if (profile) { + return jni::String::Param(profile.get()); + } + return nullptr; +} + +void +ANRReporter::ReleaseNativeStack() +{ + if (!profiler_is_active()) { + // Maybe profiler support is disabled? + return; + } + profiler_stop(); +} + +} // namespace + diff --git a/widget/android/ANRReporter.h b/widget/android/ANRReporter.h new file mode 100644 index 000000000..d3e5cc7e8 --- /dev/null +++ b/widget/android/ANRReporter.h @@ -0,0 +1,26 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 ANRReporter_h__ +#define ANRReporter_h__ + +#include "FennecJNINatives.h" + +namespace mozilla { + +class ANRReporter : public java::ANRReporter::Natives<ANRReporter> +{ +private: + ANRReporter(); + +public: + static bool RequestNativeStack(bool aUnwind); + static jni::String::LocalRef GetNativeStack(); + static void ReleaseNativeStack(); +}; + +} // namespace + +#endif // ANRReporter_h__ diff --git a/widget/android/AndroidAlerts.cpp b/widget/android/AndroidAlerts.cpp new file mode 100644 index 000000000..8d5074672 --- /dev/null +++ b/widget/android/AndroidAlerts.cpp @@ -0,0 +1,126 @@ +/* -*- Mode: c++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4; -*- */ +/* 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 "AndroidAlerts.h" +#include "GeneratedJNIWrappers.h" +#include "nsAlertsUtils.h" + +namespace mozilla { +namespace widget { + +NS_IMPL_ISUPPORTS(AndroidAlerts, nsIAlertsService) + +StaticAutoPtr<AndroidAlerts::ListenerMap> AndroidAlerts::sListenerMap; + +NS_IMETHODIMP +AndroidAlerts::ShowAlertNotification(const nsAString & aImageUrl, + const nsAString & aAlertTitle, + const nsAString & aAlertText, + bool aAlertTextClickable, + const nsAString & aAlertCookie, + nsIObserver * aAlertListener, + const nsAString & aAlertName, + const nsAString & aBidi, + const nsAString & aLang, + const nsAString & aData, + nsIPrincipal * aPrincipal, + bool aInPrivateBrowsing, + bool aRequireInteraction) +{ + MOZ_ASSERT_UNREACHABLE("Should be implemented by nsAlertsService."); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +AndroidAlerts::ShowAlert(nsIAlertNotification* aAlert, + nsIObserver* aAlertListener) +{ + return ShowPersistentNotification(EmptyString(), aAlert, aAlertListener); +} + +NS_IMETHODIMP +AndroidAlerts::ShowPersistentNotification(const nsAString& aPersistentData, + nsIAlertNotification* aAlert, + nsIObserver* aAlertListener) +{ + // nsAlertsService disables our alerts backend if we ever return failure + // here. To keep the backend enabled, we always return NS_OK even if we + // encounter an error here. + nsresult rv; + + nsAutoString imageUrl; + rv = aAlert->GetImageURL(imageUrl); + NS_ENSURE_SUCCESS(rv, NS_OK); + + nsAutoString title; + rv = aAlert->GetTitle(title); + NS_ENSURE_SUCCESS(rv, NS_OK); + + nsAutoString text; + rv = aAlert->GetText(text); + NS_ENSURE_SUCCESS(rv, NS_OK); + + nsAutoString cookie; + rv = aAlert->GetCookie(cookie); + NS_ENSURE_SUCCESS(rv, NS_OK); + + nsAutoString name; + rv = aAlert->GetName(name); + NS_ENSURE_SUCCESS(rv, NS_OK); + + nsCOMPtr<nsIPrincipal> principal; + rv = aAlert->GetPrincipal(getter_AddRefs(principal)); + NS_ENSURE_SUCCESS(rv, NS_OK); + + nsAutoString host; + nsAlertsUtils::GetSourceHostPort(principal, host); + + if (aPersistentData.IsEmpty() && aAlertListener) { + if (!sListenerMap) { + sListenerMap = new ListenerMap(); + } + // This will remove any observers already registered for this name. + sListenerMap->Put(name, aAlertListener); + } + + java::GeckoAppShell::ShowNotification( + name, cookie, title, text, host, imageUrl, + !aPersistentData.IsEmpty() ? jni::StringParam(aPersistentData) + : jni::StringParam(nullptr)); + return NS_OK; +} + +NS_IMETHODIMP +AndroidAlerts::CloseAlert(const nsAString& aAlertName, + nsIPrincipal* aPrincipal) +{ + // We delete the entry in sListenerMap later, when CloseNotification calls + // NotifyListener. + java::GeckoAppShell::CloseNotification(aAlertName); + return NS_OK; +} + +void +AndroidAlerts::NotifyListener(const nsAString& aName, const char* aTopic, + const char16_t* aCookie) +{ + if (!sListenerMap) { + return; + } + + nsCOMPtr<nsIObserver> listener = sListenerMap->Get(aName); + if (!listener) { + return; + } + + listener->Observe(nullptr, aTopic, aCookie); + + if (NS_LITERAL_CSTRING("alertfinished").Equals(aTopic)) { + sListenerMap->Remove(aName); + } +} + +} // namespace widget +} // namespace mozilla diff --git a/widget/android/AndroidAlerts.h b/widget/android/AndroidAlerts.h new file mode 100644 index 000000000..16af15ce0 --- /dev/null +++ b/widget/android/AndroidAlerts.h @@ -0,0 +1,44 @@ +/* -*- Mode: c++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4; -*- */ +/* 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_widget_AndroidAlerts_h__ +#define mozilla_widget_AndroidAlerts_h__ + +#include "nsInterfaceHashtable.h" +#include "nsCOMPtr.h" +#include "nsHashKeys.h" +#include "nsIAlertsService.h" +#include "nsIObserver.h" + +#include "mozilla/StaticPtr.h" + +namespace mozilla { +namespace widget { + +class AndroidAlerts : public nsIAlertsService +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIALERTSSERVICE + + AndroidAlerts() {} + + static void NotifyListener(const nsAString& aName, const char* aTopic, + const char16_t* aCookie); + +protected: + virtual ~AndroidAlerts() + { + sListenerMap = nullptr; + } + + using ListenerMap = nsInterfaceHashtable<nsStringHashKey, nsIObserver>; + static StaticAutoPtr<ListenerMap> sListenerMap; +}; + +} // namespace widget +} // namespace mozilla + +#endif // nsAndroidAlerts_h__ diff --git a/widget/android/AndroidBridge.cpp b/widget/android/AndroidBridge.cpp new file mode 100644 index 000000000..dd2cce39a --- /dev/null +++ b/widget/android/AndroidBridge.cpp @@ -0,0 +1,1126 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 <android/log.h> +#include <dlfcn.h> +#include <math.h> +#include <GLES2/gl2.h> + +#include "mozilla/layers/CompositorBridgeChild.h" +#include "mozilla/layers/CompositorBridgeParent.h" + +#include "mozilla/Hal.h" +#include "nsXULAppAPI.h" +#include <prthread.h> +#include "nsXPCOMStrings.h" +#include "AndroidBridge.h" +#include "AndroidJNIWrapper.h" +#include "AndroidBridgeUtilities.h" +#include "nsAlertsUtils.h" +#include "nsAppShell.h" +#include "nsOSHelperAppService.h" +#include "nsWindow.h" +#include "mozilla/Preferences.h" +#include "nsThreadUtils.h" +#include "nsIThreadManager.h" +#include "gfxPlatform.h" +#include "gfxContext.h" +#include "mozilla/gfx/2D.h" +#include "gfxUtils.h" +#include "nsPresContext.h" +#include "nsIDocShell.h" +#include "nsPIDOMWindow.h" +#include "mozilla/dom/ScreenOrientation.h" +#include "nsIDOMWindowUtils.h" +#include "nsIDOMClientRect.h" +#include "mozilla/ClearOnShutdown.h" +#include "nsPrintfCString.h" +#include "NativeJSContainer.h" +#include "nsContentUtils.h" +#include "nsIScriptError.h" +#include "nsIHttpChannel.h" + +#include "MediaCodec.h" +#include "SurfaceTexture.h" +#include "GLContextProvider.h" + +#include "mozilla/TimeStamp.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/dom/ContentChild.h" +#include "nsIObserverService.h" +#include "nsISupportsPrimitives.h" +#include "MediaPrefs.h" +#include "WidgetUtils.h" + +#include "FennecJNIWrappers.h" + +using namespace mozilla; +using namespace mozilla::gfx; +using namespace mozilla::jni; +using namespace mozilla::java; + +AndroidBridge* AndroidBridge::sBridge = nullptr; +static jobject sGlobalContext = nullptr; +nsDataHashtable<nsStringHashKey, nsString> AndroidBridge::sStoragePaths; + +jmethodID AndroidBridge::GetMethodID(JNIEnv* env, jclass jClass, + const char* methodName, const char* methodType) +{ + jmethodID methodID = env->GetMethodID(jClass, methodName, methodType); + if (!methodID) { + ALOG(">>> FATAL JNI ERROR! GetMethodID(methodName=\"%s\", " + "methodType=\"%s\") failed. Did ProGuard optimize away something it shouldn't have?", + methodName, methodType); + env->ExceptionDescribe(); + MOZ_CRASH(); + } + return methodID; +} + +jmethodID AndroidBridge::GetStaticMethodID(JNIEnv* env, jclass jClass, + const char* methodName, const char* methodType) +{ + jmethodID methodID = env->GetStaticMethodID(jClass, methodName, methodType); + if (!methodID) { + ALOG(">>> FATAL JNI ERROR! GetStaticMethodID(methodName=\"%s\", " + "methodType=\"%s\") failed. Did ProGuard optimize away something it shouldn't have?", + methodName, methodType); + env->ExceptionDescribe(); + MOZ_CRASH(); + } + return methodID; +} + +jfieldID AndroidBridge::GetFieldID(JNIEnv* env, jclass jClass, + const char* fieldName, const char* fieldType) +{ + jfieldID fieldID = env->GetFieldID(jClass, fieldName, fieldType); + if (!fieldID) { + ALOG(">>> FATAL JNI ERROR! GetFieldID(fieldName=\"%s\", " + "fieldType=\"%s\") failed. Did ProGuard optimize away something it shouldn't have?", + fieldName, fieldType); + env->ExceptionDescribe(); + MOZ_CRASH(); + } + return fieldID; +} + +jfieldID AndroidBridge::GetStaticFieldID(JNIEnv* env, jclass jClass, + const char* fieldName, const char* fieldType) +{ + jfieldID fieldID = env->GetStaticFieldID(jClass, fieldName, fieldType); + if (!fieldID) { + ALOG(">>> FATAL JNI ERROR! GetStaticFieldID(fieldName=\"%s\", " + "fieldType=\"%s\") failed. Did ProGuard optimize away something it shouldn't have?", + fieldName, fieldType); + env->ExceptionDescribe(); + MOZ_CRASH(); + } + return fieldID; +} + +void +AndroidBridge::ConstructBridge() +{ + /* NSS hack -- bionic doesn't handle recursive unloads correctly, + * because library finalizer functions are called with the dynamic + * linker lock still held. This results in a deadlock when trying + * to call dlclose() while we're already inside dlclose(). + * Conveniently, NSS has an env var that can prevent it from unloading. + */ + putenv("NSS_DISABLE_UNLOAD=1"); + + MOZ_ASSERT(!sBridge); + sBridge = new AndroidBridge(); + + MediaPrefs::GetSingleton(); +} + +void +AndroidBridge::DeconstructBridge() +{ + if (sBridge) { + delete sBridge; + // AndroidBridge destruction requires sBridge to still be valid, + // so we set sBridge to nullptr after deleting it. + sBridge = nullptr; + } +} + +AndroidBridge::~AndroidBridge() +{ +} + +AndroidBridge::AndroidBridge() + : mUiTaskQueueLock("UiTaskQueue") +{ + ALOG_BRIDGE("AndroidBridge::Init"); + + JNIEnv* const jEnv = jni::GetGeckoThreadEnv(); + AutoLocalJNIFrame jniFrame(jEnv); + + mMessageQueue = java::GeckoThread::MsgQueue(); + auto msgQueueClass = Class::LocalRef::Adopt( + jEnv, jEnv->GetObjectClass(mMessageQueue.Get())); + // mMessageQueueNext must not be null + mMessageQueueNext = GetMethodID( + jEnv, msgQueueClass.Get(), "next", "()Landroid/os/Message;"); + // mMessageQueueMessages may be null (e.g. due to proguard optimization) + mMessageQueueMessages = jEnv->GetFieldID( + msgQueueClass.Get(), "mMessages", "Landroid/os/Message;"); + + AutoJNIClass string(jEnv, "java/lang/String"); + jStringClass = string.getGlobalRef(); + + if (!GetStaticIntField("android/os/Build$VERSION", "SDK_INT", &mAPIVersion, jEnv)) { + ALOG_BRIDGE("Failed to find API version"); + } + + AutoJNIClass channels(jEnv, "java/nio/channels/Channels"); + jChannels = channels.getGlobalRef(); + jChannelCreate = channels.getStaticMethod("newChannel", "(Ljava/io/InputStream;)Ljava/nio/channels/ReadableByteChannel;"); + + AutoJNIClass readableByteChannel(jEnv, "java/nio/channels/ReadableByteChannel"); + jReadableByteChannel = readableByteChannel.getGlobalRef(); + jByteBufferRead = readableByteChannel.getMethod("read", "(Ljava/nio/ByteBuffer;)I"); + + AutoJNIClass inputStream(jEnv, "java/io/InputStream"); + jInputStream = inputStream.getGlobalRef(); + jClose = inputStream.getMethod("close", "()V"); + jAvailable = inputStream.getMethod("available", "()I"); +} + +// Raw JNIEnv variants. +jstring AndroidBridge::NewJavaString(JNIEnv* env, const char16_t* string, uint32_t len) { + jstring ret = env->NewString(reinterpret_cast<const jchar*>(string), len); + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return nullptr; + } + return ret; +} + +jstring AndroidBridge::NewJavaString(JNIEnv* env, const nsAString& string) { + return NewJavaString(env, string.BeginReading(), string.Length()); +} + +jstring AndroidBridge::NewJavaString(JNIEnv* env, const char* string) { + return NewJavaString(env, NS_ConvertUTF8toUTF16(string)); +} + +jstring AndroidBridge::NewJavaString(JNIEnv* env, const nsACString& string) { + return NewJavaString(env, NS_ConvertUTF8toUTF16(string)); +} + +// AutoLocalJNIFrame variants.. +jstring AndroidBridge::NewJavaString(AutoLocalJNIFrame* frame, const char16_t* string, uint32_t len) { + return NewJavaString(frame->GetEnv(), string, len); +} + +jstring AndroidBridge::NewJavaString(AutoLocalJNIFrame* frame, const nsAString& string) { + return NewJavaString(frame, string.BeginReading(), string.Length()); +} + +jstring AndroidBridge::NewJavaString(AutoLocalJNIFrame* frame, const char* string) { + return NewJavaString(frame, NS_ConvertUTF8toUTF16(string)); +} + +jstring AndroidBridge::NewJavaString(AutoLocalJNIFrame* frame, const nsACString& string) { + return NewJavaString(frame, NS_ConvertUTF8toUTF16(string)); +} + +static void +getHandlersFromStringArray(JNIEnv *aJNIEnv, jobjectArray jArr, jsize aLen, + nsIMutableArray *aHandlersArray, + nsIHandlerApp **aDefaultApp, + const nsAString& aAction = EmptyString(), + const nsACString& aMimeType = EmptyCString()) +{ + nsString empty = EmptyString(); + for (jsize i = 0; i < aLen; i+=4) { + + AutoLocalJNIFrame jniFrame(aJNIEnv, 4); + nsJNIString name( + static_cast<jstring>(aJNIEnv->GetObjectArrayElement(jArr, i)), aJNIEnv); + nsJNIString isDefault( + static_cast<jstring>(aJNIEnv->GetObjectArrayElement(jArr, i + 1)), aJNIEnv); + nsJNIString packageName( + static_cast<jstring>(aJNIEnv->GetObjectArrayElement(jArr, i + 2)), aJNIEnv); + nsJNIString className( + static_cast<jstring>(aJNIEnv->GetObjectArrayElement(jArr, i + 3)), aJNIEnv); + nsIHandlerApp* app = nsOSHelperAppService:: + CreateAndroidHandlerApp(name, className, packageName, + className, aMimeType, aAction); + + aHandlersArray->AppendElement(app, false); + if (aDefaultApp && isDefault.Length() > 0) + *aDefaultApp = app; + } +} + +bool +AndroidBridge::GetHandlersForMimeType(const nsAString& aMimeType, + nsIMutableArray *aHandlersArray, + nsIHandlerApp **aDefaultApp, + const nsAString& aAction) +{ + ALOG_BRIDGE("AndroidBridge::GetHandlersForMimeType"); + + auto arr = GeckoAppShell::GetHandlersForMimeType(aMimeType, aAction); + if (!arr) + return false; + + JNIEnv* const env = arr.Env(); + jsize len = env->GetArrayLength(arr.Get()); + + if (!aHandlersArray) + return len > 0; + + getHandlersFromStringArray(env, arr.Get(), len, aHandlersArray, + aDefaultApp, aAction, + NS_ConvertUTF16toUTF8(aMimeType)); + return true; +} + +bool +AndroidBridge::GetHWEncoderCapability() +{ + ALOG_BRIDGE("AndroidBridge::GetHWEncoderCapability"); + + bool value = GeckoAppShell::GetHWEncoderCapability(); + + return value; +} + + +bool +AndroidBridge::GetHWDecoderCapability() +{ + ALOG_BRIDGE("AndroidBridge::GetHWDecoderCapability"); + + bool value = GeckoAppShell::GetHWDecoderCapability(); + + return value; +} + +bool +AndroidBridge::GetHandlersForURL(const nsAString& aURL, + nsIMutableArray* aHandlersArray, + nsIHandlerApp **aDefaultApp, + const nsAString& aAction) +{ + ALOG_BRIDGE("AndroidBridge::GetHandlersForURL"); + + auto arr = GeckoAppShell::GetHandlersForURL(aURL, aAction); + if (!arr) + return false; + + JNIEnv* const env = arr.Env(); + jsize len = env->GetArrayLength(arr.Get()); + + if (!aHandlersArray) + return len > 0; + + getHandlersFromStringArray(env, arr.Get(), len, aHandlersArray, + aDefaultApp, aAction); + return true; +} + +void +AndroidBridge::GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString& aMimeType) +{ + ALOG_BRIDGE("AndroidBridge::GetMimeTypeFromExtensions"); + + auto jstrType = GeckoAppShell::GetMimeTypeFromExtensions(aFileExt); + + if (jstrType) { + aMimeType = jstrType->ToCString(); + } +} + +void +AndroidBridge::GetExtensionFromMimeType(const nsACString& aMimeType, nsACString& aFileExt) +{ + ALOG_BRIDGE("AndroidBridge::GetExtensionFromMimeType"); + + auto jstrExt = GeckoAppShell::GetExtensionFromMimeType(aMimeType); + + if (jstrExt) { + aFileExt = jstrExt->ToCString(); + } +} + +bool +AndroidBridge::GetClipboardText(nsAString& aText) +{ + ALOG_BRIDGE("AndroidBridge::GetClipboardText"); + + auto text = Clipboard::GetText(); + + if (text) { + aText = text->ToString(); + } + return !!text; +} + +int +AndroidBridge::GetDPI() +{ + static int sDPI = 0; + if (sDPI) + return sDPI; + + const int DEFAULT_DPI = 160; + + sDPI = GeckoAppShell::GetDpi(); + if (!sDPI) { + return DEFAULT_DPI; + } + + return sDPI; +} + +int +AndroidBridge::GetScreenDepth() +{ + ALOG_BRIDGE("%s", __PRETTY_FUNCTION__); + + static int sDepth = 0; + if (sDepth) + return sDepth; + + const int DEFAULT_DEPTH = 16; + + if (jni::IsAvailable()) { + sDepth = GeckoAppShell::GetScreenDepth(); + } + if (!sDepth) + return DEFAULT_DEPTH; + + return sDepth; +} +void +AndroidBridge::Vibrate(const nsTArray<uint32_t>& aPattern) +{ + ALOG_BRIDGE("%s", __PRETTY_FUNCTION__); + + uint32_t len = aPattern.Length(); + if (!len) { + ALOG_BRIDGE(" invalid 0-length array"); + return; + } + + // It's clear if this worth special-casing, but it creates less + // java junk, so dodges the GC. + if (len == 1) { + jlong d = aPattern[0]; + if (d < 0) { + ALOG_BRIDGE(" invalid vibration duration < 0"); + return; + } + GeckoAppShell::Vibrate(d); + return; + } + + // First element of the array vibrate() expects is how long to wait + // *before* vibrating. For us, this is always 0. + + JNIEnv* const env = jni::GetGeckoThreadEnv(); + AutoLocalJNIFrame jniFrame(env, 1); + + jlongArray array = env->NewLongArray(len + 1); + if (!array) { + ALOG_BRIDGE(" failed to allocate array"); + return; + } + + jlong* elts = env->GetLongArrayElements(array, nullptr); + elts[0] = 0; + for (uint32_t i = 0; i < aPattern.Length(); ++i) { + jlong d = aPattern[i]; + if (d < 0) { + ALOG_BRIDGE(" invalid vibration duration < 0"); + env->ReleaseLongArrayElements(array, elts, JNI_ABORT); + return; + } + elts[i + 1] = d; + } + env->ReleaseLongArrayElements(array, elts, 0); + + GeckoAppShell::Vibrate(LongArray::Ref::From(array), -1 /* don't repeat */); +} + +void +AndroidBridge::GetSystemColors(AndroidSystemColors *aColors) +{ + + NS_ASSERTION(aColors != nullptr, "AndroidBridge::GetSystemColors: aColors is null!"); + if (!aColors) + return; + + auto arr = GeckoAppShell::GetSystemColors(); + if (!arr) + return; + + JNIEnv* const env = arr.Env(); + uint32_t len = static_cast<uint32_t>(env->GetArrayLength(arr.Get())); + jint *elements = env->GetIntArrayElements(arr.Get(), 0); + + uint32_t colorsCount = sizeof(AndroidSystemColors) / sizeof(nscolor); + if (len < colorsCount) + colorsCount = len; + + // Convert Android colors to nscolor by switching R and B in the ARGB 32 bit value + nscolor *colors = (nscolor*)aColors; + + for (uint32_t i = 0; i < colorsCount; i++) { + uint32_t androidColor = static_cast<uint32_t>(elements[i]); + uint8_t r = (androidColor & 0x00ff0000) >> 16; + uint8_t b = (androidColor & 0x000000ff); + colors[i] = (androidColor & 0xff00ff00) | (b << 16) | r; + } + + env->ReleaseIntArrayElements(arr.Get(), elements, 0); +} + +void +AndroidBridge::GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSize, uint8_t * const aBuf) +{ + ALOG_BRIDGE("AndroidBridge::GetIconForExtension"); + NS_ASSERTION(aBuf != nullptr, "AndroidBridge::GetIconForExtension: aBuf is null!"); + if (!aBuf) + return; + + auto arr = GeckoAppShell::GetIconForExtension(NS_ConvertUTF8toUTF16(aFileExt), aIconSize); + + NS_ASSERTION(arr != nullptr, "AndroidBridge::GetIconForExtension: Returned pixels array is null!"); + if (!arr) + return; + + JNIEnv* const env = arr.Env(); + uint32_t len = static_cast<uint32_t>(env->GetArrayLength(arr.Get())); + jbyte *elements = env->GetByteArrayElements(arr.Get(), 0); + + uint32_t bufSize = aIconSize * aIconSize * 4; + NS_ASSERTION(len == bufSize, "AndroidBridge::GetIconForExtension: Pixels array is incomplete!"); + if (len == bufSize) + memcpy(aBuf, elements, bufSize); + + env->ReleaseByteArrayElements(arr.Get(), elements, 0); +} + +bool +AndroidBridge::GetStaticIntField(const char *className, const char *fieldName, int32_t* aInt, JNIEnv* jEnv /* = nullptr */) +{ + ALOG_BRIDGE("AndroidBridge::GetStaticIntField %s", fieldName); + + if (!jEnv) { + if (!jni::IsAvailable()) { + return false; + } + jEnv = jni::GetGeckoThreadEnv(); + } + + AutoJNIClass cls(jEnv, className); + jfieldID field = cls.getStaticField(fieldName, "I"); + + if (!field) { + return false; + } + + *aInt = static_cast<int32_t>(jEnv->GetStaticIntField(cls.getRawRef(), field)); + return true; +} + +bool +AndroidBridge::GetStaticStringField(const char *className, const char *fieldName, nsAString &result, JNIEnv* jEnv /* = nullptr */) +{ + ALOG_BRIDGE("AndroidBridge::GetStaticStringField %s", fieldName); + + if (!jEnv) { + if (!jni::IsAvailable()) { + return false; + } + jEnv = jni::GetGeckoThreadEnv(); + } + + AutoLocalJNIFrame jniFrame(jEnv, 1); + AutoJNIClass cls(jEnv, className); + jfieldID field = cls.getStaticField(fieldName, "Ljava/lang/String;"); + + if (!field) { + return false; + } + + jstring jstr = (jstring) jEnv->GetStaticObjectField(cls.getRawRef(), field); + if (!jstr) + return false; + + result.Assign(nsJNIString(jstr, jEnv)); + return true; +} + +namespace mozilla { + class TracerRunnable : public Runnable{ + public: + TracerRunnable() { + mTracerLock = new Mutex("TracerRunnable"); + mTracerCondVar = new CondVar(*mTracerLock, "TracerRunnable"); + mMainThread = do_GetMainThread(); + + } + ~TracerRunnable() { + delete mTracerCondVar; + delete mTracerLock; + mTracerLock = nullptr; + mTracerCondVar = nullptr; + } + + virtual nsresult Run() { + MutexAutoLock lock(*mTracerLock); + if (!AndroidBridge::Bridge()) + return NS_OK; + + mHasRun = true; + mTracerCondVar->Notify(); + return NS_OK; + } + + bool Fire() { + if (!mTracerLock || !mTracerCondVar) + return false; + MutexAutoLock lock(*mTracerLock); + mHasRun = false; + mMainThread->Dispatch(this, NS_DISPATCH_NORMAL); + while (!mHasRun) + mTracerCondVar->Wait(); + return true; + } + + void Signal() { + MutexAutoLock lock(*mTracerLock); + mHasRun = true; + mTracerCondVar->Notify(); + } + private: + Mutex* mTracerLock; + CondVar* mTracerCondVar; + bool mHasRun; + nsCOMPtr<nsIThread> mMainThread; + + }; + StaticRefPtr<TracerRunnable> sTracerRunnable; + + bool InitWidgetTracing() { + if (!sTracerRunnable) + sTracerRunnable = new TracerRunnable(); + return true; + } + + void CleanUpWidgetTracing() { + sTracerRunnable = nullptr; + } + + bool FireAndWaitForTracerEvent() { + if (sTracerRunnable) + return sTracerRunnable->Fire(); + return false; + } + + void SignalTracerThread() + { + if (sTracerRunnable) + return sTracerRunnable->Signal(); + } + +} + + +void +AndroidBridge::GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo) +{ + ALOG_BRIDGE("AndroidBridge::GetCurrentBatteryInformation"); + + // To prevent calling too many methods through JNI, the Java method returns + // an array of double even if we actually want a double and a boolean. + auto arr = GeckoAppShell::GetCurrentBatteryInformation(); + + JNIEnv* const env = arr.Env(); + if (!arr || env->GetArrayLength(arr.Get()) != 3) { + return; + } + + jdouble* info = env->GetDoubleArrayElements(arr.Get(), 0); + + aBatteryInfo->level() = info[0]; + aBatteryInfo->charging() = info[1] == 1.0f; + aBatteryInfo->remainingTime() = info[2]; + + env->ReleaseDoubleArrayElements(arr.Get(), info, 0); +} + +void +AndroidBridge::HandleGeckoMessage(JSContext* cx, JS::HandleObject object) +{ + ALOG_BRIDGE("%s", __PRETTY_FUNCTION__); + + auto message = widget::CreateNativeJSContainer(cx, object); + GeckoAppShell::HandleGeckoMessage(message); +} + +void +AndroidBridge::GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo) +{ + ALOG_BRIDGE("AndroidBridge::GetCurrentNetworkInformation"); + + // To prevent calling too many methods through JNI, the Java method returns + // an array of double even if we actually want an integer, a boolean, and an integer. + + auto arr = GeckoAppShell::GetCurrentNetworkInformation(); + + JNIEnv* const env = arr.Env(); + if (!arr || env->GetArrayLength(arr.Get()) != 3) { + return; + } + + jdouble* info = env->GetDoubleArrayElements(arr.Get(), 0); + + aNetworkInfo->type() = info[0]; + aNetworkInfo->isWifi() = info[1] == 1.0f; + aNetworkInfo->dhcpGateway() = info[2]; + + env->ReleaseDoubleArrayElements(arr.Get(), info, 0); +} + +jobject +AndroidBridge::GetGlobalContextRef() { + if (sGlobalContext) { + return sGlobalContext; + } + + JNIEnv* const env = GetEnvForThread(); + AutoLocalJNIFrame jniFrame(env, 4); + + auto context = GeckoAppShell::GetContext(); + if (!context) { + ALOG_BRIDGE("%s: Could not GetContext()", __FUNCTION__); + return 0; + } + jclass contextClass = env->FindClass("android/content/Context"); + if (!contextClass) { + ALOG_BRIDGE("%s: Could not find Context class.", __FUNCTION__); + return 0; + } + jmethodID mid = env->GetMethodID(contextClass, "getApplicationContext", + "()Landroid/content/Context;"); + if (!mid) { + ALOG_BRIDGE("%s: Could not find getApplicationContext.", __FUNCTION__); + return 0; + } + jobject appContext = env->CallObjectMethod(context.Get(), mid); + if (!appContext) { + ALOG_BRIDGE("%s: getApplicationContext failed.", __FUNCTION__); + return 0; + } + + sGlobalContext = env->NewGlobalRef(appContext); + MOZ_ASSERT(sGlobalContext); + return sGlobalContext; +} + +/* Implementation file */ +NS_IMPL_ISUPPORTS(nsAndroidBridge, nsIAndroidBridge) + +nsAndroidBridge::nsAndroidBridge() +{ + AddObservers(); +} + +nsAndroidBridge::~nsAndroidBridge() +{ + RemoveObservers(); +} + +NS_IMETHODIMP nsAndroidBridge::HandleGeckoMessage(JS::HandleValue val, + JSContext *cx) +{ + if (val.isObject()) { + JS::RootedObject object(cx, &val.toObject()); + AndroidBridge::Bridge()->HandleGeckoMessage(cx, object); + return NS_OK; + } + + // Now handle legacy JSON messages. + if (!val.isString()) { + return NS_ERROR_INVALID_ARG; + } + JS::RootedString jsonStr(cx, val.toString()); + + JS::RootedValue jsonVal(cx); + if (!JS_ParseJSON(cx, jsonStr, &jsonVal) || !jsonVal.isObject()) { + return NS_ERROR_INVALID_ARG; + } + + // Spit out a warning before sending the message. + nsContentUtils::ReportToConsoleNonLocalized( + NS_LITERAL_STRING("Use of JSON is deprecated. " + "Please pass Javascript objects directly to handleGeckoMessage."), + nsIScriptError::warningFlag, + NS_LITERAL_CSTRING("nsIAndroidBridge"), + nullptr); + + JS::RootedObject object(cx, &jsonVal.toObject()); + AndroidBridge::Bridge()->HandleGeckoMessage(cx, object); + return NS_OK; +} + +NS_IMETHODIMP nsAndroidBridge::ContentDocumentChanged(mozIDOMWindowProxy* aWindow) +{ + AndroidBridge::Bridge()->ContentDocumentChanged(aWindow); + return NS_OK; +} + +NS_IMETHODIMP nsAndroidBridge::IsContentDocumentDisplayed(mozIDOMWindowProxy* aWindow, + bool *aRet) +{ + *aRet = AndroidBridge::Bridge()->IsContentDocumentDisplayed(aWindow); + return NS_OK; +} + +NS_IMETHODIMP +nsAndroidBridge::Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* aData) +{ + if (!strcmp(aTopic, "xpcom-shutdown")) { + RemoveObservers(); + } else if (!strcmp(aTopic, "media-playback")) { + ALOG_BRIDGE("nsAndroidBridge::Observe, get media-playback event."); + + nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject); + if (!wrapper) { + return NS_OK; + } + + uint64_t windowId = 0; + nsresult rv = wrapper->GetData(&windowId); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + nsAutoString activeStr(aData); + bool isPlaying = activeStr.EqualsLiteral("active"); + UpdateAudioPlayingWindows(windowId, isPlaying); + } + return NS_OK; +} + +void +nsAndroidBridge::UpdateAudioPlayingWindows(uint64_t aWindowId, + bool aPlaying) +{ + // Request audio focus for the first audio playing window and abandon focus + // for the last audio playing window. + if (aPlaying && !mAudioPlayingWindows.Contains(aWindowId)) { + mAudioPlayingWindows.AppendElement(aWindowId); + if (mAudioPlayingWindows.Length() == 1) { + ALOG_BRIDGE("nsAndroidBridge, request audio focus."); + AudioFocusAgent::NotifyStartedPlaying(); + } + } else if (!aPlaying && mAudioPlayingWindows.Contains(aWindowId)) { + mAudioPlayingWindows.RemoveElement(aWindowId); + if (mAudioPlayingWindows.Length() == 0) { + ALOG_BRIDGE("nsAndroidBridge, abandon audio focus."); + AudioFocusAgent::NotifyStoppedPlaying(); + } + } +} + +void +nsAndroidBridge::AddObservers() +{ + nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); + if (obs) { + obs->AddObserver(this, "xpcom-shutdown", false); + if (jni::IsFennec()) { // No AudioFocusAgent in non-Fennec environment. + obs->AddObserver(this, "media-playback", false); + } + } +} + +void +nsAndroidBridge::RemoveObservers() +{ + nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); + if (obs) { + obs->RemoveObserver(this, "xpcom-shutdown"); + if (jni::IsFennec()) { // No AudioFocusAgent in non-Fennec environment. + obs->RemoveObserver(this, "media-playback"); + } + } +} + +uint32_t +AndroidBridge::GetScreenOrientation() +{ + ALOG_BRIDGE("AndroidBridge::GetScreenOrientation"); + + int16_t orientation = GeckoAppShell::GetScreenOrientation(); + + if (!orientation) + return dom::eScreenOrientation_None; + + return static_cast<dom::ScreenOrientationInternal>(orientation); +} + +uint16_t +AndroidBridge::GetScreenAngle() +{ + return GeckoAppShell::GetScreenAngle(); +} + +nsresult +AndroidBridge::GetProxyForURI(const nsACString & aSpec, + const nsACString & aScheme, + const nsACString & aHost, + const int32_t aPort, + nsACString & aResult) +{ + if (!jni::IsAvailable()) { + return NS_ERROR_FAILURE; + } + + auto jstrRet = GeckoAppShell::GetProxyForURI(aSpec, aScheme, aHost, aPort); + + if (!jstrRet) + return NS_ERROR_FAILURE; + + aResult = jstrRet->ToCString(); + return NS_OK; +} + +bool +AndroidBridge::PumpMessageLoop() +{ + JNIEnv* const env = jni::GetGeckoThreadEnv(); + + if (mMessageQueueMessages) { + auto msg = Object::LocalRef::Adopt(env, + env->GetObjectField(mMessageQueue.Get(), + mMessageQueueMessages)); + // if queue.mMessages is null, queue.next() will block, which we don't + // want. It turns out to be an order of magnitude more performant to do + // this extra check here and block less vs. one fewer checks here and + // more blocking. + if (!msg) { + return false; + } + } + + auto msg = Object::LocalRef::Adopt( + env, env->CallObjectMethod(mMessageQueue.Get(), mMessageQueueNext)); + if (!msg) { + return false; + } + + return GeckoThread::PumpMessageLoop(msg); +} + +NS_IMETHODIMP nsAndroidBridge::GetBrowserApp(nsIAndroidBrowserApp * *aBrowserApp) +{ + nsAppShell* const appShell = nsAppShell::Get(); + if (appShell) + NS_IF_ADDREF(*aBrowserApp = appShell->GetBrowserApp()); + return NS_OK; +} + +NS_IMETHODIMP nsAndroidBridge::SetBrowserApp(nsIAndroidBrowserApp *aBrowserApp) +{ + nsAppShell* const appShell = nsAppShell::Get(); + if (appShell) + appShell->SetBrowserApp(aBrowserApp); + return NS_OK; +} + +extern "C" +__attribute__ ((visibility("default"))) +jobject JNICALL +Java_org_mozilla_gecko_GeckoAppShell_allocateDirectBuffer(JNIEnv *env, jclass, jlong size); + +static jni::DependentRef<java::GeckoLayerClient> +GetJavaLayerClient(mozIDOMWindowProxy* aWindow) +{ + MOZ_ASSERT(aWindow); + + nsCOMPtr<nsPIDOMWindowOuter> domWindow = nsPIDOMWindowOuter::From(aWindow); + nsCOMPtr<nsIWidget> widget = + widget::WidgetUtils::DOMWindowToWidget(domWindow); + MOZ_ASSERT(widget); + + return static_cast<nsWindow*>(widget.get())->GetLayerClient(); +} + +void +AndroidBridge::ContentDocumentChanged(mozIDOMWindowProxy* aWindow) +{ + auto layerClient = GetJavaLayerClient(aWindow); + if (!layerClient) { + return; + } + layerClient->ContentDocumentChanged(); +} + +bool +AndroidBridge::IsContentDocumentDisplayed(mozIDOMWindowProxy* aWindow) +{ + auto layerClient = GetJavaLayerClient(aWindow); + if (!layerClient) { + return false; + } + return layerClient->IsContentDocumentDisplayed(); +} + +class AndroidBridge::DelayedTask +{ + using TimeStamp = mozilla::TimeStamp; + using TimeDuration = mozilla::TimeDuration; + +public: + DelayedTask(already_AddRefed<Runnable> aTask) + : mTask(aTask) + , mRunTime() // Null timestamp representing no delay. + {} + + DelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) + : mTask(aTask) + , mRunTime(TimeStamp::Now() + TimeDuration::FromMilliseconds(aDelayMs)) + {} + + bool IsEarlierThan(const DelayedTask& aOther) const + { + if (mRunTime) { + return aOther.mRunTime ? mRunTime < aOther.mRunTime : false; + } + // In the case of no delay, we're earlier if aOther has a delay. + // Otherwise, we're not earlier, to maintain task order. + return !!aOther.mRunTime; + } + + int64_t MillisecondsToRunTime() const + { + if (mRunTime) { + return int64_t((mRunTime - TimeStamp::Now()).ToMilliseconds()); + } + return 0; + } + + already_AddRefed<Runnable> TakeTask() + { + return mTask.forget(); + } + +private: + RefPtr<Runnable> mTask; + const TimeStamp mRunTime; +}; + + +void +AndroidBridge::PostTaskToUiThread(already_AddRefed<Runnable> aTask, int aDelayMs) +{ + // add the new task into the mUiTaskQueue, sorted with + // the earliest task first in the queue + size_t i; + DelayedTask newTask(aDelayMs ? DelayedTask(mozilla::Move(aTask), aDelayMs) + : DelayedTask(mozilla::Move(aTask))); + + { + MutexAutoLock lock(mUiTaskQueueLock); + + for (i = 0; i < mUiTaskQueue.Length(); i++) { + if (newTask.IsEarlierThan(mUiTaskQueue[i])) { + mUiTaskQueue.InsertElementAt(i, mozilla::Move(newTask)); + break; + } + } + + if (i == mUiTaskQueue.Length()) { + // We didn't insert the task, which means we should append it. + mUiTaskQueue.AppendElement(mozilla::Move(newTask)); + } + } + + if (i == 0) { + // if we're inserting it at the head of the queue, notify Java because + // we need to get a callback at an earlier time than the last scheduled + // callback + GeckoThread::RequestUiThreadCallback(int64_t(aDelayMs)); + } +} + +int64_t +AndroidBridge::RunDelayedUiThreadTasks() +{ + MutexAutoLock lock(mUiTaskQueueLock); + + while (!mUiTaskQueue.IsEmpty()) { + const int64_t timeLeft = mUiTaskQueue[0].MillisecondsToRunTime(); + if (timeLeft > 0) { + // this task (and therefore all remaining tasks) + // have not yet reached their runtime. return the + // time left until we should be called again + return timeLeft; + } + + // Retrieve task before unlocking/running. + RefPtr<Runnable> nextTask(mUiTaskQueue[0].TakeTask()); + mUiTaskQueue.RemoveElementAt(0); + + // Unlock to allow posting new tasks reentrantly. + MutexAutoUnlock unlock(mUiTaskQueueLock); + nextTask->Run(); + } + return -1; +} + +Object::LocalRef AndroidBridge::ChannelCreate(Object::Param stream) { + JNIEnv* const env = GetEnvForThread(); + auto rv = Object::LocalRef::Adopt(env, env->CallStaticObjectMethod( + sBridge->jChannels, sBridge->jChannelCreate, stream.Get())); + MOZ_CATCH_JNI_EXCEPTION(env); + return rv; +} + +void AndroidBridge::InputStreamClose(Object::Param obj) { + JNIEnv* const env = GetEnvForThread(); + env->CallVoidMethod(obj.Get(), sBridge->jClose); + MOZ_CATCH_JNI_EXCEPTION(env); +} + +uint32_t AndroidBridge::InputStreamAvailable(Object::Param obj) { + JNIEnv* const env = GetEnvForThread(); + auto rv = env->CallIntMethod(obj.Get(), sBridge->jAvailable); + MOZ_CATCH_JNI_EXCEPTION(env); + return rv; +} + +nsresult AndroidBridge::InputStreamRead(Object::Param obj, char *aBuf, uint32_t aCount, uint32_t *aRead) { + JNIEnv* const env = GetEnvForThread(); + auto arr = ByteBuffer::New(aBuf, aCount); + jint read = env->CallIntMethod(obj.Get(), sBridge->jByteBufferRead, arr.Get()); + + if (env->ExceptionCheck()) { + env->ExceptionClear(); + return NS_ERROR_FAILURE; + } + + if (read <= 0) { + *aRead = 0; + return NS_OK; + } + *aRead = read; + return NS_OK; +} diff --git a/widget/android/AndroidBridge.h b/widget/android/AndroidBridge.h new file mode 100644 index 000000000..73dc1b5ff --- /dev/null +++ b/widget/android/AndroidBridge.h @@ -0,0 +1,419 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 AndroidBridge_h__ +#define AndroidBridge_h__ + +#include <jni.h> +#include <android/log.h> +#include <cstdlib> +#include <pthread.h> + +#include "APKOpen.h" + +#include "nsCOMPtr.h" +#include "nsCOMArray.h" + +#include "GeneratedJNIWrappers.h" + +#include "nsIMutableArray.h" +#include "nsIMIMEInfo.h" +#include "nsColor.h" +#include "gfxRect.h" + +#include "nsIAndroidBridge.h" +#include "nsIDOMDOMCursor.h" + +#include "mozilla/Likely.h" +#include "mozilla/Mutex.h" +#include "mozilla/Types.h" +#include "mozilla/gfx/Point.h" +#include "mozilla/jni/Utils.h" +#include "nsIObserver.h" +#include "nsDataHashtable.h" + +#include "Units.h" + +// Some debug #defines +// #define DEBUG_ANDROID_EVENTS +// #define DEBUG_ANDROID_WIDGET + +class nsPIDOMWindowOuter; + +namespace base { +class Thread; +} // end namespace base + +typedef void* EGLSurface; + +namespace mozilla { + +class AutoLocalJNIFrame; +class Runnable; + +namespace hal { +class BatteryInformation; +class NetworkInformation; +} // namespace hal + +// The order and number of the members in this structure must correspond +// to the attrsAppearance array in GeckoAppShell.getSystemColors() +typedef struct AndroidSystemColors { + nscolor textColorPrimary; + nscolor textColorPrimaryInverse; + nscolor textColorSecondary; + nscolor textColorSecondaryInverse; + nscolor textColorTertiary; + nscolor textColorTertiaryInverse; + nscolor textColorHighlight; + nscolor colorForeground; + nscolor colorBackground; + nscolor panelColorForeground; + nscolor panelColorBackground; +} AndroidSystemColors; + +class MessageCursorContinueCallback : public nsICursorContinueCallback +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSICURSORCONTINUECALLBACK + + MessageCursorContinueCallback(int aRequestId) + : mRequestId(aRequestId) + { + } +private: + virtual ~MessageCursorContinueCallback() + { + } + + int mRequestId; +}; + +class AndroidBridge final +{ +public: + enum { + // Values for NotifyIME, in addition to values from the Gecko + // IMEMessage enum; use negative values here to prevent conflict + NOTIFY_IME_OPEN_VKB = -2, + NOTIFY_IME_REPLY_EVENT = -1, + }; + + enum { + LAYER_CLIENT_TYPE_NONE = 0, + LAYER_CLIENT_TYPE_GL = 2 // AndroidGeckoGLLayerClient + }; + + static bool IsJavaUiThread() { + return pthread_equal(pthread_self(), ::getJavaUiThread()); + } + + static void ConstructBridge(); + static void DeconstructBridge(); + + static AndroidBridge *Bridge() { + return sBridge; + } + + void ContentDocumentChanged(mozIDOMWindowProxy* aDOMWindow); + bool IsContentDocumentDisplayed(mozIDOMWindowProxy* aDOMWindow); + + bool GetHandlersForURL(const nsAString& aURL, + nsIMutableArray* handlersArray = nullptr, + nsIHandlerApp **aDefaultApp = nullptr, + const nsAString& aAction = EmptyString()); + + bool GetHandlersForMimeType(const nsAString& aMimeType, + nsIMutableArray* handlersArray = nullptr, + nsIHandlerApp **aDefaultApp = nullptr, + const nsAString& aAction = EmptyString()); + + bool GetHWEncoderCapability(); + bool GetHWDecoderCapability(); + + void GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString& aMimeType); + void GetExtensionFromMimeType(const nsACString& aMimeType, nsACString& aFileExt); + + bool GetClipboardText(nsAString& aText); + + int GetDPI(); + int GetScreenDepth(); + + void Vibrate(const nsTArray<uint32_t>& aPattern); + + void GetSystemColors(AndroidSystemColors *aColors); + + void GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSize, uint8_t * const aBuf); + + bool GetStaticStringField(const char *classID, const char *field, nsAString &result, JNIEnv* env = nullptr); + + bool GetStaticIntField(const char *className, const char *fieldName, int32_t* aInt, JNIEnv* env = nullptr); + + // Returns a global reference to the Context for Fennec's Activity. The + // caller is responsible for ensuring this doesn't leak by calling + // DeleteGlobalRef() when the context is no longer needed. + jobject GetGlobalContextRef(void); + + void HandleGeckoMessage(JSContext* cx, JS::HandleObject message); + + void GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo); + + void GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo); + + // These methods don't use a ScreenOrientation because it's an + // enum and that would require including the header which requires + // include IPC headers which requires including basictypes.h which + // requires a lot of changes... + uint32_t GetScreenOrientation(); + uint16_t GetScreenAngle(); + + int GetAPIVersion() { return mAPIVersion; } + + nsresult GetProxyForURI(const nsACString & aSpec, + const nsACString & aScheme, + const nsACString & aHost, + const int32_t aPort, + nsACString & aResult); + + bool PumpMessageLoop(); + + // Utility methods. + static jstring NewJavaString(JNIEnv* env, const char16_t* string, uint32_t len); + static jstring NewJavaString(JNIEnv* env, const nsAString& string); + static jstring NewJavaString(JNIEnv* env, const char* string); + static jstring NewJavaString(JNIEnv* env, const nsACString& string); + + static jstring NewJavaString(AutoLocalJNIFrame* frame, const char16_t* string, uint32_t len); + static jstring NewJavaString(AutoLocalJNIFrame* frame, const nsAString& string); + static jstring NewJavaString(AutoLocalJNIFrame* frame, const char* string); + static jstring NewJavaString(AutoLocalJNIFrame* frame, const nsACString& string); + + static jfieldID GetFieldID(JNIEnv* env, jclass jClass, const char* fieldName, const char* fieldType); + static jfieldID GetStaticFieldID(JNIEnv* env, jclass jClass, const char* fieldName, const char* fieldType); + static jmethodID GetMethodID(JNIEnv* env, jclass jClass, const char* methodName, const char* methodType); + static jmethodID GetStaticMethodID(JNIEnv* env, jclass jClass, const char* methodName, const char* methodType); + + static jni::Object::LocalRef ChannelCreate(jni::Object::Param); + + static void InputStreamClose(jni::Object::Param obj); + static uint32_t InputStreamAvailable(jni::Object::Param obj); + static nsresult InputStreamRead(jni::Object::Param obj, char *aBuf, uint32_t aCount, uint32_t *aRead); + +protected: + static nsDataHashtable<nsStringHashKey, nsString> sStoragePaths; + + static AndroidBridge* sBridge; + + AndroidBridge(); + ~AndroidBridge(); + + int mAPIVersion; + + // intput stream + jclass jReadableByteChannel; + jclass jChannels; + jmethodID jChannelCreate; + jmethodID jByteBufferRead; + + jclass jInputStream; + jmethodID jClose; + jmethodID jAvailable; + + jmethodID jCalculateLength; + + // some convinient types to have around + jclass jStringClass; + + jni::Object::GlobalRef mMessageQueue; + jfieldID mMessageQueueMessages; + jmethodID mMessageQueueNext; + +private: + class DelayedTask; + nsTArray<DelayedTask> mUiTaskQueue; + mozilla::Mutex mUiTaskQueueLock; + +public: + void PostTaskToUiThread(already_AddRefed<Runnable> aTask, int aDelayMs); + int64_t RunDelayedUiThreadTasks(); +}; + +class AutoJNIClass { +private: + JNIEnv* const mEnv; + const jclass mClass; + +public: + AutoJNIClass(JNIEnv* jEnv, const char* name) + : mEnv(jEnv) + , mClass(jni::GetClassRef(jEnv, name)) + {} + + ~AutoJNIClass() { + mEnv->DeleteLocalRef(mClass); + } + + jclass getRawRef() const { + return mClass; + } + + jclass getGlobalRef() const { + return static_cast<jclass>(mEnv->NewGlobalRef(mClass)); + } + + jfieldID getField(const char* name, const char* type) const { + return AndroidBridge::GetFieldID(mEnv, mClass, name, type); + } + + jfieldID getStaticField(const char* name, const char* type) const { + return AndroidBridge::GetStaticFieldID(mEnv, mClass, name, type); + } + + jmethodID getMethod(const char* name, const char* type) const { + return AndroidBridge::GetMethodID(mEnv, mClass, name, type); + } + + jmethodID getStaticMethod(const char* name, const char* type) const { + return AndroidBridge::GetStaticMethodID(mEnv, mClass, name, type); + } +}; + +class AutoJObject { +public: + AutoJObject(JNIEnv* aJNIEnv = nullptr) : mObject(nullptr) + { + mJNIEnv = aJNIEnv ? aJNIEnv : jni::GetGeckoThreadEnv(); + } + + AutoJObject(JNIEnv* aJNIEnv, jobject aObject) + { + mJNIEnv = aJNIEnv ? aJNIEnv : jni::GetGeckoThreadEnv(); + mObject = aObject; + } + + ~AutoJObject() { + if (mObject) + mJNIEnv->DeleteLocalRef(mObject); + } + + jobject operator=(jobject aObject) + { + if (mObject) { + mJNIEnv->DeleteLocalRef(mObject); + } + return mObject = aObject; + } + + operator jobject() { + return mObject; + } +private: + JNIEnv* mJNIEnv; + jobject mObject; +}; + +class AutoLocalJNIFrame { +public: + AutoLocalJNIFrame(int nEntries = 15) + : mEntries(nEntries) + , mJNIEnv(jni::GetGeckoThreadEnv()) + , mHasFrameBeenPushed(false) + { + MOZ_ASSERT(mJNIEnv); + Push(); + } + + AutoLocalJNIFrame(JNIEnv* aJNIEnv, int nEntries = 15) + : mEntries(nEntries) + , mJNIEnv(aJNIEnv ? aJNIEnv : jni::GetGeckoThreadEnv()) + , mHasFrameBeenPushed(false) + { + MOZ_ASSERT(mJNIEnv); + Push(); + } + + ~AutoLocalJNIFrame() { + if (mHasFrameBeenPushed) { + Pop(); + } + } + + JNIEnv* GetEnv() { + return mJNIEnv; + } + + bool CheckForException() { + if (mJNIEnv->ExceptionCheck()) { + MOZ_CATCH_JNI_EXCEPTION(mJNIEnv); + return true; + } + return false; + } + + // Note! Calling Purge makes all previous local refs created in + // the AutoLocalJNIFrame's scope INVALID; be sure that you locked down + // any local refs that you need to keep around in global refs! + void Purge() { + Pop(); + Push(); + } + + template <typename ReturnType = jobject> + ReturnType Pop(ReturnType aResult = nullptr) { + MOZ_ASSERT(mHasFrameBeenPushed); + mHasFrameBeenPushed = false; + return static_cast<ReturnType>( + mJNIEnv->PopLocalFrame(static_cast<jobject>(aResult))); + } + +private: + void Push() { + MOZ_ASSERT(!mHasFrameBeenPushed); + // Make sure there is enough space to store a local ref to the + // exception. I am not completely sure this is needed, but does + // not hurt. + if (mJNIEnv->PushLocalFrame(mEntries + 1) != 0) { + CheckForException(); + return; + } + mHasFrameBeenPushed = true; + } + + const int mEntries; + JNIEnv* const mJNIEnv; + bool mHasFrameBeenPushed; +}; + +} + +#define NS_ANDROIDBRIDGE_CID \ +{ 0x0FE2321D, 0xEBD9, 0x467D, \ + { 0xA7, 0x43, 0x03, 0xA6, 0x8D, 0x40, 0x59, 0x9E } } + +class nsAndroidBridge final : public nsIAndroidBridge, + public nsIObserver +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIANDROIDBRIDGE + NS_DECL_NSIOBSERVER + + nsAndroidBridge(); + +private: + ~nsAndroidBridge(); + + void AddObservers(); + void RemoveObservers(); + + void UpdateAudioPlayingWindows(uint64_t aWindowId, bool aPlaying); + + nsTArray<uint64_t> mAudioPlayingWindows; + +protected: +}; + +#endif /* AndroidBridge_h__ */ diff --git a/widget/android/AndroidBridgeUtilities.h b/widget/android/AndroidBridgeUtilities.h new file mode 100644 index 000000000..ca8326281 --- /dev/null +++ b/widget/android/AndroidBridgeUtilities.h @@ -0,0 +1,13 @@ +#ifndef ALOG +#if defined(DEBUG) || defined(FORCE_ALOG) +#define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gecko" , ## args) +#else +#define ALOG(args...) ((void)0) +#endif +#endif + +#ifdef DEBUG +#define ALOG_BRIDGE(args...) ALOG(args) +#else +#define ALOG_BRIDGE(args...) ((void)0) +#endif diff --git a/widget/android/AndroidCompositorWidget.cpp b/widget/android/AndroidCompositorWidget.cpp new file mode 100644 index 000000000..91cc08531 --- /dev/null +++ b/widget/android/AndroidCompositorWidget.cpp @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=2 et 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 "AndroidCompositorWidget.h" +#include "nsWindow.h" + +namespace mozilla { +namespace widget { + +void +AndroidCompositorWidget::SetFirstPaintViewport(const LayerIntPoint& aOffset, + const CSSToLayerScale& aZoom, + const CSSRect& aCssPageRect) +{ + auto layerClient = static_cast<nsWindow*>(RealWidget())->GetLayerClient(); + if (!layerClient) { + return; + } + + layerClient->SetFirstPaintViewport( + float(aOffset.x), float(aOffset.y), aZoom.scale, aCssPageRect.x, + aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost()); +} + +void +AndroidCompositorWidget::SyncFrameMetrics(const ParentLayerPoint& aScrollOffset, + const CSSToParentLayerScale& aZoom, + const CSSRect& aCssPageRect, + const CSSRect& aDisplayPort, + const CSSToLayerScale& aPaintedResolution, + bool aLayersUpdated, + int32_t aPaintSyncId, + ScreenMargin& aFixedLayerMargins) +{ + auto layerClient = static_cast<nsWindow*>(RealWidget())->GetLayerClient(); + if (!layerClient) { + return; + } + + // convert the displayport rect from document-relative CSS pixels to + // document-relative device pixels + LayerIntRect dp = gfx::RoundedToInt(aDisplayPort * aPaintedResolution); + + java::ViewTransform::LocalRef viewTransform = layerClient->SyncFrameMetrics( + aScrollOffset.x, aScrollOffset.y, aZoom.scale, + aCssPageRect.x, aCssPageRect.y, + aCssPageRect.XMost(), aCssPageRect.YMost(), + dp.x, dp.y, dp.width, dp.height, + aPaintedResolution.scale, aLayersUpdated, aPaintSyncId); + + MOZ_ASSERT(viewTransform, "No view transform object!"); + + aFixedLayerMargins.top = viewTransform->FixedLayerMarginTop(); + aFixedLayerMargins.right = viewTransform->FixedLayerMarginRight(); + aFixedLayerMargins.bottom = viewTransform->FixedLayerMarginBottom(); + aFixedLayerMargins.left = viewTransform->FixedLayerMarginLeft(); +} + +} // namespace widget +} // namespace mozilla diff --git a/widget/android/AndroidCompositorWidget.h b/widget/android/AndroidCompositorWidget.h new file mode 100644 index 000000000..23076e30d --- /dev/null +++ b/widget/android/AndroidCompositorWidget.h @@ -0,0 +1,44 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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_widget_AndroidCompositorWidget_h +#define mozilla_widget_AndroidCompositorWidget_h + +#include "mozilla/widget/InProcessCompositorWidget.h" + +namespace mozilla { +namespace widget { + +/** + * AndroidCompositorWidget inherits from InProcessCompositorWidget because + * Android does not support OOP compositing yet. Once it does, + * AndroidCompositorWidget will be made to inherit from CompositorWidget + * instead. + */ +class AndroidCompositorWidget final : public InProcessCompositorWidget +{ +public: + using InProcessCompositorWidget::InProcessCompositorWidget; + + AndroidCompositorWidget* AsAndroid() override { return this; } + + void SetFirstPaintViewport(const LayerIntPoint& aOffset, + const CSSToLayerScale& aZoom, + const CSSRect& aCssPageRect); + + void SyncFrameMetrics(const ParentLayerPoint& aScrollOffset, + const CSSToParentLayerScale& aZoom, + const CSSRect& aCssPageRect, + const CSSRect& aDisplayPort, + const CSSToLayerScale& aPaintedResolution, + bool aLayersUpdated, + int32_t aPaintSyncId, + ScreenMargin& aFixedLayerMargins); +}; + +} // namespace widget +} // namespace mozilla + +#endif // mozilla_widget_AndroidCompositorWidget_h diff --git a/widget/android/AndroidContentController.cpp b/widget/android/AndroidContentController.cpp new file mode 100644 index 000000000..1df053afb --- /dev/null +++ b/widget/android/AndroidContentController.cpp @@ -0,0 +1,157 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 "AndroidContentController.h" + +#include "AndroidBridge.h" +#include "base/message_loop.h" +#include "mozilla/layers/APZCCallbackHelper.h" +#include "mozilla/layers/IAPZCTreeManager.h" +#include "nsIObserverService.h" +#include "nsLayoutUtils.h" +#include "nsWindow.h" + +using mozilla::layers::IAPZCTreeManager; + +namespace mozilla { +namespace widget { + +void +AndroidContentController::Destroy() +{ + mAndroidWindow = nullptr; + ChromeProcessController::Destroy(); +} + +void +AndroidContentController::NotifyDefaultPrevented(IAPZCTreeManager* aManager, + uint64_t aInputBlockId, + bool aDefaultPrevented) +{ + if (!AndroidBridge::IsJavaUiThread()) { + // The notification must reach the APZ on the Java UI thread (aka the + // APZ "controller" thread) but we get it from the Gecko thread, so we + // have to throw it onto the other thread. + AndroidBridge::Bridge()->PostTaskToUiThread(NewRunnableMethod<uint64_t, bool>( + aManager, &IAPZCTreeManager::ContentReceivedInputBlock, + aInputBlockId, aDefaultPrevented), 0); + return; + } + + aManager->ContentReceivedInputBlock(aInputBlockId, aDefaultPrevented); +} + +void +AndroidContentController::DispatchSingleTapToObservers(const LayoutDevicePoint& aPoint, + const ScrollableLayerGuid& aGuid) const +{ + nsIContent* content = nsLayoutUtils::FindContentFor(aGuid.mScrollId); + nsPresContext* context = content + ? mozilla::layers::APZCCallbackHelper::GetPresContextForContent(content) + : nullptr; + + if (!context) { + return; + } + + CSSPoint point = mozilla::layers::APZCCallbackHelper::ApplyCallbackTransform( + aPoint / context->CSSToDevPixelScale(), aGuid); + + nsPresContext* rcdContext = context->GetToplevelContentDocumentPresContext(); + if (rcdContext && rcdContext->PresShell()->ScaleToResolution()) { + // We need to convert from the root document to the root content document, + // by unapplying the resolution that's on the content document. + const float resolution = rcdContext->PresShell()->GetResolution(); + point.x /= resolution; + point.y /= resolution; + } + + CSSIntPoint rounded = RoundedToInt(point); + nsAppShell::PostEvent([rounded] { + nsCOMPtr<nsIObserverService> obsServ = + mozilla::services::GetObserverService(); + if (!obsServ) { + return; + } + + nsPrintfCString data("{\"x\":%d,\"y\":%d}", rounded.x, rounded.y); + obsServ->NotifyObservers(nullptr, "Gesture:SingleTap", + NS_ConvertASCIItoUTF16(data).get()); + }); +} + +void +AndroidContentController::HandleTap(TapType aType, const LayoutDevicePoint& aPoint, + Modifiers aModifiers, + const ScrollableLayerGuid& aGuid, + uint64_t aInputBlockId) +{ + // This function will get invoked first on the Java UI thread, and then + // again on the main thread (because of the code in ChromeProcessController:: + // HandleTap). We want to post the SingleTap message once; it can be + // done from either thread but we need access to the callback transform + // so we do it from the main thread. + if (NS_IsMainThread() && + (aType == TapType::eSingleTap || aType == TapType::eSecondTap)) { + DispatchSingleTapToObservers(aPoint, aGuid); + } + + ChromeProcessController::HandleTap(aType, aPoint, aModifiers, aGuid, aInputBlockId); +} + +void +AndroidContentController::PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) +{ + AndroidBridge::Bridge()->PostTaskToUiThread(Move(aTask), aDelayMs); +} +void +AndroidContentController::UpdateOverscrollVelocity(const float aX, const float aY, const bool aIsRootContent) +{ + if (aIsRootContent && mAndroidWindow) { + mAndroidWindow->UpdateOverscrollVelocity(aX, aY); + } +} + +void +AndroidContentController::UpdateOverscrollOffset(const float aX, const float aY, const bool aIsRootContent) +{ + if (aIsRootContent && mAndroidWindow) { + mAndroidWindow->UpdateOverscrollOffset(aX, aY); + } +} + +void +AndroidContentController::SetScrollingRootContent(const bool isRootContent) +{ + if (mAndroidWindow) { + mAndroidWindow->SetScrollingRootContent(isRootContent); + } +} + +void +AndroidContentController::NotifyAPZStateChange(const ScrollableLayerGuid& aGuid, + APZStateChange aChange, + int aArg) +{ + // This function may get invoked twice, if the first invocation is not on + // the main thread then the ChromeProcessController version of this function + // will redispatch to the main thread. We want to make sure that our handling + // only happens on the main thread. + ChromeProcessController::NotifyAPZStateChange(aGuid, aChange, aArg); + if (NS_IsMainThread()) { + nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService(); + if (aChange == layers::GeckoContentController::APZStateChange::eTransformEnd) { + // This is used by tests to determine when the APZ is done doing whatever + // it's doing. XXX generify this as needed when writing additional tests. + observerService->NotifyObservers(nullptr, "APZ:TransformEnd", nullptr); + observerService->NotifyObservers(nullptr, "PanZoom:StateChange", u"NOTHING"); + } else if (aChange == layers::GeckoContentController::APZStateChange::eTransformBegin) { + observerService->NotifyObservers(nullptr, "PanZoom:StateChange", u"PANNING"); + } + } +} + +} // namespace widget +} // namespace mozilla diff --git a/widget/android/AndroidContentController.h b/widget/android/AndroidContentController.h new file mode 100644 index 000000000..39674c939 --- /dev/null +++ b/widget/android/AndroidContentController.h @@ -0,0 +1,59 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 AndroidContentController_h__ +#define AndroidContentController_h__ + +#include "mozilla/layers/ChromeProcessController.h" +#include "mozilla/EventForwards.h" // for Modifiers +#include "mozilla/StaticPtr.h" +#include "mozilla/TimeStamp.h" +#include "nsIDOMWindowUtils.h" +#include "nsTArray.h" +#include "nsWindow.h" + +namespace mozilla { +namespace layers { +class APZEventState; +class IAPZCTreeManager; +} +namespace widget { + +class AndroidContentController final + : public mozilla::layers::ChromeProcessController +{ +public: + AndroidContentController(nsWindow* aWindow, + mozilla::layers::APZEventState* aAPZEventState, + mozilla::layers::IAPZCTreeManager* aAPZCTreeManager) + : mozilla::layers::ChromeProcessController(aWindow, aAPZEventState, aAPZCTreeManager) + , mAndroidWindow(aWindow) + {} + + // ChromeProcessController methods + virtual void Destroy() override; + void HandleTap(TapType aType, const LayoutDevicePoint& aPoint, Modifiers aModifiers, + const ScrollableLayerGuid& aGuid, uint64_t aInputBlockId) override; + void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) override; + void UpdateOverscrollVelocity(const float aX, const float aY, const bool aIsRootContent) override; + void UpdateOverscrollOffset(const float aX, const float aY, const bool aIsRootContent) override; + void SetScrollingRootContent(const bool isRootContent) override; + void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid, + APZStateChange aChange, + int aArg) override; + + static void NotifyDefaultPrevented(mozilla::layers::IAPZCTreeManager* aManager, + uint64_t aInputBlockId, bool aDefaultPrevented); +private: + nsWindow* mAndroidWindow; + + void DispatchSingleTapToObservers(const LayoutDevicePoint& aPoint, + const ScrollableLayerGuid& aGuid) const; +}; + +} // namespace widget +} // namespace mozilla + +#endif diff --git a/widget/android/AndroidDirectTexture.h b/widget/android/AndroidDirectTexture.h new file mode 100644 index 000000000..8582b8582 --- /dev/null +++ b/widget/android/AndroidDirectTexture.h @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * 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 AndroidDirectTexture_h_ +#define AndroidDirectTexture_h_ + +#include "gfxTypes.h" +#include "mozilla/Mutex.h" +#include "AndroidGraphicBuffer.h" +#include "nsRect.h" + +namespace mozilla { + +/** + * This is a thread safe wrapper around AndroidGraphicBuffer that handles + * double buffering. Each call to Bind() flips the buffer when necessary. + * + * You need to be careful when destroying an instance of this class. If either + * buffer is locked by the application of the driver/hardware, bad things will + * happen. Be sure that the OpenGL texture is no longer on the screen. + */ +class AndroidDirectTexture +{ +public: + AndroidDirectTexture(uint32_t width, uint32_t height, uint32_t usage, gfxImageFormat format); + virtual ~AndroidDirectTexture(); + + bool Lock(uint32_t usage, unsigned char **bits); + bool Lock(uint32_t usage, const nsIntRect& rect, unsigned char **bits); + bool Unlock(bool aFlip = true); + + bool Reallocate(uint32_t aWidth, uint32_t aHeight); + bool Reallocate(uint32_t aWidth, uint32_t aHeight, gfxImageFormat aFormat); + + uint32_t Width() { return mWidth; } + uint32_t Height() { return mHeight; } + + bool Bind(); + +private: + mozilla::Mutex mLock; + bool mNeedFlip; + + uint32_t mWidth; + uint32_t mHeight; + gfxImageFormat mFormat; + + AndroidGraphicBuffer* mFrontBuffer; + AndroidGraphicBuffer* mBackBuffer; + + AndroidGraphicBuffer* mPendingReallocBuffer; + void ReallocPendingBuffer(); +}; + +} /* mozilla */ +#endif /* AndroidDirectTexture_h_ */ diff --git a/widget/android/AndroidGraphicBuffer.h b/widget/android/AndroidGraphicBuffer.h new file mode 100644 index 000000000..269f8680a --- /dev/null +++ b/widget/android/AndroidGraphicBuffer.h @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * 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 AndroidGraphicBuffer_h_ +#define AndroidGraphicBuffer_h_ + +#include "gfxTypes.h" +#include "nsRect.h" + +typedef void* EGLImageKHR; +typedef void* EGLClientBuffer; + +namespace mozilla { + +/** + * This class allows access to Android's direct texturing mechanism. Locking + * the buffer gives you a pointer you can read/write to directly. It is fully + * threadsafe, but you probably really want to use the AndroidDirectTexture + * class which will handle double buffering. + * + * In order to use the buffer in OpenGL, just call Bind() and it will attach + * to whatever texture is bound to GL_TEXTURE_2D. + */ +class AndroidGraphicBuffer +{ +public: + enum { + UsageSoftwareRead = 1, + UsageSoftwareWrite = 1 << 1, + UsageTexture = 1 << 2, + UsageTarget = 1 << 3, + Usage2D = 1 << 4 + }; + + AndroidGraphicBuffer(uint32_t width, uint32_t height, uint32_t usage, gfxImageFormat format); + virtual ~AndroidGraphicBuffer(); + + int Lock(uint32_t usage, unsigned char **bits); + int Lock(uint32_t usage, const nsIntRect& rect, unsigned char **bits); + int Unlock(); + bool Reallocate(uint32_t aWidth, uint32_t aHeight, gfxImageFormat aFormat); + + uint32_t Width() { return mWidth; } + uint32_t Height() { return mHeight; } + + bool Bind(); + + static bool IsBlacklisted(); + +private: + uint32_t mWidth; + uint32_t mHeight; + uint32_t mUsage; + gfxImageFormat mFormat; + + bool EnsureInitialized(); + bool EnsureEGLImage(); + + void DestroyBuffer(); + bool EnsureBufferCreated(); + + uint32_t GetAndroidUsage(uint32_t aUsage); + uint32_t GetAndroidFormat(gfxImageFormat aFormat); + + void *mHandle; + void *mEGLImage; +}; + +} /* mozilla */ +#endif /* AndroidGraphicBuffer_h_ */ diff --git a/widget/android/AndroidJNI.cpp b/widget/android/AndroidJNI.cpp new file mode 100644 index 000000000..3e27d253b --- /dev/null +++ b/widget/android/AndroidJNI.cpp @@ -0,0 +1,47 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 "mozilla/Hal.h" +#include "nsIFile.h" +#include "nsString.h" + +#include "AndroidBridge.h" +#include "AndroidContentController.h" +#include "AndroidGraphicBuffer.h" + +#include <jni.h> +#include <pthread.h> +#include <dlfcn.h> +#include <stdio.h> +#include <unistd.h> + +#include "nsAppShell.h" +#include "nsWindow.h" +#include <android/log.h> +#include "nsIObserverService.h" +#include "mozilla/Services.h" +#include "nsThreadUtils.h" + +#include "mozilla/Unused.h" +#include "mozilla/MathAlgorithms.h" +#include "mozilla/UniquePtr.h" + +#include "mozilla/layers/APZCTreeManager.h" +#include "nsPluginInstanceOwner.h" +#include "AndroidSurfaceTexture.h" + +using namespace mozilla; +using namespace mozilla::dom; +using namespace mozilla::layers; +using namespace mozilla::widget; + +/* Forward declare all the JNI methods as extern "C" */ + +extern "C" { +/* + * Incoming JNI methods + */ + +} diff --git a/widget/android/AndroidJNIWrapper.cpp b/widget/android/AndroidJNIWrapper.cpp new file mode 100644 index 000000000..e549c6fc7 --- /dev/null +++ b/widget/android/AndroidJNIWrapper.cpp @@ -0,0 +1,140 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 <android/log.h> +#include <dlfcn.h> +#include <prthread.h> + +#include "mozilla/DebugOnly.h" +#include "mozilla/Assertions.h" +#include "mozilla/SyncRunnable.h" +#include "nsThreadUtils.h" +#include "AndroidBridge.h" + +extern "C" { + jclass __jsjni_GetGlobalClassRef(const char *className); +} + +class GetGlobalClassRefRunnable : public mozilla::Runnable { + public: + GetGlobalClassRefRunnable(const char *className, jclass *foundClass) : + mClassName(className), mResult(foundClass) {} + NS_IMETHOD Run() override { + *mResult = __jsjni_GetGlobalClassRef(mClassName); + return NS_OK; + } + private: + const char *mClassName; + jclass *mResult; +}; + +extern "C" { + __attribute__ ((visibility("default"))) + jclass + jsjni_FindClass(const char *className) { + // FindClass outside the main thread will run into problems due + // to missing the classpath + MOZ_ASSERT(NS_IsMainThread()); + JNIEnv *env = mozilla::jni::GetGeckoThreadEnv(); + return env->FindClass(className); + } + + jclass + __jsjni_GetGlobalClassRef(const char *className) { + // root class globally + JNIEnv *env = mozilla::jni::GetGeckoThreadEnv(); + jclass globalRef = static_cast<jclass>(env->NewGlobalRef(env->FindClass(className))); + if (!globalRef) + return nullptr; + + // return the newly create global reference + return globalRef; + } + + __attribute__ ((visibility("default"))) + jclass + jsjni_GetGlobalClassRef(const char *className) { + if (NS_IsMainThread()) { + return __jsjni_GetGlobalClassRef(className); + } + + nsCOMPtr<nsIThread> mainThread; + mozilla::DebugOnly<nsresult> rv = NS_GetMainThread(getter_AddRefs(mainThread)); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + + jclass foundClass; + nsCOMPtr<nsIRunnable> runnable_ref(new GetGlobalClassRefRunnable(className, + &foundClass)); + RefPtr<mozilla::SyncRunnable> sr = new mozilla::SyncRunnable(runnable_ref); + sr->DispatchToThread(mainThread); + if (!foundClass) + return nullptr; + + return foundClass; + } + + __attribute__ ((visibility("default"))) + jmethodID + jsjni_GetStaticMethodID(jclass methodClass, + const char *methodName, + const char *signature) { + JNIEnv *env = mozilla::jni::GetGeckoThreadEnv(); + return env->GetStaticMethodID(methodClass, methodName, signature); + } + + __attribute__ ((visibility("default"))) + bool + jsjni_ExceptionCheck() { + JNIEnv *env = mozilla::jni::GetGeckoThreadEnv(); + return env->ExceptionCheck(); + } + + __attribute__ ((visibility("default"))) + void + jsjni_CallStaticVoidMethodA(jclass cls, + jmethodID method, + jvalue *values) { + JNIEnv *env = mozilla::jni::GetGeckoThreadEnv(); + + mozilla::AutoLocalJNIFrame jniFrame(env); + env->CallStaticVoidMethodA(cls, method, values); + } + + __attribute__ ((visibility("default"))) + int + jsjni_CallStaticIntMethodA(jclass cls, + jmethodID method, + jvalue *values) { + JNIEnv *env = mozilla::jni::GetGeckoThreadEnv(); + + mozilla::AutoLocalJNIFrame jniFrame(env); + return env->CallStaticIntMethodA(cls, method, values); + } + + __attribute__ ((visibility("default"))) + jobject jsjni_GetGlobalContextRef() { + return mozilla::AndroidBridge::Bridge()->GetGlobalContextRef(); + } + + __attribute__ ((visibility("default"))) + JavaVM* jsjni_GetVM() { + JavaVM* jvm; + JNIEnv* const env = mozilla::jni::GetGeckoThreadEnv(); + MOZ_ALWAYS_TRUE(!env->GetJavaVM(&jvm)); + return jvm; + } + + __attribute__ ((visibility("default"))) + JNIEnv* jsjni_GetJNIForThread() { + return mozilla::jni::GetEnvForThread(); + } + + // For compatibility with JNI.jsm; some addons bundle their own JNI.jsm, + // so we cannot just change the function name used in JNI.jsm. + __attribute__ ((visibility("default"))) + JNIEnv* GetJNIForThread() { + return mozilla::jni::GetEnvForThread(); + } +} diff --git a/widget/android/AndroidJNIWrapper.h b/widget/android/AndroidJNIWrapper.h new file mode 100644 index 000000000..90bca2693 --- /dev/null +++ b/widget/android/AndroidJNIWrapper.h @@ -0,0 +1,34 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 AndroidJNIWrapper_h__ +#define AndroidJNIWrapper_h__ + +#include "mozilla/Types.h" +#include <jni.h> +#include <android/log.h> + +extern "C" MOZ_EXPORT jclass jsjni_FindClass(const char *className); + +/** + * JNIEnv::FindClass alternative. + * Callable from any thread, including code + * invoked via the JNI that doesn't have MOZILLA_INTERNAL_API defined. + * The caller is responsible for ensuring that the class is not leaked by + * calling DeleteGlobalRef at an appropriate time. + */ +extern "C" MOZ_EXPORT jclass jsjni_GetGlobalClassRef(const char *className); + +extern "C" MOZ_EXPORT jmethodID jsjni_GetStaticMethodID(jclass methodClass, + const char *methodName, + const char *signature); +extern "C" MOZ_EXPORT bool jsjni_ExceptionCheck(); +extern "C" MOZ_EXPORT void jsjni_CallStaticVoidMethodA(jclass cls, jmethodID method, jvalue *values); +extern "C" MOZ_EXPORT int jsjni_CallStaticIntMethodA(jclass cls, jmethodID method, jvalue *values); +extern "C" MOZ_EXPORT jobject jsjni_GetGlobalContextRef(); +extern "C" MOZ_EXPORT JavaVM* jsjni_GetVM(); +extern "C" MOZ_EXPORT JNIEnv* jsjni_GetJNIForThread(); + +#endif /* AndroidJNIWrapper_h__ */ diff --git a/widget/android/AndroidJavaWrappers.cpp b/widget/android/AndroidJavaWrappers.cpp new file mode 100644 index 000000000..eb657a9c4 --- /dev/null +++ b/widget/android/AndroidJavaWrappers.cpp @@ -0,0 +1,62 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 "AndroidJavaWrappers.h" + +using namespace mozilla; + +nsJNIString::nsJNIString(jstring jstr, JNIEnv *jenv) +{ + if (!jstr) { + SetIsVoid(true); + return; + } + JNIEnv *jni = jenv; + if (!jni) { + jni = jni::GetGeckoThreadEnv(); + } + const jchar* jCharPtr = jni->GetStringChars(jstr, nullptr); + + if (!jCharPtr) { + SetIsVoid(true); + return; + } + + jsize len = jni->GetStringLength(jstr); + + if (len <= 0) { + SetIsVoid(true); + } else { + Assign(reinterpret_cast<const char16_t*>(jCharPtr), len); + } + jni->ReleaseStringChars(jstr, jCharPtr); +} + +nsJNICString::nsJNICString(jstring jstr, JNIEnv *jenv) +{ + if (!jstr) { + SetIsVoid(true); + return; + } + JNIEnv *jni = jenv; + if (!jni) { + jni = jni::GetGeckoThreadEnv(); + } + const char* jCharPtr = jni->GetStringUTFChars(jstr, nullptr); + + if (!jCharPtr) { + SetIsVoid(true); + return; + } + + jsize len = jni->GetStringUTFLength(jstr); + + if (len <= 0) { + SetIsVoid(true); + } else { + Assign(jCharPtr, len); + } + jni->ReleaseStringUTFChars(jstr, jCharPtr); +} diff --git a/widget/android/AndroidJavaWrappers.h b/widget/android/AndroidJavaWrappers.h new file mode 100644 index 000000000..fadf97353 --- /dev/null +++ b/widget/android/AndroidJavaWrappers.h @@ -0,0 +1,218 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 AndroidJavaWrappers_h__ +#define AndroidJavaWrappers_h__ + +#include <jni.h> +#include <android/input.h> +#include <android/log.h> +#include <android/api-level.h> + +#include "nsRect.h" +#include "nsString.h" +#include "nsTArray.h" +#include "nsIAndroidBridge.h" +#include "mozilla/gfx/Rect.h" +#include "mozilla/dom/Touch.h" +#include "mozilla/EventForwards.h" +#include "InputData.h" +#include "Units.h" +#include "FrameMetrics.h" + +//#define FORCE_ALOG 1 + +class nsIAndroidDisplayport; +class nsIWidget; + +namespace mozilla { + +enum { + // These keycode masks are not defined in android/keycodes.h: +#if __ANDROID_API__ < 13 + AKEYCODE_ESCAPE = 111, + AKEYCODE_FORWARD_DEL = 112, + AKEYCODE_CTRL_LEFT = 113, + AKEYCODE_CTRL_RIGHT = 114, + AKEYCODE_CAPS_LOCK = 115, + AKEYCODE_SCROLL_LOCK = 116, + AKEYCODE_META_LEFT = 117, + AKEYCODE_META_RIGHT = 118, + AKEYCODE_FUNCTION = 119, + AKEYCODE_SYSRQ = 120, + AKEYCODE_BREAK = 121, + AKEYCODE_MOVE_HOME = 122, + AKEYCODE_MOVE_END = 123, + AKEYCODE_INSERT = 124, + AKEYCODE_FORWARD = 125, + AKEYCODE_MEDIA_PLAY = 126, + AKEYCODE_MEDIA_PAUSE = 127, + AKEYCODE_MEDIA_CLOSE = 128, + AKEYCODE_MEDIA_EJECT = 129, + AKEYCODE_MEDIA_RECORD = 130, + AKEYCODE_F1 = 131, + AKEYCODE_F2 = 132, + AKEYCODE_F3 = 133, + AKEYCODE_F4 = 134, + AKEYCODE_F5 = 135, + AKEYCODE_F6 = 136, + AKEYCODE_F7 = 137, + AKEYCODE_F8 = 138, + AKEYCODE_F9 = 139, + AKEYCODE_F10 = 140, + AKEYCODE_F11 = 141, + AKEYCODE_F12 = 142, + AKEYCODE_NUM_LOCK = 143, + AKEYCODE_NUMPAD_0 = 144, + AKEYCODE_NUMPAD_1 = 145, + AKEYCODE_NUMPAD_2 = 146, + AKEYCODE_NUMPAD_3 = 147, + AKEYCODE_NUMPAD_4 = 148, + AKEYCODE_NUMPAD_5 = 149, + AKEYCODE_NUMPAD_6 = 150, + AKEYCODE_NUMPAD_7 = 151, + AKEYCODE_NUMPAD_8 = 152, + AKEYCODE_NUMPAD_9 = 153, + AKEYCODE_NUMPAD_DIVIDE = 154, + AKEYCODE_NUMPAD_MULTIPLY = 155, + AKEYCODE_NUMPAD_SUBTRACT = 156, + AKEYCODE_NUMPAD_ADD = 157, + AKEYCODE_NUMPAD_DOT = 158, + AKEYCODE_NUMPAD_COMMA = 159, + AKEYCODE_NUMPAD_ENTER = 160, + AKEYCODE_NUMPAD_EQUALS = 161, + AKEYCODE_NUMPAD_LEFT_PAREN = 162, + AKEYCODE_NUMPAD_RIGHT_PAREN = 163, + AKEYCODE_VOLUME_MUTE = 164, + AKEYCODE_INFO = 165, + AKEYCODE_CHANNEL_UP = 166, + AKEYCODE_CHANNEL_DOWN = 167, + AKEYCODE_ZOOM_IN = 168, + AKEYCODE_ZOOM_OUT = 169, + AKEYCODE_TV = 170, + AKEYCODE_WINDOW = 171, + AKEYCODE_GUIDE = 172, + AKEYCODE_DVR = 173, + AKEYCODE_BOOKMARK = 174, + AKEYCODE_CAPTIONS = 175, + AKEYCODE_SETTINGS = 176, + AKEYCODE_TV_POWER = 177, + AKEYCODE_TV_INPUT = 178, + AKEYCODE_STB_POWER = 179, + AKEYCODE_STB_INPUT = 180, + AKEYCODE_AVR_POWER = 181, + AKEYCODE_AVR_INPUT = 182, + AKEYCODE_PROG_RED = 183, + AKEYCODE_PROG_GREEN = 184, + AKEYCODE_PROG_YELLOW = 185, + AKEYCODE_PROG_BLUE = 186, + AKEYCODE_APP_SWITCH = 187, + AKEYCODE_BUTTON_1 = 188, + AKEYCODE_BUTTON_2 = 189, + AKEYCODE_BUTTON_3 = 190, + AKEYCODE_BUTTON_4 = 191, + AKEYCODE_BUTTON_5 = 192, + AKEYCODE_BUTTON_6 = 193, + AKEYCODE_BUTTON_7 = 194, + AKEYCODE_BUTTON_8 = 195, + AKEYCODE_BUTTON_9 = 196, + AKEYCODE_BUTTON_10 = 197, + AKEYCODE_BUTTON_11 = 198, + AKEYCODE_BUTTON_12 = 199, + AKEYCODE_BUTTON_13 = 200, + AKEYCODE_BUTTON_14 = 201, + AKEYCODE_BUTTON_15 = 202, + AKEYCODE_BUTTON_16 = 203, +#endif +#if __ANDROID_API__ < 14 + AKEYCODE_LANGUAGE_SWITCH = 204, + AKEYCODE_MANNER_MODE = 205, + AKEYCODE_3D_MODE = 206, +#endif +#if __ANDROID_API__ < 15 + AKEYCODE_CONTACTS = 207, + AKEYCODE_CALENDAR = 208, + AKEYCODE_MUSIC = 209, + AKEYCODE_CALCULATOR = 210, +#endif +#if __ANDROID_API__ < 16 + AKEYCODE_ZENKAKU_HANKAKU = 211, + AKEYCODE_EISU = 212, + AKEYCODE_MUHENKAN = 213, + AKEYCODE_HENKAN = 214, + AKEYCODE_KATAKANA_HIRAGANA = 215, + AKEYCODE_YEN = 216, + AKEYCODE_RO = 217, + AKEYCODE_KANA = 218, + AKEYCODE_ASSIST = 219, +#endif + + AMETA_FUNCTION_ON = 0x00000008, + AMETA_CTRL_ON = 0x00001000, + AMETA_CTRL_LEFT_ON = 0x00002000, + AMETA_CTRL_RIGHT_ON = 0x00004000, + AMETA_META_ON = 0x00010000, + AMETA_META_LEFT_ON = 0x00020000, + AMETA_META_RIGHT_ON = 0x00040000, + AMETA_CAPS_LOCK_ON = 0x00100000, + AMETA_NUM_LOCK_ON = 0x00200000, + AMETA_SCROLL_LOCK_ON = 0x00400000, + + AMETA_ALT_MASK = AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON | AMETA_ALT_ON, + AMETA_CTRL_MASK = AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON | AMETA_CTRL_ON, + AMETA_META_MASK = AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON | AMETA_META_ON, + AMETA_SHIFT_MASK = AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON | AMETA_SHIFT_ON, +}; + +class AndroidMotionEvent +{ +public: + enum { + ACTION_DOWN = 0, + ACTION_UP = 1, + ACTION_MOVE = 2, + ACTION_CANCEL = 3, + ACTION_OUTSIDE = 4, + ACTION_POINTER_DOWN = 5, + ACTION_POINTER_UP = 6, + ACTION_HOVER_MOVE = 7, + ACTION_HOVER_ENTER = 9, + ACTION_HOVER_EXIT = 10, + ACTION_MAGNIFY_START = 11, + ACTION_MAGNIFY = 12, + ACTION_MAGNIFY_END = 13, + EDGE_TOP = 0x00000001, + EDGE_BOTTOM = 0x00000002, + EDGE_LEFT = 0x00000004, + EDGE_RIGHT = 0x00000008, + SAMPLE_X = 0, + SAMPLE_Y = 1, + SAMPLE_PRESSURE = 2, + SAMPLE_SIZE = 3, + NUM_SAMPLE_DATA = 4, + TOOL_TYPE_UNKNOWN = 0, + TOOL_TYPE_FINGER = 1, + TOOL_TYPE_STYLUS = 2, + TOOL_TYPE_MOUSE = 3, + TOOL_TYPE_ERASER = 4, + dummy_java_enum_list_end + }; +}; + +class nsJNIString : public nsString +{ +public: + nsJNIString(jstring jstr, JNIEnv *jenv); +}; + +class nsJNICString : public nsCString +{ +public: + nsJNICString(jstring jstr, JNIEnv *jenv); +}; + +} + +#endif diff --git a/widget/android/GeckoBatteryManager.h b/widget/android/GeckoBatteryManager.h new file mode 100644 index 000000000..a09e83efd --- /dev/null +++ b/widget/android/GeckoBatteryManager.h @@ -0,0 +1,30 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 GeckoBatteryManager_h +#define GeckoBatteryManager_h + +#include "GeneratedJNINatives.h" +#include "nsAppShell.h" + +#include "mozilla/Hal.h" + +namespace mozilla { + +class GeckoBatteryManager final + : public java::GeckoBatteryManager::Natives<GeckoBatteryManager> +{ +public: + static void + OnBatteryChange(double aLevel, bool aCharging, double aRemainingTime) + { + hal::NotifyBatteryChange( + hal::BatteryInformation(aLevel, aCharging, aRemainingTime)); + } +}; + +} // namespace mozilla + +#endif // GeckoBatteryManager_h diff --git a/widget/android/GeckoNetworkManager.h b/widget/android/GeckoNetworkManager.h new file mode 100644 index 000000000..63cbb9c79 --- /dev/null +++ b/widget/android/GeckoNetworkManager.h @@ -0,0 +1,53 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 GeckoNetworkManager_h +#define GeckoNetworkManager_h + +#include "GeneratedJNINatives.h" +#include "nsAppShell.h" +#include "nsCOMPtr.h" +#include "nsINetworkLinkService.h" + +#include "mozilla/Services.h" + +namespace mozilla { + +class GeckoNetworkManager final + : public java::GeckoNetworkManager::Natives<GeckoNetworkManager> +{ + GeckoNetworkManager() = delete; + +public: + static void + OnConnectionChanged(int32_t aType, jni::String::Param aSubType, + bool aIsWifi, int32_t aGateway) + { + hal::NotifyNetworkChange(hal::NetworkInformation( + aType, aIsWifi, aGateway)); + + nsCOMPtr<nsIObserverService> os = services::GetObserverService(); + if (os) { + os->NotifyObservers(nullptr, + NS_NETWORK_LINK_TYPE_TOPIC, + aSubType->ToString().get()); + } + } + + static void + OnStatusChanged(jni::String::Param aStatus) + { + nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); + if (os) { + os->NotifyObservers(nullptr, + NS_NETWORK_LINK_TOPIC, + aStatus->ToString().get()); + } + } +}; + +} // namespace mozilla + +#endif // GeckoNetworkManager_h diff --git a/widget/android/GeckoScreenOrientation.h b/widget/android/GeckoScreenOrientation.h new file mode 100644 index 000000000..c6e5861be --- /dev/null +++ b/widget/android/GeckoScreenOrientation.h @@ -0,0 +1,55 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 GeckoScreenOrientation_h +#define GeckoScreenOrientation_h + +#include "GeneratedJNINatives.h" +#include "nsAppShell.h" +#include "nsCOMPtr.h" +#include "nsIScreenManager.h" + +#include "mozilla/Hal.h" +#include "mozilla/dom/ScreenOrientation.h" + +namespace mozilla { + +class GeckoScreenOrientation final + : public java::GeckoScreenOrientation::Natives<GeckoScreenOrientation> +{ + GeckoScreenOrientation() = delete; + +public: + static void + OnOrientationChange(int16_t aOrientation, int16_t aAngle) + { + nsCOMPtr<nsIScreenManager> screenMgr = + do_GetService("@mozilla.org/gfx/screenmanager;1"); + nsCOMPtr<nsIScreen> screen; + + if (!screenMgr || NS_FAILED(screenMgr->GetPrimaryScreen( + getter_AddRefs(screen))) || !screen) { + return; + } + + nsIntRect rect; + int32_t colorDepth, pixelDepth; + + if (NS_FAILED(screen->GetRect(&rect.x, &rect.y, + &rect.width, &rect.height)) || + NS_FAILED(screen->GetColorDepth(&colorDepth)) || + NS_FAILED(screen->GetPixelDepth(&pixelDepth))) { + return; + } + + hal::NotifyScreenConfigurationChange(hal::ScreenConfiguration( + rect, static_cast<dom::ScreenOrientationInternal>(aOrientation), + aAngle, colorDepth, pixelDepth)); + } +}; + +} // namespace mozilla + +#endif // GeckoScreenOrientation_h diff --git a/widget/android/GeneratedJNINatives.h b/widget/android/GeneratedJNINatives.h new file mode 100644 index 000000000..bce88ce65 --- /dev/null +++ b/widget/android/GeneratedJNINatives.h @@ -0,0 +1,526 @@ +// GENERATED CODE +// Generated by the Java program at /build/annotationProcessors at compile time +// from annotations on Java methods. To update, change the annotations on the +// corresponding Java methods and rerun the build. Manually updating this file +// will cause your build to fail. + +#ifndef GeneratedJNINatives_h +#define GeneratedJNINatives_h + +#include "GeneratedJNIWrappers.h" +#include "mozilla/jni/Natives.h" + +namespace mozilla { +namespace java { + +template<class Impl> +class AlarmReceiver::Natives : public mozilla::jni::NativeImpl<AlarmReceiver, Impl> +{ +public: + static const JNINativeMethod methods[1]; +}; + +template<class Impl> +const JNINativeMethod AlarmReceiver::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<AlarmReceiver::NotifyAlarmFired_t>( + mozilla::jni::NativeStub<AlarmReceiver::NotifyAlarmFired_t, Impl> + ::template Wrap<&Impl::NotifyAlarmFired>) +}; + +template<class Impl> +class AndroidGamepadManager::Natives : public mozilla::jni::NativeImpl<AndroidGamepadManager, Impl> +{ +public: + static const JNINativeMethod methods[3]; +}; + +template<class Impl> +const JNINativeMethod AndroidGamepadManager::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<AndroidGamepadManager::OnAxisChange_t>( + mozilla::jni::NativeStub<AndroidGamepadManager::OnAxisChange_t, Impl> + ::template Wrap<&Impl::OnAxisChange>), + + mozilla::jni::MakeNativeMethod<AndroidGamepadManager::OnButtonChange_t>( + mozilla::jni::NativeStub<AndroidGamepadManager::OnButtonChange_t, Impl> + ::template Wrap<&Impl::OnButtonChange>), + + mozilla::jni::MakeNativeMethod<AndroidGamepadManager::OnGamepadChange_t>( + mozilla::jni::NativeStub<AndroidGamepadManager::OnGamepadChange_t, Impl> + ::template Wrap<&Impl::OnGamepadChange>) +}; + +template<class Impl> +class GeckoAppShell::Natives : public mozilla::jni::NativeImpl<GeckoAppShell, Impl> +{ +public: + static const JNINativeMethod methods[8]; +}; + +template<class Impl> +const JNINativeMethod GeckoAppShell::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<GeckoAppShell::NotifyObservers_t>( + mozilla::jni::NativeStub<GeckoAppShell::NotifyObservers_t, Impl> + ::template Wrap<&Impl::NotifyObservers>), + + mozilla::jni::MakeNativeMethod<GeckoAppShell::NotifyAlertListener_t>( + mozilla::jni::NativeStub<GeckoAppShell::NotifyAlertListener_t, Impl> + ::template Wrap<&Impl::NotifyAlertListener>), + + mozilla::jni::MakeNativeMethod<GeckoAppShell::NotifyUriVisited_t>( + mozilla::jni::NativeStub<GeckoAppShell::NotifyUriVisited_t, Impl> + ::template Wrap<&Impl::NotifyUriVisited>), + + mozilla::jni::MakeNativeMethod<GeckoAppShell::OnFullScreenPluginHidden_t>( + mozilla::jni::NativeStub<GeckoAppShell::OnFullScreenPluginHidden_t, Impl> + ::template Wrap<&Impl::OnFullScreenPluginHidden>), + + mozilla::jni::MakeNativeMethod<GeckoAppShell::OnLocationChanged_t>( + mozilla::jni::NativeStub<GeckoAppShell::OnLocationChanged_t, Impl> + ::template Wrap<&Impl::OnLocationChanged>), + + mozilla::jni::MakeNativeMethod<GeckoAppShell::OnSensorChanged_t>( + mozilla::jni::NativeStub<GeckoAppShell::OnSensorChanged_t, Impl> + ::template Wrap<&Impl::OnSensorChanged>), + + mozilla::jni::MakeNativeMethod<GeckoAppShell::ReportJavaCrash_t>( + mozilla::jni::NativeStub<GeckoAppShell::ReportJavaCrash_t, Impl> + ::template Wrap<&Impl::ReportJavaCrash>), + + mozilla::jni::MakeNativeMethod<GeckoAppShell::SyncNotifyObservers_t>( + mozilla::jni::NativeStub<GeckoAppShell::SyncNotifyObservers_t, Impl> + ::template Wrap<&Impl::SyncNotifyObservers>) +}; + +template<class Impl> +class GeckoAppShell::CameraCallback::Natives : public mozilla::jni::NativeImpl<CameraCallback, Impl> +{ +public: + static const JNINativeMethod methods[1]; +}; + +template<class Impl> +const JNINativeMethod GeckoAppShell::CameraCallback::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<GeckoAppShell::CameraCallback::OnFrameData_t>( + mozilla::jni::NativeStub<GeckoAppShell::CameraCallback::OnFrameData_t, Impl> + ::template Wrap<&Impl::OnFrameData>) +}; + +template<class Impl> +class GeckoBatteryManager::Natives : public mozilla::jni::NativeImpl<GeckoBatteryManager, Impl> +{ +public: + static const JNINativeMethod methods[1]; +}; + +template<class Impl> +const JNINativeMethod GeckoBatteryManager::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<GeckoBatteryManager::OnBatteryChange_t>( + mozilla::jni::NativeStub<GeckoBatteryManager::OnBatteryChange_t, Impl> + ::template Wrap<&Impl::OnBatteryChange>) +}; + +template<class Impl> +class GeckoEditable::Natives : public mozilla::jni::NativeImpl<GeckoEditable, Impl> +{ +public: + static const JNINativeMethod methods[7]; +}; + +template<class Impl> +const JNINativeMethod GeckoEditable::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<GeckoEditable::DisposeNative_t>( + mozilla::jni::NativeStub<GeckoEditable::DisposeNative_t, Impl> + ::template Wrap<&Impl::DisposeNative>), + + mozilla::jni::MakeNativeMethod<GeckoEditable::OnImeAddCompositionRange_t>( + mozilla::jni::NativeStub<GeckoEditable::OnImeAddCompositionRange_t, Impl> + ::template Wrap<&Impl::OnImeAddCompositionRange>), + + mozilla::jni::MakeNativeMethod<GeckoEditable::OnImeReplaceText_t>( + mozilla::jni::NativeStub<GeckoEditable::OnImeReplaceText_t, Impl> + ::template Wrap<&Impl::OnImeReplaceText>), + + mozilla::jni::MakeNativeMethod<GeckoEditable::OnImeRequestCursorUpdates_t>( + mozilla::jni::NativeStub<GeckoEditable::OnImeRequestCursorUpdates_t, Impl> + ::template Wrap<&Impl::OnImeRequestCursorUpdates>), + + mozilla::jni::MakeNativeMethod<GeckoEditable::OnImeSynchronize_t>( + mozilla::jni::NativeStub<GeckoEditable::OnImeSynchronize_t, Impl> + ::template Wrap<&Impl::OnImeSynchronize>), + + mozilla::jni::MakeNativeMethod<GeckoEditable::OnImeUpdateComposition_t>( + mozilla::jni::NativeStub<GeckoEditable::OnImeUpdateComposition_t, Impl> + ::template Wrap<&Impl::OnImeUpdateComposition>), + + mozilla::jni::MakeNativeMethod<GeckoEditable::OnKeyEvent_t>( + mozilla::jni::NativeStub<GeckoEditable::OnKeyEvent_t, Impl> + ::template Wrap<&Impl::OnKeyEvent>) +}; + +template<class Impl> +class GeckoNetworkManager::Natives : public mozilla::jni::NativeImpl<GeckoNetworkManager, Impl> +{ +public: + static const JNINativeMethod methods[2]; +}; + +template<class Impl> +const JNINativeMethod GeckoNetworkManager::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<GeckoNetworkManager::OnConnectionChanged_t>( + mozilla::jni::NativeStub<GeckoNetworkManager::OnConnectionChanged_t, Impl> + ::template Wrap<&Impl::OnConnectionChanged>), + + mozilla::jni::MakeNativeMethod<GeckoNetworkManager::OnStatusChanged_t>( + mozilla::jni::NativeStub<GeckoNetworkManager::OnStatusChanged_t, Impl> + ::template Wrap<&Impl::OnStatusChanged>) +}; + +template<class Impl> +class GeckoScreenOrientation::Natives : public mozilla::jni::NativeImpl<GeckoScreenOrientation, Impl> +{ +public: + static const JNINativeMethod methods[1]; +}; + +template<class Impl> +const JNINativeMethod GeckoScreenOrientation::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<GeckoScreenOrientation::OnOrientationChange_t>( + mozilla::jni::NativeStub<GeckoScreenOrientation::OnOrientationChange_t, Impl> + ::template Wrap<&Impl::OnOrientationChange>) +}; + +template<class Impl> +class GeckoThread::Natives : public mozilla::jni::NativeImpl<GeckoThread, Impl> +{ +public: + static const JNINativeMethod methods[6]; +}; + +template<class Impl> +const JNINativeMethod GeckoThread::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<GeckoThread::CreateServices_t>( + mozilla::jni::NativeStub<GeckoThread::CreateServices_t, Impl> + ::template Wrap<&Impl::CreateServices>), + + mozilla::jni::MakeNativeMethod<GeckoThread::OnPause_t>( + mozilla::jni::NativeStub<GeckoThread::OnPause_t, Impl> + ::template Wrap<&Impl::OnPause>), + + mozilla::jni::MakeNativeMethod<GeckoThread::OnResume_t>( + mozilla::jni::NativeStub<GeckoThread::OnResume_t, Impl> + ::template Wrap<&Impl::OnResume>), + + mozilla::jni::MakeNativeMethod<GeckoThread::RunUiThreadCallback_t>( + mozilla::jni::NativeStub<GeckoThread::RunUiThreadCallback_t, Impl> + ::template Wrap<&Impl::RunUiThreadCallback>), + + mozilla::jni::MakeNativeMethod<GeckoThread::SpeculativeConnect_t>( + mozilla::jni::NativeStub<GeckoThread::SpeculativeConnect_t, Impl> + ::template Wrap<&Impl::SpeculativeConnect>), + + mozilla::jni::MakeNativeMethod<GeckoThread::WaitOnGecko_t>( + mozilla::jni::NativeStub<GeckoThread::WaitOnGecko_t, Impl> + ::template Wrap<&Impl::WaitOnGecko>) +}; + +template<class Impl> +class GeckoView::Window::Natives : public mozilla::jni::NativeImpl<Window, Impl> +{ +public: + static const JNINativeMethod methods[5]; +}; + +template<class Impl> +const JNINativeMethod GeckoView::Window::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<GeckoView::Window::Close_t>( + mozilla::jni::NativeStub<GeckoView::Window::Close_t, Impl> + ::template Wrap<&Impl::Close>), + + mozilla::jni::MakeNativeMethod<GeckoView::Window::DisposeNative_t>( + mozilla::jni::NativeStub<GeckoView::Window::DisposeNative_t, Impl> + ::template Wrap<&Impl::DisposeNative>), + + mozilla::jni::MakeNativeMethod<GeckoView::Window::LoadUri_t>( + mozilla::jni::NativeStub<GeckoView::Window::LoadUri_t, Impl> + ::template Wrap<&Impl::LoadUri>), + + mozilla::jni::MakeNativeMethod<GeckoView::Window::Open_t>( + mozilla::jni::NativeStub<GeckoView::Window::Open_t, Impl> + ::template Wrap<&Impl::Open>), + + mozilla::jni::MakeNativeMethod<GeckoView::Window::Reattach_t>( + mozilla::jni::NativeStub<GeckoView::Window::Reattach_t, Impl> + ::template Wrap<&Impl::Reattach>) +}; + +template<class Impl> +class PrefsHelper::Natives : public mozilla::jni::NativeImpl<PrefsHelper, Impl> +{ +public: + static const JNINativeMethod methods[4]; +}; + +template<class Impl> +const JNINativeMethod PrefsHelper::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<PrefsHelper::AddObserver_t>( + mozilla::jni::NativeStub<PrefsHelper::AddObserver_t, Impl> + ::template Wrap<&Impl::AddObserver>), + + mozilla::jni::MakeNativeMethod<PrefsHelper::GetPrefs_t>( + mozilla::jni::NativeStub<PrefsHelper::GetPrefs_t, Impl> + ::template Wrap<&Impl::GetPrefs>), + + mozilla::jni::MakeNativeMethod<PrefsHelper::RemoveObserver_t>( + mozilla::jni::NativeStub<PrefsHelper::RemoveObserver_t, Impl> + ::template Wrap<&Impl::RemoveObserver>), + + mozilla::jni::MakeNativeMethod<PrefsHelper::SetPref_t>( + mozilla::jni::NativeStub<PrefsHelper::SetPref_t, Impl> + ::template Wrap<&Impl::SetPref>) +}; + +template<class Impl> +class SurfaceTextureListener::Natives : public mozilla::jni::NativeImpl<SurfaceTextureListener, Impl> +{ +public: + static const JNINativeMethod methods[1]; +}; + +template<class Impl> +const JNINativeMethod SurfaceTextureListener::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<SurfaceTextureListener::OnFrameAvailable_t>( + mozilla::jni::NativeStub<SurfaceTextureListener::OnFrameAvailable_t, Impl> + ::template Wrap<&Impl::OnFrameAvailable>) +}; + +template<class Impl> +class LayerView::Compositor::Natives : public mozilla::jni::NativeImpl<Compositor, Impl> +{ +public: + static const JNINativeMethod methods[7]; +}; + +template<class Impl> +const JNINativeMethod LayerView::Compositor::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<LayerView::Compositor::AttachToJava_t>( + mozilla::jni::NativeStub<LayerView::Compositor::AttachToJava_t, Impl> + ::template Wrap<&Impl::AttachToJava>), + + mozilla::jni::MakeNativeMethod<LayerView::Compositor::CreateCompositor_t>( + mozilla::jni::NativeStub<LayerView::Compositor::CreateCompositor_t, Impl> + ::template Wrap<&Impl::CreateCompositor>), + + mozilla::jni::MakeNativeMethod<LayerView::Compositor::DisposeNative_t>( + mozilla::jni::NativeStub<LayerView::Compositor::DisposeNative_t, Impl> + ::template Wrap<&Impl::DisposeNative>), + + mozilla::jni::MakeNativeMethod<LayerView::Compositor::OnSizeChanged_t>( + mozilla::jni::NativeStub<LayerView::Compositor::OnSizeChanged_t, Impl> + ::template Wrap<&Impl::OnSizeChanged>), + + mozilla::jni::MakeNativeMethod<LayerView::Compositor::SyncInvalidateAndScheduleComposite_t>( + mozilla::jni::NativeStub<LayerView::Compositor::SyncInvalidateAndScheduleComposite_t, Impl> + ::template Wrap<&Impl::SyncInvalidateAndScheduleComposite>), + + mozilla::jni::MakeNativeMethod<LayerView::Compositor::SyncPauseCompositor_t>( + mozilla::jni::NativeStub<LayerView::Compositor::SyncPauseCompositor_t, Impl> + ::template Wrap<&Impl::SyncPauseCompositor>), + + mozilla::jni::MakeNativeMethod<LayerView::Compositor::SyncResumeResizeCompositor_t>( + mozilla::jni::NativeStub<LayerView::Compositor::SyncResumeResizeCompositor_t, Impl> + ::template Wrap<&Impl::SyncResumeResizeCompositor>) +}; + +template<class Impl> +class NativePanZoomController::Natives : public mozilla::jni::NativeImpl<NativePanZoomController, Impl> +{ +public: + static const JNINativeMethod methods[7]; +}; + +template<class Impl> +const JNINativeMethod NativePanZoomController::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<NativePanZoomController::AdjustScrollForSurfaceShift_t>( + mozilla::jni::NativeStub<NativePanZoomController::AdjustScrollForSurfaceShift_t, Impl> + ::template Wrap<&Impl::AdjustScrollForSurfaceShift>), + + mozilla::jni::MakeNativeMethod<NativePanZoomController::DisposeNative_t>( + mozilla::jni::NativeStub<NativePanZoomController::DisposeNative_t, Impl> + ::template Wrap<&Impl::DisposeNative>), + + mozilla::jni::MakeNativeMethod<NativePanZoomController::HandleMotionEvent_t>( + mozilla::jni::NativeStub<NativePanZoomController::HandleMotionEvent_t, Impl> + ::template Wrap<&Impl::HandleMotionEvent>), + + mozilla::jni::MakeNativeMethod<NativePanZoomController::HandleMotionEventVelocity_t>( + mozilla::jni::NativeStub<NativePanZoomController::HandleMotionEventVelocity_t, Impl> + ::template Wrap<&Impl::HandleMotionEventVelocity>), + + mozilla::jni::MakeNativeMethod<NativePanZoomController::HandleMouseEvent_t>( + mozilla::jni::NativeStub<NativePanZoomController::HandleMouseEvent_t, Impl> + ::template Wrap<&Impl::HandleMouseEvent>), + + mozilla::jni::MakeNativeMethod<NativePanZoomController::HandleScrollEvent_t>( + mozilla::jni::NativeStub<NativePanZoomController::HandleScrollEvent_t, Impl> + ::template Wrap<&Impl::HandleScrollEvent>), + + mozilla::jni::MakeNativeMethod<NativePanZoomController::SetIsLongpressEnabled_t>( + mozilla::jni::NativeStub<NativePanZoomController::SetIsLongpressEnabled_t, Impl> + ::template Wrap<&Impl::SetIsLongpressEnabled>) +}; + +template<class Impl> +class NativeJSContainer::Natives : public mozilla::jni::NativeImpl<NativeJSContainer, Impl> +{ +public: + static const JNINativeMethod methods[2]; +}; + +template<class Impl> +const JNINativeMethod NativeJSContainer::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<NativeJSContainer::Clone2_t>( + mozilla::jni::NativeStub<NativeJSContainer::Clone2_t, Impl> + ::template Wrap<&Impl::Clone>), + + mozilla::jni::MakeNativeMethod<NativeJSContainer::DisposeNative_t>( + mozilla::jni::NativeStub<NativeJSContainer::DisposeNative_t, Impl> + ::template Wrap<&Impl::DisposeNative>) +}; + +template<class Impl> +class NativeJSObject::Natives : public mozilla::jni::NativeImpl<NativeJSObject, Impl> +{ +public: + static const JNINativeMethod methods[27]; +}; + +template<class Impl> +const JNINativeMethod NativeJSObject::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<NativeJSObject::GetBoolean_t>( + mozilla::jni::NativeStub<NativeJSObject::GetBoolean_t, Impl> + ::template Wrap<&Impl::GetBoolean>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::GetBooleanArray_t>( + mozilla::jni::NativeStub<NativeJSObject::GetBooleanArray_t, Impl> + ::template Wrap<&Impl::GetBooleanArray>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::GetBundle_t>( + mozilla::jni::NativeStub<NativeJSObject::GetBundle_t, Impl> + ::template Wrap<&Impl::GetBundle>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::GetBundleArray_t>( + mozilla::jni::NativeStub<NativeJSObject::GetBundleArray_t, Impl> + ::template Wrap<&Impl::GetBundleArray>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::GetDouble_t>( + mozilla::jni::NativeStub<NativeJSObject::GetDouble_t, Impl> + ::template Wrap<&Impl::GetDouble>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::GetDoubleArray_t>( + mozilla::jni::NativeStub<NativeJSObject::GetDoubleArray_t, Impl> + ::template Wrap<&Impl::GetDoubleArray>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::GetInt_t>( + mozilla::jni::NativeStub<NativeJSObject::GetInt_t, Impl> + ::template Wrap<&Impl::GetInt>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::GetIntArray_t>( + mozilla::jni::NativeStub<NativeJSObject::GetIntArray_t, Impl> + ::template Wrap<&Impl::GetIntArray>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::GetObject_t>( + mozilla::jni::NativeStub<NativeJSObject::GetObject_t, Impl> + ::template Wrap<&Impl::GetObject>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::GetObjectArray_t>( + mozilla::jni::NativeStub<NativeJSObject::GetObjectArray_t, Impl> + ::template Wrap<&Impl::GetObjectArray>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::GetString_t>( + mozilla::jni::NativeStub<NativeJSObject::GetString_t, Impl> + ::template Wrap<&Impl::GetString>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::GetStringArray_t>( + mozilla::jni::NativeStub<NativeJSObject::GetStringArray_t, Impl> + ::template Wrap<&Impl::GetStringArray>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::Has_t>( + mozilla::jni::NativeStub<NativeJSObject::Has_t, Impl> + ::template Wrap<&Impl::Has>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::OptBoolean_t>( + mozilla::jni::NativeStub<NativeJSObject::OptBoolean_t, Impl> + ::template Wrap<&Impl::OptBoolean>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::OptBooleanArray_t>( + mozilla::jni::NativeStub<NativeJSObject::OptBooleanArray_t, Impl> + ::template Wrap<&Impl::OptBooleanArray>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::OptBundle_t>( + mozilla::jni::NativeStub<NativeJSObject::OptBundle_t, Impl> + ::template Wrap<&Impl::OptBundle>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::OptBundleArray_t>( + mozilla::jni::NativeStub<NativeJSObject::OptBundleArray_t, Impl> + ::template Wrap<&Impl::OptBundleArray>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::OptDouble_t>( + mozilla::jni::NativeStub<NativeJSObject::OptDouble_t, Impl> + ::template Wrap<&Impl::OptDouble>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::OptDoubleArray_t>( + mozilla::jni::NativeStub<NativeJSObject::OptDoubleArray_t, Impl> + ::template Wrap<&Impl::OptDoubleArray>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::OptInt_t>( + mozilla::jni::NativeStub<NativeJSObject::OptInt_t, Impl> + ::template Wrap<&Impl::OptInt>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::OptIntArray_t>( + mozilla::jni::NativeStub<NativeJSObject::OptIntArray_t, Impl> + ::template Wrap<&Impl::OptIntArray>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::OptObject_t>( + mozilla::jni::NativeStub<NativeJSObject::OptObject_t, Impl> + ::template Wrap<&Impl::OptObject>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::OptObjectArray_t>( + mozilla::jni::NativeStub<NativeJSObject::OptObjectArray_t, Impl> + ::template Wrap<&Impl::OptObjectArray>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::OptString_t>( + mozilla::jni::NativeStub<NativeJSObject::OptString_t, Impl> + ::template Wrap<&Impl::OptString>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::OptStringArray_t>( + mozilla::jni::NativeStub<NativeJSObject::OptStringArray_t, Impl> + ::template Wrap<&Impl::OptStringArray>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::ToBundle_t>( + mozilla::jni::NativeStub<NativeJSObject::ToBundle_t, Impl> + ::template Wrap<&Impl::ToBundle>), + + mozilla::jni::MakeNativeMethod<NativeJSObject::ToString_t>( + mozilla::jni::NativeStub<NativeJSObject::ToString_t, Impl> + ::template Wrap<&Impl::ToString>) +}; + +} /* java */ +} /* mozilla */ +#endif // GeneratedJNINatives_h diff --git a/widget/android/GeneratedJNIWrappers.cpp b/widget/android/GeneratedJNIWrappers.cpp new file mode 100644 index 000000000..37564ba24 --- /dev/null +++ b/widget/android/GeneratedJNIWrappers.cpp @@ -0,0 +1,1874 @@ +// GENERATED CODE +// Generated by the Java program at /build/annotationProcessors at compile time +// from annotations on Java methods. To update, change the annotations on the +// corresponding Java methods and rerun the build. Manually updating this file +// will cause your build to fail. + +#include "GeneratedJNIWrappers.h" +#include "mozilla/jni/Accessors.h" + +namespace mozilla { +namespace java { + +const char AlarmReceiver::name[] = + "org/mozilla/gecko/AlarmReceiver"; + +constexpr char AlarmReceiver::NotifyAlarmFired_t::name[]; +constexpr char AlarmReceiver::NotifyAlarmFired_t::signature[]; + +const char AndroidGamepadManager::name[] = + "org/mozilla/gecko/AndroidGamepadManager"; + +constexpr char AndroidGamepadManager::OnAxisChange_t::name[]; +constexpr char AndroidGamepadManager::OnAxisChange_t::signature[]; + +constexpr char AndroidGamepadManager::OnButtonChange_t::name[]; +constexpr char AndroidGamepadManager::OnButtonChange_t::signature[]; + +constexpr char AndroidGamepadManager::OnGamepadAdded_t::name[]; +constexpr char AndroidGamepadManager::OnGamepadAdded_t::signature[]; + +auto AndroidGamepadManager::OnGamepadAdded(int32_t a0, int32_t a1) -> void +{ + return mozilla::jni::Method<OnGamepadAdded_t>::Call(AndroidGamepadManager::Context(), nullptr, a0, a1); +} + +constexpr char AndroidGamepadManager::OnGamepadChange_t::name[]; +constexpr char AndroidGamepadManager::OnGamepadChange_t::signature[]; + +constexpr char AndroidGamepadManager::Start_t::name[]; +constexpr char AndroidGamepadManager::Start_t::signature[]; + +auto AndroidGamepadManager::Start() -> void +{ + return mozilla::jni::Method<Start_t>::Call(AndroidGamepadManager::Context(), nullptr); +} + +constexpr char AndroidGamepadManager::Stop_t::name[]; +constexpr char AndroidGamepadManager::Stop_t::signature[]; + +auto AndroidGamepadManager::Stop() -> void +{ + return mozilla::jni::Method<Stop_t>::Call(AndroidGamepadManager::Context(), nullptr); +} + +const char GeckoAppShell::name[] = + "org/mozilla/gecko/GeckoAppShell"; + +constexpr char GeckoAppShell::AddFullScreenPluginView_t::name[]; +constexpr char GeckoAppShell::AddFullScreenPluginView_t::signature[]; + +auto GeckoAppShell::AddFullScreenPluginView(mozilla::jni::Object::Param a0) -> void +{ + return mozilla::jni::Method<AddFullScreenPluginView_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::CancelVibrate_t::name[]; +constexpr char GeckoAppShell::CancelVibrate_t::signature[]; + +auto GeckoAppShell::CancelVibrate() -> void +{ + return mozilla::jni::Method<CancelVibrate_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::CheckURIVisited_t::name[]; +constexpr char GeckoAppShell::CheckURIVisited_t::signature[]; + +auto GeckoAppShell::CheckURIVisited(mozilla::jni::String::Param a0) -> void +{ + return mozilla::jni::Method<CheckURIVisited_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::CloseCamera_t::name[]; +constexpr char GeckoAppShell::CloseCamera_t::signature[]; + +auto GeckoAppShell::CloseCamera() -> void +{ + return mozilla::jni::Method<CloseCamera_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::CloseNotification_t::name[]; +constexpr char GeckoAppShell::CloseNotification_t::signature[]; + +auto GeckoAppShell::CloseNotification(mozilla::jni::String::Param a0) -> void +{ + return mozilla::jni::Method<CloseNotification_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::ConnectionGetMimeType_t::name[]; +constexpr char GeckoAppShell::ConnectionGetMimeType_t::signature[]; + +auto GeckoAppShell::ConnectionGetMimeType(mozilla::jni::Object::Param a0) -> mozilla::jni::String::LocalRef +{ + return mozilla::jni::Method<ConnectionGetMimeType_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::CreateInputStream_t::name[]; +constexpr char GeckoAppShell::CreateInputStream_t::signature[]; + +auto GeckoAppShell::CreateInputStream(mozilla::jni::Object::Param a0) -> mozilla::jni::Object::LocalRef +{ + return mozilla::jni::Method<CreateInputStream_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::CreateShortcut_t::name[]; +constexpr char GeckoAppShell::CreateShortcut_t::signature[]; + +auto GeckoAppShell::CreateShortcut(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1) -> void +{ + return mozilla::jni::Method<CreateShortcut_t>::Call(GeckoAppShell::Context(), nullptr, a0, a1); +} + +constexpr char GeckoAppShell::DisableAlarm_t::name[]; +constexpr char GeckoAppShell::DisableAlarm_t::signature[]; + +auto GeckoAppShell::DisableAlarm() -> void +{ + return mozilla::jni::Method<DisableAlarm_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::DisableBatteryNotifications_t::name[]; +constexpr char GeckoAppShell::DisableBatteryNotifications_t::signature[]; + +auto GeckoAppShell::DisableBatteryNotifications() -> void +{ + return mozilla::jni::Method<DisableBatteryNotifications_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::DisableNetworkNotifications_t::name[]; +constexpr char GeckoAppShell::DisableNetworkNotifications_t::signature[]; + +auto GeckoAppShell::DisableNetworkNotifications() -> void +{ + return mozilla::jni::Method<DisableNetworkNotifications_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::DisableScreenOrientationNotifications_t::name[]; +constexpr char GeckoAppShell::DisableScreenOrientationNotifications_t::signature[]; + +auto GeckoAppShell::DisableScreenOrientationNotifications() -> void +{ + return mozilla::jni::Method<DisableScreenOrientationNotifications_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::DisableSensor_t::name[]; +constexpr char GeckoAppShell::DisableSensor_t::signature[]; + +auto GeckoAppShell::DisableSensor(int32_t a0) -> void +{ + return mozilla::jni::Method<DisableSensor_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::EnableBatteryNotifications_t::name[]; +constexpr char GeckoAppShell::EnableBatteryNotifications_t::signature[]; + +auto GeckoAppShell::EnableBatteryNotifications() -> void +{ + return mozilla::jni::Method<EnableBatteryNotifications_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::EnableLocation_t::name[]; +constexpr char GeckoAppShell::EnableLocation_t::signature[]; + +auto GeckoAppShell::EnableLocation(bool a0) -> void +{ + return mozilla::jni::Method<EnableLocation_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::EnableLocationHighAccuracy_t::name[]; +constexpr char GeckoAppShell::EnableLocationHighAccuracy_t::signature[]; + +auto GeckoAppShell::EnableLocationHighAccuracy(bool a0) -> void +{ + return mozilla::jni::Method<EnableLocationHighAccuracy_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::EnableNetworkNotifications_t::name[]; +constexpr char GeckoAppShell::EnableNetworkNotifications_t::signature[]; + +auto GeckoAppShell::EnableNetworkNotifications() -> void +{ + return mozilla::jni::Method<EnableNetworkNotifications_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::EnableScreenOrientationNotifications_t::name[]; +constexpr char GeckoAppShell::EnableScreenOrientationNotifications_t::signature[]; + +auto GeckoAppShell::EnableScreenOrientationNotifications() -> void +{ + return mozilla::jni::Method<EnableScreenOrientationNotifications_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::EnableSensor_t::name[]; +constexpr char GeckoAppShell::EnableSensor_t::signature[]; + +auto GeckoAppShell::EnableSensor(int32_t a0) -> void +{ + return mozilla::jni::Method<EnableSensor_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::GetApplicationContext_t::name[]; +constexpr char GeckoAppShell::GetApplicationContext_t::signature[]; + +auto GeckoAppShell::GetApplicationContext() -> mozilla::jni::Object::LocalRef +{ + return mozilla::jni::Method<GetApplicationContext_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::GetConnection_t::name[]; +constexpr char GeckoAppShell::GetConnection_t::signature[]; + +auto GeckoAppShell::GetConnection(mozilla::jni::String::Param a0) -> mozilla::jni::Object::LocalRef +{ + return mozilla::jni::Method<GetConnection_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::GetContext_t::name[]; +constexpr char GeckoAppShell::GetContext_t::signature[]; + +auto GeckoAppShell::GetContext() -> mozilla::jni::Object::LocalRef +{ + return mozilla::jni::Method<GetContext_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::GetCurrentBatteryInformation_t::name[]; +constexpr char GeckoAppShell::GetCurrentBatteryInformation_t::signature[]; + +auto GeckoAppShell::GetCurrentBatteryInformation() -> mozilla::jni::DoubleArray::LocalRef +{ + return mozilla::jni::Method<GetCurrentBatteryInformation_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::GetCurrentNetworkInformation_t::name[]; +constexpr char GeckoAppShell::GetCurrentNetworkInformation_t::signature[]; + +auto GeckoAppShell::GetCurrentNetworkInformation() -> mozilla::jni::DoubleArray::LocalRef +{ + return mozilla::jni::Method<GetCurrentNetworkInformation_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::GetDensity_t::name[]; +constexpr char GeckoAppShell::GetDensity_t::signature[]; + +auto GeckoAppShell::GetDensity() -> float +{ + return mozilla::jni::Method<GetDensity_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::GetDpi_t::name[]; +constexpr char GeckoAppShell::GetDpi_t::signature[]; + +auto GeckoAppShell::GetDpi() -> int32_t +{ + return mozilla::jni::Method<GetDpi_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::GetExceptionStackTrace_t::name[]; +constexpr char GeckoAppShell::GetExceptionStackTrace_t::signature[]; + +auto GeckoAppShell::GetExceptionStackTrace(mozilla::jni::Throwable::Param a0) -> mozilla::jni::String::LocalRef +{ + return mozilla::jni::Method<GetExceptionStackTrace_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::GetExtensionFromMimeType_t::name[]; +constexpr char GeckoAppShell::GetExtensionFromMimeType_t::signature[]; + +auto GeckoAppShell::GetExtensionFromMimeType(mozilla::jni::String::Param a0) -> mozilla::jni::String::LocalRef +{ + return mozilla::jni::Method<GetExtensionFromMimeType_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::GetHWDecoderCapability_t::name[]; +constexpr char GeckoAppShell::GetHWDecoderCapability_t::signature[]; + +auto GeckoAppShell::GetHWDecoderCapability() -> bool +{ + return mozilla::jni::Method<GetHWDecoderCapability_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::GetHWEncoderCapability_t::name[]; +constexpr char GeckoAppShell::GetHWEncoderCapability_t::signature[]; + +auto GeckoAppShell::GetHWEncoderCapability() -> bool +{ + return mozilla::jni::Method<GetHWEncoderCapability_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::GetHandlersForMimeType_t::name[]; +constexpr char GeckoAppShell::GetHandlersForMimeType_t::signature[]; + +auto GeckoAppShell::GetHandlersForMimeType(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1) -> mozilla::jni::ObjectArray::LocalRef +{ + return mozilla::jni::Method<GetHandlersForMimeType_t>::Call(GeckoAppShell::Context(), nullptr, a0, a1); +} + +constexpr char GeckoAppShell::GetHandlersForURL_t::name[]; +constexpr char GeckoAppShell::GetHandlersForURL_t::signature[]; + +auto GeckoAppShell::GetHandlersForURL(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1) -> mozilla::jni::ObjectArray::LocalRef +{ + return mozilla::jni::Method<GetHandlersForURL_t>::Call(GeckoAppShell::Context(), nullptr, a0, a1); +} + +constexpr char GeckoAppShell::GetIconForExtension_t::name[]; +constexpr char GeckoAppShell::GetIconForExtension_t::signature[]; + +auto GeckoAppShell::GetIconForExtension(mozilla::jni::String::Param a0, int32_t a1) -> mozilla::jni::ByteArray::LocalRef +{ + return mozilla::jni::Method<GetIconForExtension_t>::Call(GeckoAppShell::Context(), nullptr, a0, a1); +} + +constexpr char GeckoAppShell::GetMaxTouchPoints_t::name[]; +constexpr char GeckoAppShell::GetMaxTouchPoints_t::signature[]; + +auto GeckoAppShell::GetMaxTouchPoints() -> int32_t +{ + return mozilla::jni::Method<GetMaxTouchPoints_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::GetMimeTypeFromExtensions_t::name[]; +constexpr char GeckoAppShell::GetMimeTypeFromExtensions_t::signature[]; + +auto GeckoAppShell::GetMimeTypeFromExtensions(mozilla::jni::String::Param a0) -> mozilla::jni::String::LocalRef +{ + return mozilla::jni::Method<GetMimeTypeFromExtensions_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::GetNetworkLinkType_t::name[]; +constexpr char GeckoAppShell::GetNetworkLinkType_t::signature[]; + +auto GeckoAppShell::GetNetworkLinkType() -> int32_t +{ + return mozilla::jni::Method<GetNetworkLinkType_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::GetProxyForURI_t::name[]; +constexpr char GeckoAppShell::GetProxyForURI_t::signature[]; + +auto GeckoAppShell::GetProxyForURI(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1, mozilla::jni::String::Param a2, int32_t a3) -> mozilla::jni::String::LocalRef +{ + return mozilla::jni::Method<GetProxyForURI_t>::Call(GeckoAppShell::Context(), nullptr, a0, a1, a2, a3); +} + +constexpr char GeckoAppShell::GetScreenAngle_t::name[]; +constexpr char GeckoAppShell::GetScreenAngle_t::signature[]; + +auto GeckoAppShell::GetScreenAngle() -> int32_t +{ + return mozilla::jni::Method<GetScreenAngle_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::GetScreenDepth_t::name[]; +constexpr char GeckoAppShell::GetScreenDepth_t::signature[]; + +auto GeckoAppShell::GetScreenDepth() -> int32_t +{ + return mozilla::jni::Method<GetScreenDepth_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::GetScreenOrientation_t::name[]; +constexpr char GeckoAppShell::GetScreenOrientation_t::signature[]; + +auto GeckoAppShell::GetScreenOrientation() -> int16_t +{ + return mozilla::jni::Method<GetScreenOrientation_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::GetScreenSize_t::name[]; +constexpr char GeckoAppShell::GetScreenSize_t::signature[]; + +auto GeckoAppShell::GetScreenSize() -> mozilla::jni::Object::LocalRef +{ + return mozilla::jni::Method<GetScreenSize_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::GetShowPasswordSetting_t::name[]; +constexpr char GeckoAppShell::GetShowPasswordSetting_t::signature[]; + +auto GeckoAppShell::GetShowPasswordSetting() -> bool +{ + return mozilla::jni::Method<GetShowPasswordSetting_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::GetSystemColors_t::name[]; +constexpr char GeckoAppShell::GetSystemColors_t::signature[]; + +auto GeckoAppShell::GetSystemColors() -> mozilla::jni::IntArray::LocalRef +{ + return mozilla::jni::Method<GetSystemColors_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::HandleGeckoMessage_t::name[]; +constexpr char GeckoAppShell::HandleGeckoMessage_t::signature[]; + +auto GeckoAppShell::HandleGeckoMessage(mozilla::jni::Object::Param a0) -> void +{ + return mozilla::jni::Method<HandleGeckoMessage_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::HandleUncaughtException_t::name[]; +constexpr char GeckoAppShell::HandleUncaughtException_t::signature[]; + +auto GeckoAppShell::HandleUncaughtException(mozilla::jni::Throwable::Param a0) -> void +{ + return mozilla::jni::Method<HandleUncaughtException_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::HideProgressDialog_t::name[]; +constexpr char GeckoAppShell::HideProgressDialog_t::signature[]; + +auto GeckoAppShell::HideProgressDialog() -> void +{ + return mozilla::jni::Method<HideProgressDialog_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::InitCamera_t::name[]; +constexpr char GeckoAppShell::InitCamera_t::signature[]; + +auto GeckoAppShell::InitCamera(mozilla::jni::String::Param a0, int32_t a1, int32_t a2, int32_t a3) -> mozilla::jni::IntArray::LocalRef +{ + return mozilla::jni::Method<InitCamera_t>::Call(GeckoAppShell::Context(), nullptr, a0, a1, a2, a3); +} + +constexpr char GeckoAppShell::IsNetworkLinkKnown_t::name[]; +constexpr char GeckoAppShell::IsNetworkLinkKnown_t::signature[]; + +auto GeckoAppShell::IsNetworkLinkKnown() -> bool +{ + return mozilla::jni::Method<IsNetworkLinkKnown_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::IsNetworkLinkUp_t::name[]; +constexpr char GeckoAppShell::IsNetworkLinkUp_t::signature[]; + +auto GeckoAppShell::IsNetworkLinkUp() -> bool +{ + return mozilla::jni::Method<IsNetworkLinkUp_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::IsTablet_t::name[]; +constexpr char GeckoAppShell::IsTablet_t::signature[]; + +auto GeckoAppShell::IsTablet() -> bool +{ + return mozilla::jni::Method<IsTablet_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::KillAnyZombies_t::name[]; +constexpr char GeckoAppShell::KillAnyZombies_t::signature[]; + +auto GeckoAppShell::KillAnyZombies() -> void +{ + return mozilla::jni::Method<KillAnyZombies_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::LoadPluginClass_t::name[]; +constexpr char GeckoAppShell::LoadPluginClass_t::signature[]; + +auto GeckoAppShell::LoadPluginClass(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1) -> mozilla::jni::Class::LocalRef +{ + return mozilla::jni::Method<LoadPluginClass_t>::Call(GeckoAppShell::Context(), nullptr, a0, a1); +} + +constexpr char GeckoAppShell::LockScreenOrientation_t::name[]; +constexpr char GeckoAppShell::LockScreenOrientation_t::signature[]; + +auto GeckoAppShell::LockScreenOrientation(int32_t a0) -> void +{ + return mozilla::jni::Method<LockScreenOrientation_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::MarkURIVisited_t::name[]; +constexpr char GeckoAppShell::MarkURIVisited_t::signature[]; + +auto GeckoAppShell::MarkURIVisited(mozilla::jni::String::Param a0) -> void +{ + return mozilla::jni::Method<MarkURIVisited_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::MoveTaskToBack_t::name[]; +constexpr char GeckoAppShell::MoveTaskToBack_t::signature[]; + +auto GeckoAppShell::MoveTaskToBack() -> void +{ + return mozilla::jni::Method<MoveTaskToBack_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::NotifyObservers_t::name[]; +constexpr char GeckoAppShell::NotifyObservers_t::signature[]; + +constexpr char GeckoAppShell::NotifyAlertListener_t::name[]; +constexpr char GeckoAppShell::NotifyAlertListener_t::signature[]; + +constexpr char GeckoAppShell::NotifyUriVisited_t::name[]; +constexpr char GeckoAppShell::NotifyUriVisited_t::signature[]; + +constexpr char GeckoAppShell::NotifyWakeLockChanged_t::name[]; +constexpr char GeckoAppShell::NotifyWakeLockChanged_t::signature[]; + +auto GeckoAppShell::NotifyWakeLockChanged(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1) -> void +{ + return mozilla::jni::Method<NotifyWakeLockChanged_t>::Call(GeckoAppShell::Context(), nullptr, a0, a1); +} + +constexpr char GeckoAppShell::OnFullScreenPluginHidden_t::name[]; +constexpr char GeckoAppShell::OnFullScreenPluginHidden_t::signature[]; + +constexpr char GeckoAppShell::OnLocationChanged_t::name[]; +constexpr char GeckoAppShell::OnLocationChanged_t::signature[]; + +constexpr char GeckoAppShell::OnSensorChanged_t::name[]; +constexpr char GeckoAppShell::OnSensorChanged_t::signature[]; + +constexpr char GeckoAppShell::OpenUriExternal_t::name[]; +constexpr char GeckoAppShell::OpenUriExternal_t::signature[]; + +auto GeckoAppShell::OpenUriExternal(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1, mozilla::jni::String::Param a2, mozilla::jni::String::Param a3, mozilla::jni::String::Param a4, mozilla::jni::String::Param a5) -> bool +{ + return mozilla::jni::Method<OpenUriExternal_t>::Call(GeckoAppShell::Context(), nullptr, a0, a1, a2, a3, a4, a5); +} + +constexpr char GeckoAppShell::OpenWindowForNotification_t::name[]; +constexpr char GeckoAppShell::OpenWindowForNotification_t::signature[]; + +auto GeckoAppShell::OpenWindowForNotification() -> void +{ + return mozilla::jni::Method<OpenWindowForNotification_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::PerformHapticFeedback_t::name[]; +constexpr char GeckoAppShell::PerformHapticFeedback_t::signature[]; + +auto GeckoAppShell::PerformHapticFeedback(bool a0) -> void +{ + return mozilla::jni::Method<PerformHapticFeedback_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::RemoveFullScreenPluginView_t::name[]; +constexpr char GeckoAppShell::RemoveFullScreenPluginView_t::signature[]; + +auto GeckoAppShell::RemoveFullScreenPluginView(mozilla::jni::Object::Param a0) -> void +{ + return mozilla::jni::Method<RemoveFullScreenPluginView_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::ReportJavaCrash_t::name[]; +constexpr char GeckoAppShell::ReportJavaCrash_t::signature[]; + +constexpr char GeckoAppShell::ScheduleRestart_t::name[]; +constexpr char GeckoAppShell::ScheduleRestart_t::signature[]; + +auto GeckoAppShell::ScheduleRestart() -> void +{ + return mozilla::jni::Method<ScheduleRestart_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::SetAlarm_t::name[]; +constexpr char GeckoAppShell::SetAlarm_t::signature[]; + +auto GeckoAppShell::SetAlarm(int32_t a0, int32_t a1) -> bool +{ + return mozilla::jni::Method<SetAlarm_t>::Call(GeckoAppShell::Context(), nullptr, a0, a1); +} + +constexpr char GeckoAppShell::SetFullScreen_t::name[]; +constexpr char GeckoAppShell::SetFullScreen_t::signature[]; + +auto GeckoAppShell::SetFullScreen(bool a0) -> void +{ + return mozilla::jni::Method<SetFullScreen_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::SetKeepScreenOn_t::name[]; +constexpr char GeckoAppShell::SetKeepScreenOn_t::signature[]; + +auto GeckoAppShell::SetKeepScreenOn(bool a0) -> void +{ + return mozilla::jni::Method<SetKeepScreenOn_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::SetScreenDepthOverride_t::name[]; +constexpr char GeckoAppShell::SetScreenDepthOverride_t::signature[]; + +auto GeckoAppShell::SetScreenDepthOverride(int32_t a0) -> void +{ + return mozilla::jni::Method<SetScreenDepthOverride_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::SetURITitle_t::name[]; +constexpr char GeckoAppShell::SetURITitle_t::signature[]; + +auto GeckoAppShell::SetURITitle(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1) -> void +{ + return mozilla::jni::Method<SetURITitle_t>::Call(GeckoAppShell::Context(), nullptr, a0, a1); +} + +constexpr char GeckoAppShell::ShowNotification_t::name[]; +constexpr char GeckoAppShell::ShowNotification_t::signature[]; + +auto GeckoAppShell::ShowNotification(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1, mozilla::jni::String::Param a2, mozilla::jni::String::Param a3, mozilla::jni::String::Param a4, mozilla::jni::String::Param a5, mozilla::jni::String::Param a6) -> void +{ + return mozilla::jni::Method<ShowNotification_t>::Call(GeckoAppShell::Context(), nullptr, a0, a1, a2, a3, a4, a5, a6); +} + +constexpr char GeckoAppShell::SyncNotifyObservers_t::name[]; +constexpr char GeckoAppShell::SyncNotifyObservers_t::signature[]; + +constexpr char GeckoAppShell::UnlockProfile_t::name[]; +constexpr char GeckoAppShell::UnlockProfile_t::signature[]; + +auto GeckoAppShell::UnlockProfile() -> bool +{ + return mozilla::jni::Method<UnlockProfile_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::UnlockScreenOrientation_t::name[]; +constexpr char GeckoAppShell::UnlockScreenOrientation_t::signature[]; + +auto GeckoAppShell::UnlockScreenOrientation() -> void +{ + return mozilla::jni::Method<UnlockScreenOrientation_t>::Call(GeckoAppShell::Context(), nullptr); +} + +constexpr char GeckoAppShell::Vibrate_t::name[]; +constexpr char GeckoAppShell::Vibrate_t::signature[]; + +auto GeckoAppShell::Vibrate(int64_t a0) -> void +{ + return mozilla::jni::Method<Vibrate_t>::Call(GeckoAppShell::Context(), nullptr, a0); +} + +constexpr char GeckoAppShell::Vibrate2_t::name[]; +constexpr char GeckoAppShell::Vibrate2_t::signature[]; + +auto GeckoAppShell::Vibrate(mozilla::jni::LongArray::Param a0, int32_t a1) -> void +{ + return mozilla::jni::Method<Vibrate2_t>::Call(GeckoAppShell::Context(), nullptr, a0, a1); +} + +const char GeckoAppShell::CameraCallback::name[] = + "org/mozilla/gecko/GeckoAppShell$CameraCallback"; + +constexpr char GeckoAppShell::CameraCallback::OnFrameData_t::name[]; +constexpr char GeckoAppShell::CameraCallback::OnFrameData_t::signature[]; + +const char GeckoBatteryManager::name[] = + "org/mozilla/gecko/GeckoBatteryManager"; + +constexpr char GeckoBatteryManager::OnBatteryChange_t::name[]; +constexpr char GeckoBatteryManager::OnBatteryChange_t::signature[]; + +const char GeckoEditable::name[] = + "org/mozilla/gecko/GeckoEditable"; + +constexpr char GeckoEditable::New_t::name[]; +constexpr char GeckoEditable::New_t::signature[]; + +auto GeckoEditable::New(mozilla::jni::Object::Param a0) -> GeckoEditable::LocalRef +{ + return mozilla::jni::Constructor<New_t>::Call(GeckoEditable::Context(), nullptr, a0); +} + +constexpr char GeckoEditable::DisposeNative_t::name[]; +constexpr char GeckoEditable::DisposeNative_t::signature[]; + +constexpr char GeckoEditable::NotifyIME_t::name[]; +constexpr char GeckoEditable::NotifyIME_t::signature[]; + +auto GeckoEditable::NotifyIME(int32_t a0) const -> void +{ + return mozilla::jni::Method<NotifyIME_t>::Call(GeckoEditable::mCtx, nullptr, a0); +} + +constexpr char GeckoEditable::NotifyIMEContext_t::name[]; +constexpr char GeckoEditable::NotifyIMEContext_t::signature[]; + +auto GeckoEditable::NotifyIMEContext(int32_t a0, mozilla::jni::String::Param a1, mozilla::jni::String::Param a2, mozilla::jni::String::Param a3) const -> void +{ + return mozilla::jni::Method<NotifyIMEContext_t>::Call(GeckoEditable::mCtx, nullptr, a0, a1, a2, a3); +} + +constexpr char GeckoEditable::OnDefaultKeyEvent_t::name[]; +constexpr char GeckoEditable::OnDefaultKeyEvent_t::signature[]; + +auto GeckoEditable::OnDefaultKeyEvent(mozilla::jni::Object::Param a0) const -> void +{ + return mozilla::jni::Method<OnDefaultKeyEvent_t>::Call(GeckoEditable::mCtx, nullptr, a0); +} + +constexpr char GeckoEditable::OnImeAddCompositionRange_t::name[]; +constexpr char GeckoEditable::OnImeAddCompositionRange_t::signature[]; + +constexpr char GeckoEditable::OnImeReplaceText_t::name[]; +constexpr char GeckoEditable::OnImeReplaceText_t::signature[]; + +constexpr char GeckoEditable::OnImeRequestCursorUpdates_t::name[]; +constexpr char GeckoEditable::OnImeRequestCursorUpdates_t::signature[]; + +constexpr char GeckoEditable::OnImeSynchronize_t::name[]; +constexpr char GeckoEditable::OnImeSynchronize_t::signature[]; + +constexpr char GeckoEditable::OnImeUpdateComposition_t::name[]; +constexpr char GeckoEditable::OnImeUpdateComposition_t::signature[]; + +constexpr char GeckoEditable::OnKeyEvent_t::name[]; +constexpr char GeckoEditable::OnKeyEvent_t::signature[]; + +constexpr char GeckoEditable::OnSelectionChange_t::name[]; +constexpr char GeckoEditable::OnSelectionChange_t::signature[]; + +auto GeckoEditable::OnSelectionChange(int32_t a0, int32_t a1) const -> void +{ + return mozilla::jni::Method<OnSelectionChange_t>::Call(GeckoEditable::mCtx, nullptr, a0, a1); +} + +constexpr char GeckoEditable::OnTextChange_t::name[]; +constexpr char GeckoEditable::OnTextChange_t::signature[]; + +auto GeckoEditable::OnTextChange(mozilla::jni::String::Param a0, int32_t a1, int32_t a2, int32_t a3) const -> void +{ + return mozilla::jni::Method<OnTextChange_t>::Call(GeckoEditable::mCtx, nullptr, a0, a1, a2, a3); +} + +constexpr char GeckoEditable::OnViewChange_t::name[]; +constexpr char GeckoEditable::OnViewChange_t::signature[]; + +auto GeckoEditable::OnViewChange(mozilla::jni::Object::Param a0) const -> void +{ + return mozilla::jni::Method<OnViewChange_t>::Call(GeckoEditable::mCtx, nullptr, a0); +} + +constexpr char GeckoEditable::UpdateCompositionRects_t::name[]; +constexpr char GeckoEditable::UpdateCompositionRects_t::signature[]; + +auto GeckoEditable::UpdateCompositionRects(mozilla::jni::ObjectArray::Param a0) const -> void +{ + return mozilla::jni::Method<UpdateCompositionRects_t>::Call(GeckoEditable::mCtx, nullptr, a0); +} + +const char GeckoEditableListener::name[] = + "org/mozilla/gecko/GeckoEditableListener"; + +const char GeckoNetworkManager::name[] = + "org/mozilla/gecko/GeckoNetworkManager"; + +constexpr char GeckoNetworkManager::OnConnectionChanged_t::name[]; +constexpr char GeckoNetworkManager::OnConnectionChanged_t::signature[]; + +constexpr char GeckoNetworkManager::OnStatusChanged_t::name[]; +constexpr char GeckoNetworkManager::OnStatusChanged_t::signature[]; + +const char GeckoScreenOrientation::name[] = + "org/mozilla/gecko/GeckoScreenOrientation"; + +constexpr char GeckoScreenOrientation::OnOrientationChange_t::name[]; +constexpr char GeckoScreenOrientation::OnOrientationChange_t::signature[]; + +const char GeckoThread::name[] = + "org/mozilla/gecko/GeckoThread"; + +constexpr char GeckoThread::CheckAndSetState_t::name[]; +constexpr char GeckoThread::CheckAndSetState_t::signature[]; + +auto GeckoThread::CheckAndSetState(mozilla::jni::Object::Param a0, mozilla::jni::Object::Param a1) -> bool +{ + return mozilla::jni::Method<CheckAndSetState_t>::Call(GeckoThread::Context(), nullptr, a0, a1); +} + +constexpr char GeckoThread::CreateServices_t::name[]; +constexpr char GeckoThread::CreateServices_t::signature[]; + +constexpr char GeckoThread::OnPause_t::name[]; +constexpr char GeckoThread::OnPause_t::signature[]; + +constexpr char GeckoThread::OnResume_t::name[]; +constexpr char GeckoThread::OnResume_t::signature[]; + +constexpr char GeckoThread::PumpMessageLoop_t::name[]; +constexpr char GeckoThread::PumpMessageLoop_t::signature[]; + +auto GeckoThread::PumpMessageLoop(mozilla::jni::Object::Param a0) -> bool +{ + return mozilla::jni::Method<PumpMessageLoop_t>::Call(GeckoThread::Context(), nullptr, a0); +} + +constexpr char GeckoThread::RequestUiThreadCallback_t::name[]; +constexpr char GeckoThread::RequestUiThreadCallback_t::signature[]; + +auto GeckoThread::RequestUiThreadCallback(int64_t a0) -> void +{ + return mozilla::jni::Method<RequestUiThreadCallback_t>::Call(GeckoThread::Context(), nullptr, a0); +} + +constexpr char GeckoThread::RunUiThreadCallback_t::name[]; +constexpr char GeckoThread::RunUiThreadCallback_t::signature[]; + +constexpr char GeckoThread::SetState_t::name[]; +constexpr char GeckoThread::SetState_t::signature[]; + +auto GeckoThread::SetState(mozilla::jni::Object::Param a0) -> void +{ + return mozilla::jni::Method<SetState_t>::Call(GeckoThread::Context(), nullptr, a0); +} + +constexpr char GeckoThread::SpeculativeConnect_t::name[]; +constexpr char GeckoThread::SpeculativeConnect_t::signature[]; + +constexpr char GeckoThread::WaitOnGecko_t::name[]; +constexpr char GeckoThread::WaitOnGecko_t::signature[]; + +constexpr char GeckoThread::ClsLoader_t::name[]; +constexpr char GeckoThread::ClsLoader_t::signature[]; + +auto GeckoThread::ClsLoader() -> mozilla::jni::Object::LocalRef +{ + return mozilla::jni::Field<ClsLoader_t>::Get(GeckoThread::Context(), nullptr); +} + +constexpr char GeckoThread::MsgQueue_t::name[]; +constexpr char GeckoThread::MsgQueue_t::signature[]; + +auto GeckoThread::MsgQueue() -> mozilla::jni::Object::LocalRef +{ + return mozilla::jni::Field<MsgQueue_t>::Get(GeckoThread::Context(), nullptr); +} + +auto GeckoThread::MsgQueue(mozilla::jni::Object::Param a0) -> void +{ + return mozilla::jni::Field<MsgQueue_t>::Set(GeckoThread::Context(), nullptr, a0); +} + +const char GeckoThread::State::name[] = + "org/mozilla/gecko/GeckoThread$State"; + +constexpr char GeckoThread::State::EXITED_t::name[]; +constexpr char GeckoThread::State::EXITED_t::signature[]; + +auto GeckoThread::State::EXITED() -> State::LocalRef +{ + return mozilla::jni::Field<EXITED_t>::Get(State::Context(), nullptr); +} + +constexpr char GeckoThread::State::EXITING_t::name[]; +constexpr char GeckoThread::State::EXITING_t::signature[]; + +auto GeckoThread::State::EXITING() -> State::LocalRef +{ + return mozilla::jni::Field<EXITING_t>::Get(State::Context(), nullptr); +} + +constexpr char GeckoThread::State::INITIAL_t::name[]; +constexpr char GeckoThread::State::INITIAL_t::signature[]; + +auto GeckoThread::State::INITIAL() -> State::LocalRef +{ + return mozilla::jni::Field<INITIAL_t>::Get(State::Context(), nullptr); +} + +constexpr char GeckoThread::State::JNI_READY_t::name[]; +constexpr char GeckoThread::State::JNI_READY_t::signature[]; + +auto GeckoThread::State::JNI_READY() -> State::LocalRef +{ + return mozilla::jni::Field<JNI_READY_t>::Get(State::Context(), nullptr); +} + +constexpr char GeckoThread::State::LAUNCHED_t::name[]; +constexpr char GeckoThread::State::LAUNCHED_t::signature[]; + +auto GeckoThread::State::LAUNCHED() -> State::LocalRef +{ + return mozilla::jni::Field<LAUNCHED_t>::Get(State::Context(), nullptr); +} + +constexpr char GeckoThread::State::LIBS_READY_t::name[]; +constexpr char GeckoThread::State::LIBS_READY_t::signature[]; + +auto GeckoThread::State::LIBS_READY() -> State::LocalRef +{ + return mozilla::jni::Field<LIBS_READY_t>::Get(State::Context(), nullptr); +} + +constexpr char GeckoThread::State::MOZGLUE_READY_t::name[]; +constexpr char GeckoThread::State::MOZGLUE_READY_t::signature[]; + +auto GeckoThread::State::MOZGLUE_READY() -> State::LocalRef +{ + return mozilla::jni::Field<MOZGLUE_READY_t>::Get(State::Context(), nullptr); +} + +constexpr char GeckoThread::State::PROFILE_READY_t::name[]; +constexpr char GeckoThread::State::PROFILE_READY_t::signature[]; + +auto GeckoThread::State::PROFILE_READY() -> State::LocalRef +{ + return mozilla::jni::Field<PROFILE_READY_t>::Get(State::Context(), nullptr); +} + +constexpr char GeckoThread::State::RUNNING_t::name[]; +constexpr char GeckoThread::State::RUNNING_t::signature[]; + +auto GeckoThread::State::RUNNING() -> State::LocalRef +{ + return mozilla::jni::Field<RUNNING_t>::Get(State::Context(), nullptr); +} + +const char GeckoView::name[] = + "org/mozilla/gecko/GeckoView"; + +const char GeckoView::Window::name[] = + "org/mozilla/gecko/GeckoView$Window"; + +constexpr char GeckoView::Window::Close_t::name[]; +constexpr char GeckoView::Window::Close_t::signature[]; + +constexpr char GeckoView::Window::DisposeNative_t::name[]; +constexpr char GeckoView::Window::DisposeNative_t::signature[]; + +constexpr char GeckoView::Window::LoadUri_t::name[]; +constexpr char GeckoView::Window::LoadUri_t::signature[]; + +constexpr char GeckoView::Window::Open_t::name[]; +constexpr char GeckoView::Window::Open_t::signature[]; + +constexpr char GeckoView::Window::Reattach_t::name[]; +constexpr char GeckoView::Window::Reattach_t::signature[]; + +const char PrefsHelper::name[] = + "org/mozilla/gecko/PrefsHelper"; + +constexpr char PrefsHelper::CallPrefHandler_t::name[]; +constexpr char PrefsHelper::CallPrefHandler_t::signature[]; + +auto PrefsHelper::CallPrefHandler(mozilla::jni::Object::Param a0, int32_t a1, mozilla::jni::String::Param a2, bool a3, int32_t a4, mozilla::jni::String::Param a5) -> void +{ + return mozilla::jni::Method<CallPrefHandler_t>::Call(PrefsHelper::Context(), nullptr, a0, a1, a2, a3, a4, a5); +} + +constexpr char PrefsHelper::AddObserver_t::name[]; +constexpr char PrefsHelper::AddObserver_t::signature[]; + +constexpr char PrefsHelper::GetPrefs_t::name[]; +constexpr char PrefsHelper::GetPrefs_t::signature[]; + +constexpr char PrefsHelper::RemoveObserver_t::name[]; +constexpr char PrefsHelper::RemoveObserver_t::signature[]; + +constexpr char PrefsHelper::SetPref_t::name[]; +constexpr char PrefsHelper::SetPref_t::signature[]; + +constexpr char PrefsHelper::OnPrefChange_t::name[]; +constexpr char PrefsHelper::OnPrefChange_t::signature[]; + +auto PrefsHelper::OnPrefChange(mozilla::jni::String::Param a0, int32_t a1, bool a2, int32_t a3, mozilla::jni::String::Param a4) -> void +{ + return mozilla::jni::Method<OnPrefChange_t>::Call(PrefsHelper::Context(), nullptr, a0, a1, a2, a3, a4); +} + +const char SurfaceTextureListener::name[] = + "org/mozilla/gecko/SurfaceTextureListener"; + +constexpr char SurfaceTextureListener::New_t::name[]; +constexpr char SurfaceTextureListener::New_t::signature[]; + +auto SurfaceTextureListener::New() -> SurfaceTextureListener::LocalRef +{ + return mozilla::jni::Constructor<New_t>::Call(SurfaceTextureListener::Context(), nullptr); +} + +constexpr char SurfaceTextureListener::OnFrameAvailable_t::name[]; +constexpr char SurfaceTextureListener::OnFrameAvailable_t::signature[]; + +const char GeckoLayerClient::name[] = + "org/mozilla/gecko/gfx/GeckoLayerClient"; + +constexpr char GeckoLayerClient::ContentDocumentChanged_t::name[]; +constexpr char GeckoLayerClient::ContentDocumentChanged_t::signature[]; + +auto GeckoLayerClient::ContentDocumentChanged() const -> void +{ + return mozilla::jni::Method<ContentDocumentChanged_t>::Call(GeckoLayerClient::mCtx, nullptr); +} + +constexpr char GeckoLayerClient::CreateFrame_t::name[]; +constexpr char GeckoLayerClient::CreateFrame_t::signature[]; + +auto GeckoLayerClient::CreateFrame() const -> mozilla::jni::Object::LocalRef +{ + return mozilla::jni::Method<CreateFrame_t>::Call(GeckoLayerClient::mCtx, nullptr); +} + +constexpr char GeckoLayerClient::IsContentDocumentDisplayed_t::name[]; +constexpr char GeckoLayerClient::IsContentDocumentDisplayed_t::signature[]; + +auto GeckoLayerClient::IsContentDocumentDisplayed() const -> bool +{ + return mozilla::jni::Method<IsContentDocumentDisplayed_t>::Call(GeckoLayerClient::mCtx, nullptr); +} + +constexpr char GeckoLayerClient::OnGeckoReady_t::name[]; +constexpr char GeckoLayerClient::OnGeckoReady_t::signature[]; + +auto GeckoLayerClient::OnGeckoReady() const -> void +{ + return mozilla::jni::Method<OnGeckoReady_t>::Call(GeckoLayerClient::mCtx, nullptr); +} + +constexpr char GeckoLayerClient::SetFirstPaintViewport_t::name[]; +constexpr char GeckoLayerClient::SetFirstPaintViewport_t::signature[]; + +auto GeckoLayerClient::SetFirstPaintViewport(float a0, float a1, float a2, float a3, float a4, float a5, float a6) const -> void +{ + return mozilla::jni::Method<SetFirstPaintViewport_t>::Call(GeckoLayerClient::mCtx, nullptr, a0, a1, a2, a3, a4, a5, a6); +} + +constexpr char GeckoLayerClient::SyncFrameMetrics_t::name[]; +constexpr char GeckoLayerClient::SyncFrameMetrics_t::signature[]; + +auto GeckoLayerClient::SyncFrameMetrics(float a0, float a1, float a2, float a3, float a4, float a5, float a6, int32_t a7, int32_t a8, int32_t a9, int32_t a10, float a11, bool a12, int32_t a13) const -> mozilla::jni::Object::LocalRef +{ + return mozilla::jni::Method<SyncFrameMetrics_t>::Call(GeckoLayerClient::mCtx, nullptr, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); +} + +constexpr char GeckoLayerClient::SynthesizeNativeMouseEvent_t::name[]; +constexpr char GeckoLayerClient::SynthesizeNativeMouseEvent_t::signature[]; + +auto GeckoLayerClient::SynthesizeNativeMouseEvent(int32_t a0, int32_t a1, int32_t a2) const -> void +{ + return mozilla::jni::Method<SynthesizeNativeMouseEvent_t>::Call(GeckoLayerClient::mCtx, nullptr, a0, a1, a2); +} + +constexpr char GeckoLayerClient::SynthesizeNativeTouchPoint_t::name[]; +constexpr char GeckoLayerClient::SynthesizeNativeTouchPoint_t::signature[]; + +auto GeckoLayerClient::SynthesizeNativeTouchPoint(int32_t a0, int32_t a1, int32_t a2, int32_t a3, double a4, int32_t a5) const -> void +{ + return mozilla::jni::Method<SynthesizeNativeTouchPoint_t>::Call(GeckoLayerClient::mCtx, nullptr, a0, a1, a2, a3, a4, a5); +} + +constexpr char GeckoLayerClient::ClearColor_t::name[]; +constexpr char GeckoLayerClient::ClearColor_t::signature[]; + +auto GeckoLayerClient::ClearColor() const -> int32_t +{ + return mozilla::jni::Field<ClearColor_t>::Get(GeckoLayerClient::mCtx, nullptr); +} + +auto GeckoLayerClient::ClearColor(int32_t a0) const -> void +{ + return mozilla::jni::Field<ClearColor_t>::Set(GeckoLayerClient::mCtx, nullptr, a0); +} + +const char ImmutableViewportMetrics::name[] = + "org/mozilla/gecko/gfx/ImmutableViewportMetrics"; + +constexpr char ImmutableViewportMetrics::New_t::name[]; +constexpr char ImmutableViewportMetrics::New_t::signature[]; + +auto ImmutableViewportMetrics::New(float a0, float a1, float a2, float a3, float a4, float a5, float a6, float a7, float a8, float a9, int32_t a10, int32_t a11, float a12) -> ImmutableViewportMetrics::LocalRef +{ + return mozilla::jni::Constructor<New_t>::Call(ImmutableViewportMetrics::Context(), nullptr, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); +} + +const char LayerRenderer::name[] = + "org/mozilla/gecko/gfx/LayerRenderer"; + +const char LayerRenderer::Frame::name[] = + "org/mozilla/gecko/gfx/LayerRenderer$Frame"; + +constexpr char LayerRenderer::Frame::BeginDrawing_t::name[]; +constexpr char LayerRenderer::Frame::BeginDrawing_t::signature[]; + +auto LayerRenderer::Frame::BeginDrawing() const -> void +{ + return mozilla::jni::Method<BeginDrawing_t>::Call(Frame::mCtx, nullptr); +} + +constexpr char LayerRenderer::Frame::EndDrawing_t::name[]; +constexpr char LayerRenderer::Frame::EndDrawing_t::signature[]; + +auto LayerRenderer::Frame::EndDrawing() const -> void +{ + return mozilla::jni::Method<EndDrawing_t>::Call(Frame::mCtx, nullptr); +} + +const char LayerView::name[] = + "org/mozilla/gecko/gfx/LayerView"; + +constexpr char LayerView::GetCompositor_t::name[]; +constexpr char LayerView::GetCompositor_t::signature[]; + +auto LayerView::GetCompositor() const -> mozilla::jni::Object::LocalRef +{ + return mozilla::jni::Method<GetCompositor_t>::Call(LayerView::mCtx, nullptr); +} + +constexpr char LayerView::UpdateZoomedView_t::name[]; +constexpr char LayerView::UpdateZoomedView_t::signature[]; + +auto LayerView::UpdateZoomedView(mozilla::jni::ByteBuffer::Param a0) -> void +{ + return mozilla::jni::Method<UpdateZoomedView_t>::Call(LayerView::Context(), nullptr, a0); +} + +constexpr char LayerView::CompositorCreated_t::name[]; +constexpr char LayerView::CompositorCreated_t::signature[]; + +auto LayerView::CompositorCreated() const -> bool +{ + return mozilla::jni::Field<CompositorCreated_t>::Get(LayerView::mCtx, nullptr); +} + +auto LayerView::CompositorCreated(bool a0) const -> void +{ + return mozilla::jni::Field<CompositorCreated_t>::Set(LayerView::mCtx, nullptr, a0); +} + +const char LayerView::Compositor::name[] = + "org/mozilla/gecko/gfx/LayerView$Compositor"; + +constexpr char LayerView::Compositor::AttachToJava_t::name[]; +constexpr char LayerView::Compositor::AttachToJava_t::signature[]; + +constexpr char LayerView::Compositor::CreateCompositor_t::name[]; +constexpr char LayerView::Compositor::CreateCompositor_t::signature[]; + +constexpr char LayerView::Compositor::Destroy_t::name[]; +constexpr char LayerView::Compositor::Destroy_t::signature[]; + +auto LayerView::Compositor::Destroy() const -> void +{ + return mozilla::jni::Method<Destroy_t>::Call(Compositor::mCtx, nullptr); +} + +constexpr char LayerView::Compositor::DisposeNative_t::name[]; +constexpr char LayerView::Compositor::DisposeNative_t::signature[]; + +constexpr char LayerView::Compositor::OnSizeChanged_t::name[]; +constexpr char LayerView::Compositor::OnSizeChanged_t::signature[]; + +constexpr char LayerView::Compositor::Reattach_t::name[]; +constexpr char LayerView::Compositor::Reattach_t::signature[]; + +auto LayerView::Compositor::Reattach() const -> void +{ + return mozilla::jni::Method<Reattach_t>::Call(Compositor::mCtx, nullptr); +} + +constexpr char LayerView::Compositor::SyncInvalidateAndScheduleComposite_t::name[]; +constexpr char LayerView::Compositor::SyncInvalidateAndScheduleComposite_t::signature[]; + +constexpr char LayerView::Compositor::SyncPauseCompositor_t::name[]; +constexpr char LayerView::Compositor::SyncPauseCompositor_t::signature[]; + +constexpr char LayerView::Compositor::SyncResumeResizeCompositor_t::name[]; +constexpr char LayerView::Compositor::SyncResumeResizeCompositor_t::signature[]; + +const char NativePanZoomController::name[] = + "org/mozilla/gecko/gfx/NativePanZoomController"; + +constexpr char NativePanZoomController::AdjustScrollForSurfaceShift_t::name[]; +constexpr char NativePanZoomController::AdjustScrollForSurfaceShift_t::signature[]; + +constexpr char NativePanZoomController::Destroy_t::name[]; +constexpr char NativePanZoomController::Destroy_t::signature[]; + +auto NativePanZoomController::Destroy() const -> void +{ + return mozilla::jni::Method<Destroy_t>::Call(NativePanZoomController::mCtx, nullptr); +} + +constexpr char NativePanZoomController::DisposeNative_t::name[]; +constexpr char NativePanZoomController::DisposeNative_t::signature[]; + +constexpr char NativePanZoomController::HandleMotionEvent_t::name[]; +constexpr char NativePanZoomController::HandleMotionEvent_t::signature[]; + +constexpr char NativePanZoomController::HandleMotionEventVelocity_t::name[]; +constexpr char NativePanZoomController::HandleMotionEventVelocity_t::signature[]; + +constexpr char NativePanZoomController::HandleMouseEvent_t::name[]; +constexpr char NativePanZoomController::HandleMouseEvent_t::signature[]; + +constexpr char NativePanZoomController::HandleScrollEvent_t::name[]; +constexpr char NativePanZoomController::HandleScrollEvent_t::signature[]; + +constexpr char NativePanZoomController::SetIsLongpressEnabled_t::name[]; +constexpr char NativePanZoomController::SetIsLongpressEnabled_t::signature[]; + +constexpr char NativePanZoomController::OnSelectionDragState_t::name[]; +constexpr char NativePanZoomController::OnSelectionDragState_t::signature[]; + +auto NativePanZoomController::OnSelectionDragState(bool a0) const -> void +{ + return mozilla::jni::Method<OnSelectionDragState_t>::Call(NativePanZoomController::mCtx, nullptr, a0); +} + +constexpr char NativePanZoomController::SetScrollingRootContent_t::name[]; +constexpr char NativePanZoomController::SetScrollingRootContent_t::signature[]; + +auto NativePanZoomController::SetScrollingRootContent(bool a0) const -> void +{ + return mozilla::jni::Method<SetScrollingRootContent_t>::Call(NativePanZoomController::mCtx, nullptr, a0); +} + +constexpr char NativePanZoomController::UpdateOverscrollOffset_t::name[]; +constexpr char NativePanZoomController::UpdateOverscrollOffset_t::signature[]; + +auto NativePanZoomController::UpdateOverscrollOffset(float a0, float a1) const -> void +{ + return mozilla::jni::Method<UpdateOverscrollOffset_t>::Call(NativePanZoomController::mCtx, nullptr, a0, a1); +} + +constexpr char NativePanZoomController::UpdateOverscrollVelocity_t::name[]; +constexpr char NativePanZoomController::UpdateOverscrollVelocity_t::signature[]; + +auto NativePanZoomController::UpdateOverscrollVelocity(float a0, float a1) const -> void +{ + return mozilla::jni::Method<UpdateOverscrollVelocity_t>::Call(NativePanZoomController::mCtx, nullptr, a0, a1); +} + +const char ProgressiveUpdateData::name[] = + "org/mozilla/gecko/gfx/ProgressiveUpdateData"; + +constexpr char ProgressiveUpdateData::New_t::name[]; +constexpr char ProgressiveUpdateData::New_t::signature[]; + +auto ProgressiveUpdateData::New() -> ProgressiveUpdateData::LocalRef +{ + return mozilla::jni::Constructor<New_t>::Call(ProgressiveUpdateData::Context(), nullptr); +} + +constexpr char ProgressiveUpdateData::SetViewport_t::name[]; +constexpr char ProgressiveUpdateData::SetViewport_t::signature[]; + +auto ProgressiveUpdateData::SetViewport(mozilla::jni::Object::Param a0) const -> void +{ + return mozilla::jni::Method<SetViewport_t>::Call(ProgressiveUpdateData::mCtx, nullptr, a0); +} + +constexpr char ProgressiveUpdateData::Abort_t::name[]; +constexpr char ProgressiveUpdateData::Abort_t::signature[]; + +auto ProgressiveUpdateData::Abort() const -> bool +{ + return mozilla::jni::Field<Abort_t>::Get(ProgressiveUpdateData::mCtx, nullptr); +} + +auto ProgressiveUpdateData::Abort(bool a0) const -> void +{ + return mozilla::jni::Field<Abort_t>::Set(ProgressiveUpdateData::mCtx, nullptr, a0); +} + +constexpr char ProgressiveUpdateData::Scale_t::name[]; +constexpr char ProgressiveUpdateData::Scale_t::signature[]; + +auto ProgressiveUpdateData::Scale() const -> float +{ + return mozilla::jni::Field<Scale_t>::Get(ProgressiveUpdateData::mCtx, nullptr); +} + +auto ProgressiveUpdateData::Scale(float a0) const -> void +{ + return mozilla::jni::Field<Scale_t>::Set(ProgressiveUpdateData::mCtx, nullptr, a0); +} + +constexpr char ProgressiveUpdateData::X_t::name[]; +constexpr char ProgressiveUpdateData::X_t::signature[]; + +auto ProgressiveUpdateData::X() const -> float +{ + return mozilla::jni::Field<X_t>::Get(ProgressiveUpdateData::mCtx, nullptr); +} + +auto ProgressiveUpdateData::X(float a0) const -> void +{ + return mozilla::jni::Field<X_t>::Set(ProgressiveUpdateData::mCtx, nullptr, a0); +} + +constexpr char ProgressiveUpdateData::Y_t::name[]; +constexpr char ProgressiveUpdateData::Y_t::signature[]; + +auto ProgressiveUpdateData::Y() const -> float +{ + return mozilla::jni::Field<Y_t>::Get(ProgressiveUpdateData::mCtx, nullptr); +} + +auto ProgressiveUpdateData::Y(float a0) const -> void +{ + return mozilla::jni::Field<Y_t>::Set(ProgressiveUpdateData::mCtx, nullptr, a0); +} + +const char StackScroller::name[] = + "org/mozilla/gecko/gfx/StackScroller"; + +constexpr char StackScroller::New_t::name[]; +constexpr char StackScroller::New_t::signature[]; + +auto StackScroller::New(mozilla::jni::Object::Param a0, StackScroller::LocalRef* a1) -> nsresult +{ + MOZ_ASSERT(a1); + nsresult rv = NS_OK; + *a1 = mozilla::jni::Constructor<New_t>::Call(StackScroller::Context(), &rv, a0); + return rv; +} + +constexpr char StackScroller::AbortAnimation_t::name[]; +constexpr char StackScroller::AbortAnimation_t::signature[]; + +auto StackScroller::AbortAnimation() const -> nsresult +{ + nsresult rv = NS_OK; + mozilla::jni::Method<AbortAnimation_t>::Call(StackScroller::mCtx, &rv); + return rv; +} + +constexpr char StackScroller::ComputeScrollOffset_t::name[]; +constexpr char StackScroller::ComputeScrollOffset_t::signature[]; + +auto StackScroller::ComputeScrollOffset(int64_t a0, bool* a1) const -> nsresult +{ + MOZ_ASSERT(a1); + nsresult rv = NS_OK; + *a1 = mozilla::jni::Method<ComputeScrollOffset_t>::Call(StackScroller::mCtx, &rv, a0); + return rv; +} + +constexpr char StackScroller::Fling_t::name[]; +constexpr char StackScroller::Fling_t::signature[]; + +auto StackScroller::Fling(int32_t a0, int32_t a1, int32_t a2, int32_t a3, int32_t a4, int32_t a5, int32_t a6, int32_t a7, int32_t a8, int32_t a9, int64_t a10) const -> nsresult +{ + nsresult rv = NS_OK; + mozilla::jni::Method<Fling_t>::Call(StackScroller::mCtx, &rv, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); + return rv; +} + +constexpr char StackScroller::ForceFinished_t::name[]; +constexpr char StackScroller::ForceFinished_t::signature[]; + +auto StackScroller::ForceFinished(bool a0) const -> nsresult +{ + nsresult rv = NS_OK; + mozilla::jni::Method<ForceFinished_t>::Call(StackScroller::mCtx, &rv, a0); + return rv; +} + +constexpr char StackScroller::GetCurrSpeedX_t::name[]; +constexpr char StackScroller::GetCurrSpeedX_t::signature[]; + +auto StackScroller::GetCurrSpeedX(float* a0) const -> nsresult +{ + MOZ_ASSERT(a0); + nsresult rv = NS_OK; + *a0 = mozilla::jni::Method<GetCurrSpeedX_t>::Call(StackScroller::mCtx, &rv); + return rv; +} + +constexpr char StackScroller::GetCurrSpeedY_t::name[]; +constexpr char StackScroller::GetCurrSpeedY_t::signature[]; + +auto StackScroller::GetCurrSpeedY(float* a0) const -> nsresult +{ + MOZ_ASSERT(a0); + nsresult rv = NS_OK; + *a0 = mozilla::jni::Method<GetCurrSpeedY_t>::Call(StackScroller::mCtx, &rv); + return rv; +} + +constexpr char StackScroller::GetCurrX_t::name[]; +constexpr char StackScroller::GetCurrX_t::signature[]; + +auto StackScroller::GetCurrX(int32_t* a0) const -> nsresult +{ + MOZ_ASSERT(a0); + nsresult rv = NS_OK; + *a0 = mozilla::jni::Method<GetCurrX_t>::Call(StackScroller::mCtx, &rv); + return rv; +} + +constexpr char StackScroller::GetCurrY_t::name[]; +constexpr char StackScroller::GetCurrY_t::signature[]; + +auto StackScroller::GetCurrY(int32_t* a0) const -> nsresult +{ + MOZ_ASSERT(a0); + nsresult rv = NS_OK; + *a0 = mozilla::jni::Method<GetCurrY_t>::Call(StackScroller::mCtx, &rv); + return rv; +} + +constexpr char StackScroller::GetFinalX_t::name[]; +constexpr char StackScroller::GetFinalX_t::signature[]; + +auto StackScroller::GetFinalX(int32_t* a0) const -> nsresult +{ + MOZ_ASSERT(a0); + nsresult rv = NS_OK; + *a0 = mozilla::jni::Method<GetFinalX_t>::Call(StackScroller::mCtx, &rv); + return rv; +} + +constexpr char StackScroller::GetFinalY_t::name[]; +constexpr char StackScroller::GetFinalY_t::signature[]; + +auto StackScroller::GetFinalY(int32_t* a0) const -> nsresult +{ + MOZ_ASSERT(a0); + nsresult rv = NS_OK; + *a0 = mozilla::jni::Method<GetFinalY_t>::Call(StackScroller::mCtx, &rv); + return rv; +} + +constexpr char StackScroller::InitContants_t::name[]; +constexpr char StackScroller::InitContants_t::signature[]; + +auto StackScroller::InitContants() -> nsresult +{ + nsresult rv = NS_OK; + mozilla::jni::Method<InitContants_t>::Call(StackScroller::Context(), &rv); + return rv; +} + +constexpr char StackScroller::IsFinished_t::name[]; +constexpr char StackScroller::IsFinished_t::signature[]; + +auto StackScroller::IsFinished(bool* a0) const -> nsresult +{ + MOZ_ASSERT(a0); + nsresult rv = NS_OK; + *a0 = mozilla::jni::Method<IsFinished_t>::Call(StackScroller::mCtx, &rv); + return rv; +} + +constexpr char StackScroller::SetFinalX_t::name[]; +constexpr char StackScroller::SetFinalX_t::signature[]; + +auto StackScroller::SetFinalX(int32_t a0) const -> nsresult +{ + nsresult rv = NS_OK; + mozilla::jni::Method<SetFinalX_t>::Call(StackScroller::mCtx, &rv, a0); + return rv; +} + +constexpr char StackScroller::SpringBack_t::name[]; +constexpr char StackScroller::SpringBack_t::signature[]; + +auto StackScroller::SpringBack(int32_t a0, int32_t a1, int32_t a2, int32_t a3, int32_t a4, int32_t a5, int64_t a6, bool* a7) const -> nsresult +{ + MOZ_ASSERT(a7); + nsresult rv = NS_OK; + *a7 = mozilla::jni::Method<SpringBack_t>::Call(StackScroller::mCtx, &rv, a0, a1, a2, a3, a4, a5, a6); + return rv; +} + +constexpr char StackScroller::StartScroll_t::name[]; +constexpr char StackScroller::StartScroll_t::signature[]; + +auto StackScroller::StartScroll(int32_t a0, int32_t a1, int32_t a2, int32_t a3, int64_t a4, int32_t a5) const -> nsresult +{ + nsresult rv = NS_OK; + mozilla::jni::Method<StartScroll_t>::Call(StackScroller::mCtx, &rv, a0, a1, a2, a3, a4, a5); + return rv; +} + +constexpr char StackScroller::ViscousFluid_t::name[]; +constexpr char StackScroller::ViscousFluid_t::signature[]; + +auto StackScroller::ViscousFluid(float a0, float* a1) -> nsresult +{ + MOZ_ASSERT(a1); + nsresult rv = NS_OK; + *a1 = mozilla::jni::Method<ViscousFluid_t>::Call(StackScroller::Context(), &rv, a0); + return rv; +} + +constexpr char StackScroller::MFlywheel_t::name[]; +constexpr char StackScroller::MFlywheel_t::signature[]; + +auto StackScroller::MFlywheel(bool* a0) const -> nsresult +{ + MOZ_ASSERT(a0); + nsresult rv = NS_OK; + *a0 = mozilla::jni::Field<MFlywheel_t>::Get(StackScroller::mCtx, &rv); + return rv; +} + +constexpr char StackScroller::MMode_t::name[]; +constexpr char StackScroller::MMode_t::signature[]; + +auto StackScroller::MMode(int32_t* a0) const -> nsresult +{ + MOZ_ASSERT(a0); + nsresult rv = NS_OK; + *a0 = mozilla::jni::Field<MMode_t>::Get(StackScroller::mCtx, &rv); + return rv; +} + +auto StackScroller::MMode(int32_t a0) const -> nsresult +{ + nsresult rv = NS_OK; + mozilla::jni::Field<MMode_t>::Set(StackScroller::mCtx, &rv, a0); + return rv; +} + +constexpr char StackScroller::MScrollerX_t::name[]; +constexpr char StackScroller::MScrollerX_t::signature[]; + +auto StackScroller::MScrollerX(mozilla::jni::Object::LocalRef* a0) const -> nsresult +{ + MOZ_ASSERT(a0); + nsresult rv = NS_OK; + *a0 = mozilla::jni::Field<MScrollerX_t>::Get(StackScroller::mCtx, &rv); + return rv; +} + +constexpr char StackScroller::MScrollerY_t::name[]; +constexpr char StackScroller::MScrollerY_t::signature[]; + +auto StackScroller::MScrollerY(mozilla::jni::Object::LocalRef* a0) const -> nsresult +{ + MOZ_ASSERT(a0); + nsresult rv = NS_OK; + *a0 = mozilla::jni::Field<MScrollerY_t>::Get(StackScroller::mCtx, &rv); + return rv; +} + +constexpr char StackScroller::SViscousFluidNormalize_t::name[]; +constexpr char StackScroller::SViscousFluidNormalize_t::signature[]; + +auto StackScroller::SViscousFluidNormalize(float* a0) -> nsresult +{ + MOZ_ASSERT(a0); + nsresult rv = NS_OK; + *a0 = mozilla::jni::Field<SViscousFluidNormalize_t>::Get(StackScroller::Context(), &rv); + return rv; +} + +auto StackScroller::SViscousFluidNormalize(float a0) -> nsresult +{ + nsresult rv = NS_OK; + mozilla::jni::Field<SViscousFluidNormalize_t>::Set(StackScroller::Context(), &rv, a0); + return rv; +} + +constexpr char StackScroller::SViscousFluidScale_t::name[]; +constexpr char StackScroller::SViscousFluidScale_t::signature[]; + +auto StackScroller::SViscousFluidScale(float* a0) -> nsresult +{ + MOZ_ASSERT(a0); + nsresult rv = NS_OK; + *a0 = mozilla::jni::Field<SViscousFluidScale_t>::Get(StackScroller::Context(), &rv); + return rv; +} + +auto StackScroller::SViscousFluidScale(float a0) -> nsresult +{ + nsresult rv = NS_OK; + mozilla::jni::Field<SViscousFluidScale_t>::Set(StackScroller::Context(), &rv, a0); + return rv; +} + +const char ViewTransform::name[] = + "org/mozilla/gecko/gfx/ViewTransform"; + +constexpr char ViewTransform::New_t::name[]; +constexpr char ViewTransform::New_t::signature[]; + +auto ViewTransform::New(float a0, float a1, float a2) -> ViewTransform::LocalRef +{ + return mozilla::jni::Constructor<New_t>::Call(ViewTransform::Context(), nullptr, a0, a1, a2); +} + +constexpr char ViewTransform::FixedLayerMarginBottom_t::name[]; +constexpr char ViewTransform::FixedLayerMarginBottom_t::signature[]; + +auto ViewTransform::FixedLayerMarginBottom() const -> float +{ + return mozilla::jni::Field<FixedLayerMarginBottom_t>::Get(ViewTransform::mCtx, nullptr); +} + +auto ViewTransform::FixedLayerMarginBottom(float a0) const -> void +{ + return mozilla::jni::Field<FixedLayerMarginBottom_t>::Set(ViewTransform::mCtx, nullptr, a0); +} + +constexpr char ViewTransform::FixedLayerMarginLeft_t::name[]; +constexpr char ViewTransform::FixedLayerMarginLeft_t::signature[]; + +auto ViewTransform::FixedLayerMarginLeft() const -> float +{ + return mozilla::jni::Field<FixedLayerMarginLeft_t>::Get(ViewTransform::mCtx, nullptr); +} + +auto ViewTransform::FixedLayerMarginLeft(float a0) const -> void +{ + return mozilla::jni::Field<FixedLayerMarginLeft_t>::Set(ViewTransform::mCtx, nullptr, a0); +} + +constexpr char ViewTransform::FixedLayerMarginRight_t::name[]; +constexpr char ViewTransform::FixedLayerMarginRight_t::signature[]; + +auto ViewTransform::FixedLayerMarginRight() const -> float +{ + return mozilla::jni::Field<FixedLayerMarginRight_t>::Get(ViewTransform::mCtx, nullptr); +} + +auto ViewTransform::FixedLayerMarginRight(float a0) const -> void +{ + return mozilla::jni::Field<FixedLayerMarginRight_t>::Set(ViewTransform::mCtx, nullptr, a0); +} + +constexpr char ViewTransform::FixedLayerMarginTop_t::name[]; +constexpr char ViewTransform::FixedLayerMarginTop_t::signature[]; + +auto ViewTransform::FixedLayerMarginTop() const -> float +{ + return mozilla::jni::Field<FixedLayerMarginTop_t>::Get(ViewTransform::mCtx, nullptr); +} + +auto ViewTransform::FixedLayerMarginTop(float a0) const -> void +{ + return mozilla::jni::Field<FixedLayerMarginTop_t>::Set(ViewTransform::mCtx, nullptr, a0); +} + +constexpr char ViewTransform::Height_t::name[]; +constexpr char ViewTransform::Height_t::signature[]; + +auto ViewTransform::Height() const -> float +{ + return mozilla::jni::Field<Height_t>::Get(ViewTransform::mCtx, nullptr); +} + +auto ViewTransform::Height(float a0) const -> void +{ + return mozilla::jni::Field<Height_t>::Set(ViewTransform::mCtx, nullptr, a0); +} + +constexpr char ViewTransform::Scale_t::name[]; +constexpr char ViewTransform::Scale_t::signature[]; + +auto ViewTransform::Scale() const -> float +{ + return mozilla::jni::Field<Scale_t>::Get(ViewTransform::mCtx, nullptr); +} + +auto ViewTransform::Scale(float a0) const -> void +{ + return mozilla::jni::Field<Scale_t>::Set(ViewTransform::mCtx, nullptr, a0); +} + +constexpr char ViewTransform::Width_t::name[]; +constexpr char ViewTransform::Width_t::signature[]; + +auto ViewTransform::Width() const -> float +{ + return mozilla::jni::Field<Width_t>::Get(ViewTransform::mCtx, nullptr); +} + +auto ViewTransform::Width(float a0) const -> void +{ + return mozilla::jni::Field<Width_t>::Set(ViewTransform::mCtx, nullptr, a0); +} + +constexpr char ViewTransform::X_t::name[]; +constexpr char ViewTransform::X_t::signature[]; + +auto ViewTransform::X() const -> float +{ + return mozilla::jni::Field<X_t>::Get(ViewTransform::mCtx, nullptr); +} + +auto ViewTransform::X(float a0) const -> void +{ + return mozilla::jni::Field<X_t>::Set(ViewTransform::mCtx, nullptr, a0); +} + +constexpr char ViewTransform::Y_t::name[]; +constexpr char ViewTransform::Y_t::signature[]; + +auto ViewTransform::Y() const -> float +{ + return mozilla::jni::Field<Y_t>::Get(ViewTransform::mCtx, nullptr); +} + +auto ViewTransform::Y(float a0) const -> void +{ + return mozilla::jni::Field<Y_t>::Set(ViewTransform::mCtx, nullptr, a0); +} + +const char Clipboard::name[] = + "org/mozilla/gecko/util/Clipboard"; + +constexpr char Clipboard::ClearText_t::name[]; +constexpr char Clipboard::ClearText_t::signature[]; + +auto Clipboard::ClearText() -> void +{ + return mozilla::jni::Method<ClearText_t>::Call(Clipboard::Context(), nullptr); +} + +constexpr char Clipboard::GetText_t::name[]; +constexpr char Clipboard::GetText_t::signature[]; + +auto Clipboard::GetText() -> mozilla::jni::String::LocalRef +{ + return mozilla::jni::Method<GetText_t>::Call(Clipboard::Context(), nullptr); +} + +constexpr char Clipboard::HasText_t::name[]; +constexpr char Clipboard::HasText_t::signature[]; + +auto Clipboard::HasText() -> bool +{ + return mozilla::jni::Method<HasText_t>::Call(Clipboard::Context(), nullptr); +} + +constexpr char Clipboard::SetText_t::name[]; +constexpr char Clipboard::SetText_t::signature[]; + +auto Clipboard::SetText(mozilla::jni::String::Param a0) -> void +{ + return mozilla::jni::Method<SetText_t>::Call(Clipboard::Context(), nullptr, a0); +} + +const char HardwareCodecCapabilityUtils::name[] = + "org/mozilla/gecko/util/HardwareCodecCapabilityUtils"; + +constexpr char HardwareCodecCapabilityUtils::HasHWVP9_t::name[]; +constexpr char HardwareCodecCapabilityUtils::HasHWVP9_t::signature[]; + +auto HardwareCodecCapabilityUtils::HasHWVP9() -> bool +{ + return mozilla::jni::Method<HasHWVP9_t>::Call(HardwareCodecCapabilityUtils::Context(), nullptr); +} + +constexpr char HardwareCodecCapabilityUtils::FindDecoderCodecInfoForMimeType_t::name[]; +constexpr char HardwareCodecCapabilityUtils::FindDecoderCodecInfoForMimeType_t::signature[]; + +auto HardwareCodecCapabilityUtils::FindDecoderCodecInfoForMimeType(mozilla::jni::String::Param a0) -> bool +{ + return mozilla::jni::Method<FindDecoderCodecInfoForMimeType_t>::Call(HardwareCodecCapabilityUtils::Context(), nullptr, a0); +} + +const char NativeJSContainer::name[] = + "org/mozilla/gecko/util/NativeJSContainer"; + +constexpr char NativeJSContainer::New_t::name[]; +constexpr char NativeJSContainer::New_t::signature[]; + +auto NativeJSContainer::New() -> NativeJSContainer::LocalRef +{ + return mozilla::jni::Constructor<New_t>::Call(NativeJSContainer::Context(), nullptr); +} + +constexpr char NativeJSContainer::Clone2_t::name[]; +constexpr char NativeJSContainer::Clone2_t::signature[]; + +constexpr char NativeJSContainer::DisposeNative_t::name[]; +constexpr char NativeJSContainer::DisposeNative_t::signature[]; + +const char NativeJSObject::name[] = + "org/mozilla/gecko/util/NativeJSObject"; + +constexpr char NativeJSObject::New_t::name[]; +constexpr char NativeJSObject::New_t::signature[]; + +auto NativeJSObject::New() -> NativeJSObject::LocalRef +{ + return mozilla::jni::Constructor<New_t>::Call(NativeJSObject::Context(), nullptr); +} + +constexpr char NativeJSObject::DisposeNative_t::name[]; +constexpr char NativeJSObject::DisposeNative_t::signature[]; + +auto NativeJSObject::DisposeNative() const -> void +{ + return mozilla::jni::Method<DisposeNative_t>::Call(NativeJSObject::mCtx, nullptr); +} + +constexpr char NativeJSObject::GetBoolean_t::name[]; +constexpr char NativeJSObject::GetBoolean_t::signature[]; + +constexpr char NativeJSObject::GetBooleanArray_t::name[]; +constexpr char NativeJSObject::GetBooleanArray_t::signature[]; + +constexpr char NativeJSObject::GetBundle_t::name[]; +constexpr char NativeJSObject::GetBundle_t::signature[]; + +constexpr char NativeJSObject::GetBundleArray_t::name[]; +constexpr char NativeJSObject::GetBundleArray_t::signature[]; + +constexpr char NativeJSObject::GetDouble_t::name[]; +constexpr char NativeJSObject::GetDouble_t::signature[]; + +constexpr char NativeJSObject::GetDoubleArray_t::name[]; +constexpr char NativeJSObject::GetDoubleArray_t::signature[]; + +constexpr char NativeJSObject::GetInt_t::name[]; +constexpr char NativeJSObject::GetInt_t::signature[]; + +constexpr char NativeJSObject::GetIntArray_t::name[]; +constexpr char NativeJSObject::GetIntArray_t::signature[]; + +constexpr char NativeJSObject::GetObject_t::name[]; +constexpr char NativeJSObject::GetObject_t::signature[]; + +constexpr char NativeJSObject::GetObjectArray_t::name[]; +constexpr char NativeJSObject::GetObjectArray_t::signature[]; + +constexpr char NativeJSObject::GetString_t::name[]; +constexpr char NativeJSObject::GetString_t::signature[]; + +constexpr char NativeJSObject::GetStringArray_t::name[]; +constexpr char NativeJSObject::GetStringArray_t::signature[]; + +constexpr char NativeJSObject::Has_t::name[]; +constexpr char NativeJSObject::Has_t::signature[]; + +constexpr char NativeJSObject::OptBoolean_t::name[]; +constexpr char NativeJSObject::OptBoolean_t::signature[]; + +constexpr char NativeJSObject::OptBooleanArray_t::name[]; +constexpr char NativeJSObject::OptBooleanArray_t::signature[]; + +constexpr char NativeJSObject::OptBundle_t::name[]; +constexpr char NativeJSObject::OptBundle_t::signature[]; + +constexpr char NativeJSObject::OptBundleArray_t::name[]; +constexpr char NativeJSObject::OptBundleArray_t::signature[]; + +constexpr char NativeJSObject::OptDouble_t::name[]; +constexpr char NativeJSObject::OptDouble_t::signature[]; + +constexpr char NativeJSObject::OptDoubleArray_t::name[]; +constexpr char NativeJSObject::OptDoubleArray_t::signature[]; + +constexpr char NativeJSObject::OptInt_t::name[]; +constexpr char NativeJSObject::OptInt_t::signature[]; + +constexpr char NativeJSObject::OptIntArray_t::name[]; +constexpr char NativeJSObject::OptIntArray_t::signature[]; + +constexpr char NativeJSObject::OptObject_t::name[]; +constexpr char NativeJSObject::OptObject_t::signature[]; + +constexpr char NativeJSObject::OptObjectArray_t::name[]; +constexpr char NativeJSObject::OptObjectArray_t::signature[]; + +constexpr char NativeJSObject::OptString_t::name[]; +constexpr char NativeJSObject::OptString_t::signature[]; + +constexpr char NativeJSObject::OptStringArray_t::name[]; +constexpr char NativeJSObject::OptStringArray_t::signature[]; + +constexpr char NativeJSObject::ToBundle_t::name[]; +constexpr char NativeJSObject::ToBundle_t::signature[]; + +constexpr char NativeJSObject::ToString_t::name[]; +constexpr char NativeJSObject::ToString_t::signature[]; + +} /* java */ +} /* mozilla */ diff --git a/widget/android/GeneratedJNIWrappers.h b/widget/android/GeneratedJNIWrappers.h new file mode 100644 index 000000000..7d4777648 --- /dev/null +++ b/widget/android/GeneratedJNIWrappers.h @@ -0,0 +1,5456 @@ +// GENERATED CODE +// Generated by the Java program at /build/annotationProcessors at compile time +// from annotations on Java methods. To update, change the annotations on the +// corresponding Java methods and rerun the build. Manually updating this file +// will cause your build to fail. + +#ifndef GeneratedJNIWrappers_h +#define GeneratedJNIWrappers_h + +#include "mozilla/jni/Refs.h" + +namespace mozilla { +namespace java { + +class AlarmReceiver : public mozilla::jni::ObjectBase<AlarmReceiver> +{ +public: + static const char name[]; + + explicit AlarmReceiver(const Context& ctx) : ObjectBase<AlarmReceiver>(ctx) {} + + struct NotifyAlarmFired_t { + typedef AlarmReceiver Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "notifyAlarmFired"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + + template<class Impl> class Natives; +}; + +class AndroidGamepadManager : public mozilla::jni::ObjectBase<AndroidGamepadManager> +{ +public: + static const char name[]; + + explicit AndroidGamepadManager(const Context& ctx) : ObjectBase<AndroidGamepadManager>(ctx) {} + + struct OnAxisChange_t { + typedef AndroidGamepadManager Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + mozilla::jni::BooleanArray::Param, + mozilla::jni::FloatArray::Param> Args; + static constexpr char name[] = "onAxisChange"; + static constexpr char signature[] = + "(I[Z[F)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct OnButtonChange_t { + typedef AndroidGamepadManager Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + bool, + float> Args; + static constexpr char name[] = "onButtonChange"; + static constexpr char signature[] = + "(IIZF)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct OnGamepadAdded_t { + typedef AndroidGamepadManager Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t> Args; + static constexpr char name[] = "onGamepadAdded"; + static constexpr char signature[] = + "(II)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto OnGamepadAdded(int32_t, int32_t) -> void; + + struct OnGamepadChange_t { + typedef AndroidGamepadManager Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + bool> Args; + static constexpr char name[] = "onGamepadChange"; + static constexpr char signature[] = + "(IZ)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct Start_t { + typedef AndroidGamepadManager Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "start"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto Start() -> void; + + struct Stop_t { + typedef AndroidGamepadManager Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "stop"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto Stop() -> void; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class GeckoAppShell : public mozilla::jni::ObjectBase<GeckoAppShell> +{ +public: + static const char name[]; + + explicit GeckoAppShell(const Context& ctx) : ObjectBase<GeckoAppShell>(ctx) {} + + class CameraCallback; + + struct AddFullScreenPluginView_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "addFullScreenPluginView"; + static constexpr char signature[] = + "(Landroid/view/View;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto AddFullScreenPluginView(mozilla::jni::Object::Param) -> void; + + struct CancelVibrate_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "cancelVibrate"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto CancelVibrate() -> void; + + struct CheckURIVisited_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "checkUriVisited"; + static constexpr char signature[] = + "(Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto CheckURIVisited(mozilla::jni::String::Param) -> void; + + struct CloseCamera_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "closeCamera"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto CloseCamera() -> void; + + struct CloseNotification_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "closeNotification"; + static constexpr char signature[] = + "(Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto CloseNotification(mozilla::jni::String::Param) -> void; + + struct ConnectionGetMimeType_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::String::LocalRef ReturnType; + typedef mozilla::jni::String::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "connectionGetMimeType"; + static constexpr char signature[] = + "(Ljava/net/URLConnection;)Ljava/lang/String;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto ConnectionGetMimeType(mozilla::jni::Object::Param) -> mozilla::jni::String::LocalRef; + + struct CreateInputStream_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::Object::LocalRef ReturnType; + typedef mozilla::jni::Object::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "createInputStream"; + static constexpr char signature[] = + "(Ljava/net/URLConnection;)Ljava/io/InputStream;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto CreateInputStream(mozilla::jni::Object::Param) -> mozilla::jni::Object::LocalRef; + + struct CreateShortcut_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "createShortcut"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto CreateShortcut(mozilla::jni::String::Param, mozilla::jni::String::Param) -> void; + + struct DisableAlarm_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "disableAlarm"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto DisableAlarm() -> void; + + struct DisableBatteryNotifications_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "disableBatteryNotifications"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto DisableBatteryNotifications() -> void; + + struct DisableNetworkNotifications_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "disableNetworkNotifications"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto DisableNetworkNotifications() -> void; + + struct DisableScreenOrientationNotifications_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "disableScreenOrientationNotifications"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto DisableScreenOrientationNotifications() -> void; + + struct DisableSensor_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t> Args; + static constexpr char name[] = "disableSensor"; + static constexpr char signature[] = + "(I)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto DisableSensor(int32_t) -> void; + + struct EnableBatteryNotifications_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "enableBatteryNotifications"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto EnableBatteryNotifications() -> void; + + struct EnableLocation_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + bool> Args; + static constexpr char name[] = "enableLocation"; + static constexpr char signature[] = + "(Z)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto EnableLocation(bool) -> void; + + struct EnableLocationHighAccuracy_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + bool> Args; + static constexpr char name[] = "enableLocationHighAccuracy"; + static constexpr char signature[] = + "(Z)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto EnableLocationHighAccuracy(bool) -> void; + + struct EnableNetworkNotifications_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "enableNetworkNotifications"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto EnableNetworkNotifications() -> void; + + struct EnableScreenOrientationNotifications_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "enableScreenOrientationNotifications"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto EnableScreenOrientationNotifications() -> void; + + struct EnableSensor_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t> Args; + static constexpr char name[] = "enableSensor"; + static constexpr char signature[] = + "(I)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto EnableSensor(int32_t) -> void; + + struct GetApplicationContext_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::Object::LocalRef ReturnType; + typedef mozilla::jni::Object::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getApplicationContext"; + static constexpr char signature[] = + "()Landroid/content/Context;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetApplicationContext() -> mozilla::jni::Object::LocalRef; + + struct GetConnection_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::Object::LocalRef ReturnType; + typedef mozilla::jni::Object::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getConnection"; + static constexpr char signature[] = + "(Ljava/lang/String;)Ljava/net/URLConnection;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetConnection(mozilla::jni::String::Param) -> mozilla::jni::Object::LocalRef; + + struct GetContext_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::Object::LocalRef ReturnType; + typedef mozilla::jni::Object::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getContext"; + static constexpr char signature[] = + "()Landroid/content/Context;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetContext() -> mozilla::jni::Object::LocalRef; + + struct GetCurrentBatteryInformation_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::DoubleArray::LocalRef ReturnType; + typedef mozilla::jni::DoubleArray::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getCurrentBatteryInformation"; + static constexpr char signature[] = + "()[D"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetCurrentBatteryInformation() -> mozilla::jni::DoubleArray::LocalRef; + + struct GetCurrentNetworkInformation_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::DoubleArray::LocalRef ReturnType; + typedef mozilla::jni::DoubleArray::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getCurrentNetworkInformation"; + static constexpr char signature[] = + "()[D"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetCurrentNetworkInformation() -> mozilla::jni::DoubleArray::LocalRef; + + struct GetDensity_t { + typedef GeckoAppShell Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getDensity"; + static constexpr char signature[] = + "()F"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetDensity() -> float; + + struct GetDpi_t { + typedef GeckoAppShell Owner; + typedef int32_t ReturnType; + typedef int32_t SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getDpi"; + static constexpr char signature[] = + "()I"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetDpi() -> int32_t; + + struct GetExceptionStackTrace_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::String::LocalRef ReturnType; + typedef mozilla::jni::String::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Throwable::Param> Args; + static constexpr char name[] = "getExceptionStackTrace"; + static constexpr char signature[] = + "(Ljava/lang/Throwable;)Ljava/lang/String;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::IGNORE; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetExceptionStackTrace(mozilla::jni::Throwable::Param) -> mozilla::jni::String::LocalRef; + + struct GetExtensionFromMimeType_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::String::LocalRef ReturnType; + typedef mozilla::jni::String::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getExtensionFromMimeType"; + static constexpr char signature[] = + "(Ljava/lang/String;)Ljava/lang/String;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetExtensionFromMimeType(mozilla::jni::String::Param) -> mozilla::jni::String::LocalRef; + + struct GetHWDecoderCapability_t { + typedef GeckoAppShell Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getHWDecoderCapability"; + static constexpr char signature[] = + "()Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetHWDecoderCapability() -> bool; + + struct GetHWEncoderCapability_t { + typedef GeckoAppShell Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getHWEncoderCapability"; + static constexpr char signature[] = + "()Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetHWEncoderCapability() -> bool; + + struct GetHandlersForMimeType_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::ObjectArray::LocalRef ReturnType; + typedef mozilla::jni::ObjectArray::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getHandlersForMimeType"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetHandlersForMimeType(mozilla::jni::String::Param, mozilla::jni::String::Param) -> mozilla::jni::ObjectArray::LocalRef; + + struct GetHandlersForURL_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::ObjectArray::LocalRef ReturnType; + typedef mozilla::jni::ObjectArray::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getHandlersForURL"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetHandlersForURL(mozilla::jni::String::Param, mozilla::jni::String::Param) -> mozilla::jni::ObjectArray::LocalRef; + + struct GetIconForExtension_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::ByteArray::LocalRef ReturnType; + typedef mozilla::jni::ByteArray::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + int32_t> Args; + static constexpr char name[] = "getIconForExtension"; + static constexpr char signature[] = + "(Ljava/lang/String;I)[B"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetIconForExtension(mozilla::jni::String::Param, int32_t) -> mozilla::jni::ByteArray::LocalRef; + + struct GetMaxTouchPoints_t { + typedef GeckoAppShell Owner; + typedef int32_t ReturnType; + typedef int32_t SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getMaxTouchPoints"; + static constexpr char signature[] = + "()I"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetMaxTouchPoints() -> int32_t; + + struct GetMimeTypeFromExtensions_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::String::LocalRef ReturnType; + typedef mozilla::jni::String::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getMimeTypeFromExtensions"; + static constexpr char signature[] = + "(Ljava/lang/String;)Ljava/lang/String;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetMimeTypeFromExtensions(mozilla::jni::String::Param) -> mozilla::jni::String::LocalRef; + + struct GetNetworkLinkType_t { + typedef GeckoAppShell Owner; + typedef int32_t ReturnType; + typedef int32_t SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getNetworkLinkType"; + static constexpr char signature[] = + "()I"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetNetworkLinkType() -> int32_t; + + struct GetProxyForURI_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::String::LocalRef ReturnType; + typedef mozilla::jni::String::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param, + mozilla::jni::String::Param, + int32_t> Args; + static constexpr char name[] = "getProxyForURI"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/String;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetProxyForURI(mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param, int32_t) -> mozilla::jni::String::LocalRef; + + struct GetScreenAngle_t { + typedef GeckoAppShell Owner; + typedef int32_t ReturnType; + typedef int32_t SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getScreenAngle"; + static constexpr char signature[] = + "()I"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetScreenAngle() -> int32_t; + + struct GetScreenDepth_t { + typedef GeckoAppShell Owner; + typedef int32_t ReturnType; + typedef int32_t SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getScreenDepth"; + static constexpr char signature[] = + "()I"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetScreenDepth() -> int32_t; + + struct GetScreenOrientation_t { + typedef GeckoAppShell Owner; + typedef int16_t ReturnType; + typedef int16_t SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getScreenOrientation"; + static constexpr char signature[] = + "()S"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetScreenOrientation() -> int16_t; + + struct GetScreenSize_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::Object::LocalRef ReturnType; + typedef mozilla::jni::Object::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getScreenSize"; + static constexpr char signature[] = + "()Landroid/graphics/Rect;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetScreenSize() -> mozilla::jni::Object::LocalRef; + + struct GetShowPasswordSetting_t { + typedef GeckoAppShell Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getShowPasswordSetting"; + static constexpr char signature[] = + "()Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetShowPasswordSetting() -> bool; + + struct GetSystemColors_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::IntArray::LocalRef ReturnType; + typedef mozilla::jni::IntArray::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getSystemColors"; + static constexpr char signature[] = + "()[I"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetSystemColors() -> mozilla::jni::IntArray::LocalRef; + + struct HandleGeckoMessage_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "handleGeckoMessage"; + static constexpr char signature[] = + "(Lorg/mozilla/gecko/util/NativeJSContainer;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto HandleGeckoMessage(mozilla::jni::Object::Param) -> void; + + struct HandleUncaughtException_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Throwable::Param> Args; + static constexpr char name[] = "handleUncaughtException"; + static constexpr char signature[] = + "(Ljava/lang/Throwable;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::IGNORE; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto HandleUncaughtException(mozilla::jni::Throwable::Param) -> void; + + struct HideProgressDialog_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "hideProgressDialog"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto HideProgressDialog() -> void; + + struct InitCamera_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::IntArray::LocalRef ReturnType; + typedef mozilla::jni::IntArray::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + int32_t, + int32_t, + int32_t> Args; + static constexpr char name[] = "initCamera"; + static constexpr char signature[] = + "(Ljava/lang/String;III)[I"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto InitCamera(mozilla::jni::String::Param, int32_t, int32_t, int32_t) -> mozilla::jni::IntArray::LocalRef; + + struct IsNetworkLinkKnown_t { + typedef GeckoAppShell Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "isNetworkLinkKnown"; + static constexpr char signature[] = + "()Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto IsNetworkLinkKnown() -> bool; + + struct IsNetworkLinkUp_t { + typedef GeckoAppShell Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "isNetworkLinkUp"; + static constexpr char signature[] = + "()Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto IsNetworkLinkUp() -> bool; + + struct IsTablet_t { + typedef GeckoAppShell Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "isTablet"; + static constexpr char signature[] = + "()Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto IsTablet() -> bool; + + struct KillAnyZombies_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "killAnyZombies"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto KillAnyZombies() -> void; + + struct LoadPluginClass_t { + typedef GeckoAppShell Owner; + typedef mozilla::jni::Class::LocalRef ReturnType; + typedef mozilla::jni::Class::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "loadPluginClass"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Class;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto LoadPluginClass(mozilla::jni::String::Param, mozilla::jni::String::Param) -> mozilla::jni::Class::LocalRef; + + struct LockScreenOrientation_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t> Args; + static constexpr char name[] = "lockScreenOrientation"; + static constexpr char signature[] = + "(I)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto LockScreenOrientation(int32_t) -> void; + + struct MarkURIVisited_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "markUriVisited"; + static constexpr char signature[] = + "(Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto MarkURIVisited(mozilla::jni::String::Param) -> void; + + struct MoveTaskToBack_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "moveTaskToBack"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto MoveTaskToBack() -> void; + + struct NotifyObservers_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "nativeNotifyObservers"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct NotifyAlertListener_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "notifyAlertListener"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct NotifyUriVisited_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "notifyUriVisited"; + static constexpr char signature[] = + "(Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct NotifyWakeLockChanged_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "notifyWakeLockChanged"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto NotifyWakeLockChanged(mozilla::jni::String::Param, mozilla::jni::String::Param) -> void; + + struct OnFullScreenPluginHidden_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "onFullScreenPluginHidden"; + static constexpr char signature[] = + "(Landroid/view/View;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct OnLocationChanged_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + double, + double, + double, + float, + float, + float, + int64_t> Args; + static constexpr char name[] = "onLocationChanged"; + static constexpr char signature[] = + "(DDDFFFJ)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct OnSensorChanged_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + float, + float, + float, + float, + int32_t, + int64_t> Args; + static constexpr char name[] = "onSensorChanged"; + static constexpr char signature[] = + "(IFFFFIJ)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct OpenUriExternal_t { + typedef GeckoAppShell Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param, + mozilla::jni::String::Param, + mozilla::jni::String::Param, + mozilla::jni::String::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "openUriExternal"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto OpenUriExternal(mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param) -> bool; + + struct OpenWindowForNotification_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "openWindowForNotification"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto OpenWindowForNotification() -> void; + + struct PerformHapticFeedback_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + bool> Args; + static constexpr char name[] = "performHapticFeedback"; + static constexpr char signature[] = + "(Z)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto PerformHapticFeedback(bool) -> void; + + struct RemoveFullScreenPluginView_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "removeFullScreenPluginView"; + static constexpr char signature[] = + "(Landroid/view/View;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto RemoveFullScreenPluginView(mozilla::jni::Object::Param) -> void; + + struct ReportJavaCrash_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Throwable::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "reportJavaCrash"; + static constexpr char signature[] = + "(Ljava/lang/Throwable;Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct ScheduleRestart_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "scheduleRestart"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto ScheduleRestart() -> void; + + struct SetAlarm_t { + typedef GeckoAppShell Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t> Args; + static constexpr char name[] = "setAlarm"; + static constexpr char signature[] = + "(II)Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto SetAlarm(int32_t, int32_t) -> bool; + + struct SetFullScreen_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + bool> Args; + static constexpr char name[] = "setFullScreen"; + static constexpr char signature[] = + "(Z)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto SetFullScreen(bool) -> void; + + struct SetKeepScreenOn_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + bool> Args; + static constexpr char name[] = "setKeepScreenOn"; + static constexpr char signature[] = + "(Z)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto SetKeepScreenOn(bool) -> void; + + struct SetScreenDepthOverride_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t> Args; + static constexpr char name[] = "setScreenDepthOverride"; + static constexpr char signature[] = + "(I)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto SetScreenDepthOverride(int32_t) -> void; + + struct SetURITitle_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "setUriTitle"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto SetURITitle(mozilla::jni::String::Param, mozilla::jni::String::Param) -> void; + + struct ShowNotification_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param, + mozilla::jni::String::Param, + mozilla::jni::String::Param, + mozilla::jni::String::Param, + mozilla::jni::String::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "showNotification"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto ShowNotification(mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param) -> void; + + struct SyncNotifyObservers_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "syncNotifyObservers"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct UnlockProfile_t { + typedef GeckoAppShell Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "unlockProfile"; + static constexpr char signature[] = + "()Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto UnlockProfile() -> bool; + + struct UnlockScreenOrientation_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "unlockScreenOrientation"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto UnlockScreenOrientation() -> void; + + struct Vibrate_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int64_t> Args; + static constexpr char name[] = "vibrate"; + static constexpr char signature[] = + "(J)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto Vibrate(int64_t) -> void; + + struct Vibrate2_t { + typedef GeckoAppShell Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::LongArray::Param, + int32_t> Args; + static constexpr char name[] = "vibrate"; + static constexpr char signature[] = + "([JI)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto Vibrate(mozilla::jni::LongArray::Param, int32_t) -> void; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class GeckoAppShell::CameraCallback : public mozilla::jni::ObjectBase<CameraCallback> +{ +public: + static const char name[]; + + explicit CameraCallback(const Context& ctx) : ObjectBase<CameraCallback>(ctx) {} + + struct OnFrameData_t { + typedef CameraCallback Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + mozilla::jni::ByteArray::Param> Args; + static constexpr char name[] = "onFrameData"; + static constexpr char signature[] = + "(I[B)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + + template<class Impl> class Natives; +}; + +class GeckoBatteryManager : public mozilla::jni::ObjectBase<GeckoBatteryManager> +{ +public: + static const char name[]; + + explicit GeckoBatteryManager(const Context& ctx) : ObjectBase<GeckoBatteryManager>(ctx) {} + + struct OnBatteryChange_t { + typedef GeckoBatteryManager Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + double, + bool, + double> Args; + static constexpr char name[] = "onBatteryChange"; + static constexpr char signature[] = + "(DZD)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + + template<class Impl> class Natives; +}; + +class GeckoEditable : public mozilla::jni::ObjectBase<GeckoEditable> +{ +public: + static const char name[]; + + explicit GeckoEditable(const Context& ctx) : ObjectBase<GeckoEditable>(ctx) {} + + struct New_t { + typedef GeckoEditable Owner; + typedef GeckoEditable::LocalRef ReturnType; + typedef GeckoEditable::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "<init>"; + static constexpr char signature[] = + "(Lorg/mozilla/gecko/GeckoView;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto New(mozilla::jni::Object::Param) -> GeckoEditable::LocalRef; + + struct DisposeNative_t { + typedef GeckoEditable Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "disposeNative"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::PROXY; + }; + + struct NotifyIME_t { + typedef GeckoEditable Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t> Args; + static constexpr char name[] = "notifyIME"; + static constexpr char signature[] = + "(I)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto NotifyIME(int32_t) const -> void; + + struct NotifyIMEContext_t { + typedef GeckoEditable Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + mozilla::jni::String::Param, + mozilla::jni::String::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "notifyIMEContext"; + static constexpr char signature[] = + "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto NotifyIMEContext(int32_t, mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param) const -> void; + + struct OnDefaultKeyEvent_t { + typedef GeckoEditable Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "onDefaultKeyEvent"; + static constexpr char signature[] = + "(Landroid/view/KeyEvent;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto OnDefaultKeyEvent(mozilla::jni::Object::Param) const -> void; + + struct OnImeAddCompositionRange_t { + typedef GeckoEditable Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + int32_t, + int32_t, + int32_t, + bool, + int32_t, + int32_t, + int32_t> Args; + static constexpr char name[] = "onImeAddCompositionRange"; + static constexpr char signature[] = + "(IIIIIZIII)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::PROXY; + }; + + struct OnImeReplaceText_t { + typedef GeckoEditable Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "onImeReplaceText"; + static constexpr char signature[] = + "(IILjava/lang/String;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::PROXY; + }; + + struct OnImeRequestCursorUpdates_t { + typedef GeckoEditable Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t> Args; + static constexpr char name[] = "onImeRequestCursorUpdates"; + static constexpr char signature[] = + "(I)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::PROXY; + }; + + struct OnImeSynchronize_t { + typedef GeckoEditable Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "onImeSynchronize"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::PROXY; + }; + + struct OnImeUpdateComposition_t { + typedef GeckoEditable Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t> Args; + static constexpr char name[] = "onImeUpdateComposition"; + static constexpr char signature[] = + "(II)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::PROXY; + }; + + struct OnKeyEvent_t { + typedef GeckoEditable Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + int32_t, + int32_t, + int64_t, + int32_t, + int32_t, + int32_t, + int32_t, + int32_t, + bool, + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "onKeyEvent"; + static constexpr char signature[] = + "(IIIIJIIIIIZLandroid/view/KeyEvent;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::PROXY; + }; + + struct OnSelectionChange_t { + typedef GeckoEditable Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t> Args; + static constexpr char name[] = "onSelectionChange"; + static constexpr char signature[] = + "(II)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::IGNORE; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto OnSelectionChange(int32_t, int32_t) const -> void; + + struct OnTextChange_t { + typedef GeckoEditable Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + int32_t, + int32_t, + int32_t> Args; + static constexpr char name[] = "onTextChange"; + static constexpr char signature[] = + "(Ljava/lang/CharSequence;III)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::IGNORE; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto OnTextChange(mozilla::jni::String::Param, int32_t, int32_t, int32_t) const -> void; + + struct OnViewChange_t { + typedef GeckoEditable Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "onViewChange"; + static constexpr char signature[] = + "(Lorg/mozilla/gecko/GeckoView;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto OnViewChange(mozilla::jni::Object::Param) const -> void; + + struct UpdateCompositionRects_t { + typedef GeckoEditable Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::ObjectArray::Param> Args; + static constexpr char name[] = "updateCompositionRects"; + static constexpr char signature[] = + "([Landroid/graphics/RectF;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto UpdateCompositionRects(mozilla::jni::ObjectArray::Param) const -> void; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class GeckoEditableListener : public mozilla::jni::ObjectBase<GeckoEditableListener> +{ +public: + static const char name[]; + + explicit GeckoEditableListener(const Context& ctx) : ObjectBase<GeckoEditableListener>(ctx) {} + + static const int32_t NOTIFY_IME_OF_BLUR = 2; + + static const int32_t NOTIFY_IME_OF_FOCUS = 1; + + static const int32_t NOTIFY_IME_OPEN_VKB = -2; + + static const int32_t NOTIFY_IME_REPLY_EVENT = -1; + + static const int32_t NOTIFY_IME_TO_CANCEL_COMPOSITION = 9; + + static const int32_t NOTIFY_IME_TO_COMMIT_COMPOSITION = 8; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + +}; + +class GeckoNetworkManager : public mozilla::jni::ObjectBase<GeckoNetworkManager> +{ +public: + static const char name[]; + + explicit GeckoNetworkManager(const Context& ctx) : ObjectBase<GeckoNetworkManager>(ctx) {} + + struct OnConnectionChanged_t { + typedef GeckoNetworkManager Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + mozilla::jni::String::Param, + bool, + int32_t> Args; + static constexpr char name[] = "onConnectionChanged"; + static constexpr char signature[] = + "(ILjava/lang/String;ZI)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct OnStatusChanged_t { + typedef GeckoNetworkManager Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "onStatusChanged"; + static constexpr char signature[] = + "(Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class GeckoScreenOrientation : public mozilla::jni::ObjectBase<GeckoScreenOrientation> +{ +public: + static const char name[]; + + explicit GeckoScreenOrientation(const Context& ctx) : ObjectBase<GeckoScreenOrientation>(ctx) {} + + struct OnOrientationChange_t { + typedef GeckoScreenOrientation Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int16_t, + int16_t> Args; + static constexpr char name[] = "onOrientationChange"; + static constexpr char signature[] = + "(SS)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class GeckoThread : public mozilla::jni::ObjectBase<GeckoThread> +{ +public: + static const char name[]; + + explicit GeckoThread(const Context& ctx) : ObjectBase<GeckoThread>(ctx) {} + + class State; + + struct CheckAndSetState_t { + typedef GeckoThread Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param, + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "checkAndSetState"; + static constexpr char signature[] = + "(Lorg/mozilla/gecko/GeckoThread$State;Lorg/mozilla/gecko/GeckoThread$State;)Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto CheckAndSetState(mozilla::jni::Object::Param, mozilla::jni::Object::Param) -> bool; + + struct CreateServices_t { + typedef GeckoThread Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "nativeCreateServices"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct OnPause_t { + typedef GeckoThread Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "nativeOnPause"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct OnResume_t { + typedef GeckoThread Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "nativeOnResume"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct PumpMessageLoop_t { + typedef GeckoThread Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "pumpMessageLoop"; + static constexpr char signature[] = + "(Landroid/os/Message;)Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto PumpMessageLoop(mozilla::jni::Object::Param) -> bool; + + struct RequestUiThreadCallback_t { + typedef GeckoThread Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int64_t> Args; + static constexpr char name[] = "requestUiThreadCallback"; + static constexpr char signature[] = + "(J)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto RequestUiThreadCallback(int64_t) -> void; + + struct RunUiThreadCallback_t { + typedef GeckoThread Owner; + typedef int64_t ReturnType; + typedef int64_t SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "runUiThreadCallback"; + static constexpr char signature[] = + "()J"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct SetState_t { + typedef GeckoThread Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "setState"; + static constexpr char signature[] = + "(Lorg/mozilla/gecko/GeckoThread$State;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto SetState(mozilla::jni::Object::Param) -> void; + + struct SpeculativeConnect_t { + typedef GeckoThread Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "speculativeConnectNative"; + static constexpr char signature[] = + "(Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct WaitOnGecko_t { + typedef GeckoThread Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "waitOnGecko"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct ClsLoader_t { + typedef GeckoThread Owner; + typedef mozilla::jni::Object::LocalRef ReturnType; + typedef mozilla::jni::Object::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "clsLoader"; + static constexpr char signature[] = + "Ljava/lang/ClassLoader;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto ClsLoader() -> mozilla::jni::Object::LocalRef; + + struct MsgQueue_t { + typedef GeckoThread Owner; + typedef mozilla::jni::Object::LocalRef ReturnType; + typedef mozilla::jni::Object::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "msgQueue"; + static constexpr char signature[] = + "Landroid/os/MessageQueue;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto MsgQueue() -> mozilla::jni::Object::LocalRef; + + static auto MsgQueue(mozilla::jni::Object::Param) -> void; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class GeckoThread::State : public mozilla::jni::ObjectBase<State> +{ +public: + static const char name[]; + + explicit State(const Context& ctx) : ObjectBase<State>(ctx) {} + + struct EXITED_t { + typedef State Owner; + typedef State::LocalRef ReturnType; + typedef State::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "EXITED"; + static constexpr char signature[] = + "Lorg/mozilla/gecko/GeckoThread$State;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto EXITED() -> State::LocalRef; + + struct EXITING_t { + typedef State Owner; + typedef State::LocalRef ReturnType; + typedef State::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "EXITING"; + static constexpr char signature[] = + "Lorg/mozilla/gecko/GeckoThread$State;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto EXITING() -> State::LocalRef; + + struct INITIAL_t { + typedef State Owner; + typedef State::LocalRef ReturnType; + typedef State::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "INITIAL"; + static constexpr char signature[] = + "Lorg/mozilla/gecko/GeckoThread$State;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto INITIAL() -> State::LocalRef; + + struct JNI_READY_t { + typedef State Owner; + typedef State::LocalRef ReturnType; + typedef State::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "JNI_READY"; + static constexpr char signature[] = + "Lorg/mozilla/gecko/GeckoThread$State;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto JNI_READY() -> State::LocalRef; + + struct LAUNCHED_t { + typedef State Owner; + typedef State::LocalRef ReturnType; + typedef State::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "LAUNCHED"; + static constexpr char signature[] = + "Lorg/mozilla/gecko/GeckoThread$State;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto LAUNCHED() -> State::LocalRef; + + struct LIBS_READY_t { + typedef State Owner; + typedef State::LocalRef ReturnType; + typedef State::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "LIBS_READY"; + static constexpr char signature[] = + "Lorg/mozilla/gecko/GeckoThread$State;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto LIBS_READY() -> State::LocalRef; + + struct MOZGLUE_READY_t { + typedef State Owner; + typedef State::LocalRef ReturnType; + typedef State::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "MOZGLUE_READY"; + static constexpr char signature[] = + "Lorg/mozilla/gecko/GeckoThread$State;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto MOZGLUE_READY() -> State::LocalRef; + + struct PROFILE_READY_t { + typedef State Owner; + typedef State::LocalRef ReturnType; + typedef State::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "PROFILE_READY"; + static constexpr char signature[] = + "Lorg/mozilla/gecko/GeckoThread$State;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto PROFILE_READY() -> State::LocalRef; + + struct RUNNING_t { + typedef State Owner; + typedef State::LocalRef ReturnType; + typedef State::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "RUNNING"; + static constexpr char signature[] = + "Lorg/mozilla/gecko/GeckoThread$State;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto RUNNING() -> State::LocalRef; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + +}; + +class GeckoView : public mozilla::jni::ObjectBase<GeckoView> +{ +public: + static const char name[]; + + explicit GeckoView(const Context& ctx) : ObjectBase<GeckoView>(ctx) {} + + class Window; + + static const int32_t LOAD_DEFAULT = 0; + + static const int32_t LOAD_NEW_TAB = 1; + + static const int32_t LOAD_SWITCH_TAB = 2; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + +}; + +class GeckoView::Window : public mozilla::jni::ObjectBase<Window> +{ +public: + static const char name[]; + + explicit Window(const Context& ctx) : ObjectBase<Window>(ctx) {} + + struct Close_t { + typedef Window Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "close"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::PROXY; + }; + + struct DisposeNative_t { + typedef Window Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "disposeNative"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::PROXY; + }; + + struct LoadUri_t { + typedef Window Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + int32_t> Args; + static constexpr char name[] = "loadUri"; + static constexpr char signature[] = + "(Ljava/lang/String;I)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::PROXY; + }; + + struct Open_t { + typedef Window Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + Window::Param, + GeckoView::Param, + mozilla::jni::Object::Param, + mozilla::jni::String::Param, + int32_t> Args; + static constexpr char name[] = "open"; + static constexpr char signature[] = + "(Lorg/mozilla/gecko/GeckoView$Window;Lorg/mozilla/gecko/GeckoView;Ljava/lang/Object;Ljava/lang/String;I)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::PROXY; + }; + + struct Reattach_t { + typedef Window Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + GeckoView::Param, + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "reattach"; + static constexpr char signature[] = + "(Lorg/mozilla/gecko/GeckoView;Ljava/lang/Object;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::PROXY; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class PrefsHelper : public mozilla::jni::ObjectBase<PrefsHelper> +{ +public: + static const char name[]; + + explicit PrefsHelper(const Context& ctx) : ObjectBase<PrefsHelper>(ctx) {} + + struct CallPrefHandler_t { + typedef PrefsHelper Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param, + int32_t, + mozilla::jni::String::Param, + bool, + int32_t, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "callPrefHandler"; + static constexpr char signature[] = + "(Lorg/mozilla/gecko/PrefsHelper$PrefHandler;ILjava/lang/String;ZILjava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto CallPrefHandler(mozilla::jni::Object::Param, int32_t, mozilla::jni::String::Param, bool, int32_t, mozilla::jni::String::Param) -> void; + + struct AddObserver_t { + typedef PrefsHelper Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::ObjectArray::Param, + mozilla::jni::Object::Param, + mozilla::jni::ObjectArray::Param> Args; + static constexpr char name[] = "nativeAddObserver"; + static constexpr char signature[] = + "([Ljava/lang/String;Lorg/mozilla/gecko/PrefsHelper$PrefHandler;[Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct GetPrefs_t { + typedef PrefsHelper Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::ObjectArray::Param, + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "nativeGetPrefs"; + static constexpr char signature[] = + "([Ljava/lang/String;Lorg/mozilla/gecko/PrefsHelper$PrefHandler;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct RemoveObserver_t { + typedef PrefsHelper Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::ObjectArray::Param> Args; + static constexpr char name[] = "nativeRemoveObserver"; + static constexpr char signature[] = + "([Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct SetPref_t { + typedef PrefsHelper Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + bool, + int32_t, + bool, + int32_t, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "nativeSetPref"; + static constexpr char signature[] = + "(Ljava/lang/String;ZIZILjava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct OnPrefChange_t { + typedef PrefsHelper Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + int32_t, + bool, + int32_t, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "onPrefChange"; + static constexpr char signature[] = + "(Ljava/lang/String;IZILjava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto OnPrefChange(mozilla::jni::String::Param, int32_t, bool, int32_t, mozilla::jni::String::Param) -> void; + + static const int32_t PREF_BOOL = 1; + + static const int32_t PREF_FINISH = 0; + + static const int32_t PREF_INT = 2; + + static const int32_t PREF_INVALID = -1; + + static const int32_t PREF_STRING = 3; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class SurfaceTextureListener : public mozilla::jni::ObjectBase<SurfaceTextureListener> +{ +public: + static const char name[]; + + explicit SurfaceTextureListener(const Context& ctx) : ObjectBase<SurfaceTextureListener>(ctx) {} + + struct New_t { + typedef SurfaceTextureListener Owner; + typedef SurfaceTextureListener::LocalRef ReturnType; + typedef SurfaceTextureListener::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "<init>"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto New() -> SurfaceTextureListener::LocalRef; + + struct OnFrameAvailable_t { + typedef SurfaceTextureListener Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "nativeOnFrameAvailable"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class GeckoLayerClient : public mozilla::jni::ObjectBase<GeckoLayerClient> +{ +public: + static const char name[]; + + explicit GeckoLayerClient(const Context& ctx) : ObjectBase<GeckoLayerClient>(ctx) {} + + struct ContentDocumentChanged_t { + typedef GeckoLayerClient Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "contentDocumentChanged"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto ContentDocumentChanged() const -> void; + + struct CreateFrame_t { + typedef GeckoLayerClient Owner; + typedef mozilla::jni::Object::LocalRef ReturnType; + typedef mozilla::jni::Object::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "createFrame"; + static constexpr char signature[] = + "()Lorg/mozilla/gecko/gfx/LayerRenderer$Frame;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto CreateFrame() const -> mozilla::jni::Object::LocalRef; + + struct IsContentDocumentDisplayed_t { + typedef GeckoLayerClient Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "isContentDocumentDisplayed"; + static constexpr char signature[] = + "()Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto IsContentDocumentDisplayed() const -> bool; + + struct OnGeckoReady_t { + typedef GeckoLayerClient Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "onGeckoReady"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto OnGeckoReady() const -> void; + + struct SetFirstPaintViewport_t { + typedef GeckoLayerClient Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + float, + float, + float, + float, + float, + float, + float> Args; + static constexpr char name[] = "setFirstPaintViewport"; + static constexpr char signature[] = + "(FFFFFFF)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto SetFirstPaintViewport(float, float, float, float, float, float, float) const -> void; + + struct SyncFrameMetrics_t { + typedef GeckoLayerClient Owner; + typedef mozilla::jni::Object::LocalRef ReturnType; + typedef mozilla::jni::Object::Param SetterType; + typedef mozilla::jni::Args< + float, + float, + float, + float, + float, + float, + float, + int32_t, + int32_t, + int32_t, + int32_t, + float, + bool, + int32_t> Args; + static constexpr char name[] = "syncFrameMetrics"; + static constexpr char signature[] = + "(FFFFFFFIIIIFZI)Lorg/mozilla/gecko/gfx/ViewTransform;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto SyncFrameMetrics(float, float, float, float, float, float, float, int32_t, int32_t, int32_t, int32_t, float, bool, int32_t) const -> mozilla::jni::Object::LocalRef; + + struct SynthesizeNativeMouseEvent_t { + typedef GeckoLayerClient Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + int32_t> Args; + static constexpr char name[] = "synthesizeNativeMouseEvent"; + static constexpr char signature[] = + "(III)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto SynthesizeNativeMouseEvent(int32_t, int32_t, int32_t) const -> void; + + struct SynthesizeNativeTouchPoint_t { + typedef GeckoLayerClient Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + int32_t, + int32_t, + double, + int32_t> Args; + static constexpr char name[] = "synthesizeNativeTouchPoint"; + static constexpr char signature[] = + "(IIIIDI)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto SynthesizeNativeTouchPoint(int32_t, int32_t, int32_t, int32_t, double, int32_t) const -> void; + + struct ClearColor_t { + typedef GeckoLayerClient Owner; + typedef int32_t ReturnType; + typedef int32_t SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "mClearColor"; + static constexpr char signature[] = + "I"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto ClearColor() const -> int32_t; + + auto ClearColor(int32_t) const -> void; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + +}; + +class ImmutableViewportMetrics : public mozilla::jni::ObjectBase<ImmutableViewportMetrics> +{ +public: + static const char name[]; + + explicit ImmutableViewportMetrics(const Context& ctx) : ObjectBase<ImmutableViewportMetrics>(ctx) {} + + struct New_t { + typedef ImmutableViewportMetrics Owner; + typedef ImmutableViewportMetrics::LocalRef ReturnType; + typedef ImmutableViewportMetrics::Param SetterType; + typedef mozilla::jni::Args< + float, + float, + float, + float, + float, + float, + float, + float, + float, + float, + int32_t, + int32_t, + float> Args; + static constexpr char name[] = "<init>"; + static constexpr char signature[] = + "(FFFFFFFFFFIIF)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto New(float, float, float, float, float, float, float, float, float, float, int32_t, int32_t, float) -> ImmutableViewportMetrics::LocalRef; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + +}; + +class LayerRenderer : public mozilla::jni::ObjectBase<LayerRenderer> +{ +public: + static const char name[]; + + explicit LayerRenderer(const Context& ctx) : ObjectBase<LayerRenderer>(ctx) {} + + class Frame; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + +}; + +class LayerRenderer::Frame : public mozilla::jni::ObjectBase<Frame> +{ +public: + static const char name[]; + + explicit Frame(const Context& ctx) : ObjectBase<Frame>(ctx) {} + + struct BeginDrawing_t { + typedef Frame Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "beginDrawing"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto BeginDrawing() const -> void; + + struct EndDrawing_t { + typedef Frame Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "endDrawing"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto EndDrawing() const -> void; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + +}; + +class LayerView : public mozilla::jni::ObjectBase<LayerView> +{ +public: + static const char name[]; + + explicit LayerView(const Context& ctx) : ObjectBase<LayerView>(ctx) {} + + class Compositor; + + struct GetCompositor_t { + typedef LayerView Owner; + typedef mozilla::jni::Object::LocalRef ReturnType; + typedef mozilla::jni::Object::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getCompositor"; + static constexpr char signature[] = + "()Ljava/lang/Object;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto GetCompositor() const -> mozilla::jni::Object::LocalRef; + + struct UpdateZoomedView_t { + typedef LayerView Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::ByteBuffer::Param> Args; + static constexpr char name[] = "updateZoomedView"; + static constexpr char signature[] = + "(Ljava/nio/ByteBuffer;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto UpdateZoomedView(mozilla::jni::ByteBuffer::Param) -> void; + + struct CompositorCreated_t { + typedef LayerView Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "mCompositorCreated"; + static constexpr char signature[] = + "Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto CompositorCreated() const -> bool; + + auto CompositorCreated(bool) const -> void; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + +}; + +class LayerView::Compositor : public mozilla::jni::ObjectBase<Compositor> +{ +public: + static const char name[]; + + explicit Compositor(const Context& ctx) : ObjectBase<Compositor>(ctx) {} + + struct AttachToJava_t { + typedef Compositor Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param, + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "attachToJava"; + static constexpr char signature[] = + "(Lorg/mozilla/gecko/gfx/GeckoLayerClient;Lorg/mozilla/gecko/gfx/NativePanZoomController;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct CreateCompositor_t { + typedef Compositor Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "createCompositor"; + static constexpr char signature[] = + "(IILjava/lang/Object;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::PROXY; + }; + + struct Destroy_t { + typedef Compositor Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "destroy"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Destroy() const -> void; + + struct DisposeNative_t { + typedef Compositor Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "disposeNative"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct OnSizeChanged_t { + typedef Compositor Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + int32_t, + int32_t> Args; + static constexpr char name[] = "onSizeChanged"; + static constexpr char signature[] = + "(IIII)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct Reattach_t { + typedef Compositor Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "reattach"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Reattach() const -> void; + + struct SyncInvalidateAndScheduleComposite_t { + typedef Compositor Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "syncInvalidateAndScheduleComposite"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct SyncPauseCompositor_t { + typedef Compositor Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "syncPauseCompositor"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct SyncResumeResizeCompositor_t { + typedef Compositor Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "syncResumeResizeCompositor"; + static constexpr char signature[] = + "(IILjava/lang/Object;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class NativePanZoomController : public mozilla::jni::ObjectBase<NativePanZoomController> +{ +public: + static const char name[]; + + explicit NativePanZoomController(const Context& ctx) : ObjectBase<NativePanZoomController>(ctx) {} + + struct AdjustScrollForSurfaceShift_t { + typedef NativePanZoomController Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + float, + float> Args; + static constexpr char name[] = "adjustScrollForSurfaceShift"; + static constexpr char signature[] = + "(FF)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct Destroy_t { + typedef NativePanZoomController Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "destroy"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Destroy() const -> void; + + struct DisposeNative_t { + typedef NativePanZoomController Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "disposeNative"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct HandleMotionEvent_t { + typedef NativePanZoomController Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + int64_t, + int32_t, + mozilla::jni::IntArray::Param, + mozilla::jni::FloatArray::Param, + mozilla::jni::FloatArray::Param, + mozilla::jni::FloatArray::Param, + mozilla::jni::FloatArray::Param, + mozilla::jni::FloatArray::Param, + mozilla::jni::FloatArray::Param> Args; + static constexpr char name[] = "handleMotionEvent"; + static constexpr char signature[] = + "(IIJI[I[F[F[F[F[F[F)Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct HandleMotionEventVelocity_t { + typedef NativePanZoomController Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int64_t, + float> Args; + static constexpr char name[] = "handleMotionEventVelocity"; + static constexpr char signature[] = + "(JF)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct HandleMouseEvent_t { + typedef NativePanZoomController Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + int32_t, + int64_t, + int32_t, + float, + float, + int32_t> Args; + static constexpr char name[] = "handleMouseEvent"; + static constexpr char signature[] = + "(IJIFFI)Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct HandleScrollEvent_t { + typedef NativePanZoomController Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + int64_t, + int32_t, + float, + float, + float, + float> Args; + static constexpr char name[] = "handleScrollEvent"; + static constexpr char signature[] = + "(JIFFFF)Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct SetIsLongpressEnabled_t { + typedef NativePanZoomController Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + bool> Args; + static constexpr char name[] = "nativeSetIsLongpressEnabled"; + static constexpr char signature[] = + "(Z)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OnSelectionDragState_t { + typedef NativePanZoomController Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + bool> Args; + static constexpr char name[] = "onSelectionDragState"; + static constexpr char signature[] = + "(Z)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto OnSelectionDragState(bool) const -> void; + + struct SetScrollingRootContent_t { + typedef NativePanZoomController Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + bool> Args; + static constexpr char name[] = "setScrollingRootContent"; + static constexpr char signature[] = + "(Z)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto SetScrollingRootContent(bool) const -> void; + + struct UpdateOverscrollOffset_t { + typedef NativePanZoomController Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + float, + float> Args; + static constexpr char name[] = "updateOverscrollOffset"; + static constexpr char signature[] = + "(FF)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto UpdateOverscrollOffset(float, float) const -> void; + + struct UpdateOverscrollVelocity_t { + typedef NativePanZoomController Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + float, + float> Args; + static constexpr char name[] = "updateOverscrollVelocity"; + static constexpr char signature[] = + "(FF)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto UpdateOverscrollVelocity(float, float) const -> void; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class ProgressiveUpdateData : public mozilla::jni::ObjectBase<ProgressiveUpdateData> +{ +public: + static const char name[]; + + explicit ProgressiveUpdateData(const Context& ctx) : ObjectBase<ProgressiveUpdateData>(ctx) {} + + struct New_t { + typedef ProgressiveUpdateData Owner; + typedef ProgressiveUpdateData::LocalRef ReturnType; + typedef ProgressiveUpdateData::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "<init>"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto New() -> ProgressiveUpdateData::LocalRef; + + struct SetViewport_t { + typedef ProgressiveUpdateData Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "setViewport"; + static constexpr char signature[] = + "(Lorg/mozilla/gecko/gfx/ImmutableViewportMetrics;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto SetViewport(mozilla::jni::Object::Param) const -> void; + + struct Abort_t { + typedef ProgressiveUpdateData Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "abort"; + static constexpr char signature[] = + "Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Abort() const -> bool; + + auto Abort(bool) const -> void; + + struct Scale_t { + typedef ProgressiveUpdateData Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "scale"; + static constexpr char signature[] = + "F"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Scale() const -> float; + + auto Scale(float) const -> void; + + struct X_t { + typedef ProgressiveUpdateData Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "x"; + static constexpr char signature[] = + "F"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto X() const -> float; + + auto X(float) const -> void; + + struct Y_t { + typedef ProgressiveUpdateData Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "y"; + static constexpr char signature[] = + "F"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Y() const -> float; + + auto Y(float) const -> void; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + +}; + +class StackScroller : public mozilla::jni::ObjectBase<StackScroller> +{ +public: + static const char name[]; + + explicit StackScroller(const Context& ctx) : ObjectBase<StackScroller>(ctx) {} + + struct New_t { + typedef StackScroller Owner; + typedef StackScroller::LocalRef ReturnType; + typedef StackScroller::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "<init>"; + static constexpr char signature[] = + "(Landroid/content/Context;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto New(mozilla::jni::Object::Param, StackScroller::LocalRef*) -> nsresult; + + struct AbortAnimation_t { + typedef StackScroller Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "abortAnimation"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto AbortAnimation() const -> nsresult; + + struct ComputeScrollOffset_t { + typedef StackScroller Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + int64_t> Args; + static constexpr char name[] = "computeScrollOffset"; + static constexpr char signature[] = + "(J)Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto ComputeScrollOffset(int64_t, bool*) const -> nsresult; + + struct Fling_t { + typedef StackScroller Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + int32_t, + int32_t, + int32_t, + int32_t, + int32_t, + int32_t, + int32_t, + int32_t, + int64_t> Args; + static constexpr char name[] = "fling"; + static constexpr char signature[] = + "(IIIIIIIIIIJ)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Fling(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int64_t) const -> nsresult; + + struct ForceFinished_t { + typedef StackScroller Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + bool> Args; + static constexpr char name[] = "forceFinished"; + static constexpr char signature[] = + "(Z)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto ForceFinished(bool) const -> nsresult; + + struct GetCurrSpeedX_t { + typedef StackScroller Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getCurrSpeedX"; + static constexpr char signature[] = + "()F"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto GetCurrSpeedX(float*) const -> nsresult; + + struct GetCurrSpeedY_t { + typedef StackScroller Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getCurrSpeedY"; + static constexpr char signature[] = + "()F"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto GetCurrSpeedY(float*) const -> nsresult; + + struct GetCurrX_t { + typedef StackScroller Owner; + typedef int32_t ReturnType; + typedef int32_t SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getCurrX"; + static constexpr char signature[] = + "()I"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto GetCurrX(int32_t*) const -> nsresult; + + struct GetCurrY_t { + typedef StackScroller Owner; + typedef int32_t ReturnType; + typedef int32_t SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getCurrY"; + static constexpr char signature[] = + "()I"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto GetCurrY(int32_t*) const -> nsresult; + + struct GetFinalX_t { + typedef StackScroller Owner; + typedef int32_t ReturnType; + typedef int32_t SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getFinalX"; + static constexpr char signature[] = + "()I"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto GetFinalX(int32_t*) const -> nsresult; + + struct GetFinalY_t { + typedef StackScroller Owner; + typedef int32_t ReturnType; + typedef int32_t SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getFinalY"; + static constexpr char signature[] = + "()I"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto GetFinalY(int32_t*) const -> nsresult; + + struct InitContants_t { + typedef StackScroller Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "initContants"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto InitContants() -> nsresult; + + struct IsFinished_t { + typedef StackScroller Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "isFinished"; + static constexpr char signature[] = + "()Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto IsFinished(bool*) const -> nsresult; + + struct SetFinalX_t { + typedef StackScroller Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t> Args; + static constexpr char name[] = "setFinalX"; + static constexpr char signature[] = + "(I)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto SetFinalX(int32_t) const -> nsresult; + + struct SpringBack_t { + typedef StackScroller Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + int32_t, + int32_t, + int32_t, + int32_t, + int64_t> Args; + static constexpr char name[] = "springBack"; + static constexpr char signature[] = + "(IIIIIIJ)Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto SpringBack(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int64_t, bool*) const -> nsresult; + + struct StartScroll_t { + typedef StackScroller Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + int32_t, + int32_t, + int64_t, + int32_t> Args; + static constexpr char name[] = "startScroll"; + static constexpr char signature[] = + "(IIIIJI)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto StartScroll(int32_t, int32_t, int32_t, int32_t, int64_t, int32_t) const -> nsresult; + + struct ViscousFluid_t { + typedef StackScroller Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args< + float> Args; + static constexpr char name[] = "viscousFluid"; + static constexpr char signature[] = + "(F)F"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto ViscousFluid(float, float*) -> nsresult; + + static const int32_t FLING_MODE = 1; + + static const int32_t SCROLL_MODE = 0; + + struct MFlywheel_t { + typedef StackScroller Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "mFlywheel"; + static constexpr char signature[] = + "Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto MFlywheel(bool*) const -> nsresult; + + struct MMode_t { + typedef StackScroller Owner; + typedef int32_t ReturnType; + typedef int32_t SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "mMode"; + static constexpr char signature[] = + "I"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto MMode(int32_t*) const -> nsresult; + + auto MMode(int32_t) const -> nsresult; + + struct MScrollerX_t { + typedef StackScroller Owner; + typedef mozilla::jni::Object::LocalRef ReturnType; + typedef mozilla::jni::Object::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "mScrollerX"; + static constexpr char signature[] = + "Lorg/mozilla/gecko/gfx/StackScroller$SplineStackScroller;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto MScrollerX(mozilla::jni::Object::LocalRef*) const -> nsresult; + + struct MScrollerY_t { + typedef StackScroller Owner; + typedef mozilla::jni::Object::LocalRef ReturnType; + typedef mozilla::jni::Object::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "mScrollerY"; + static constexpr char signature[] = + "Lorg/mozilla/gecko/gfx/StackScroller$SplineStackScroller;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto MScrollerY(mozilla::jni::Object::LocalRef*) const -> nsresult; + + struct SViscousFluidNormalize_t { + typedef StackScroller Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "sViscousFluidNormalize"; + static constexpr char signature[] = + "F"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto SViscousFluidNormalize(float*) -> nsresult; + + static auto SViscousFluidNormalize(float) -> nsresult; + + struct SViscousFluidScale_t { + typedef StackScroller Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "sViscousFluidScale"; + static constexpr char signature[] = + "F"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::NSRESULT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto SViscousFluidScale(float*) -> nsresult; + + static auto SViscousFluidScale(float) -> nsresult; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + +}; + +class ViewTransform : public mozilla::jni::ObjectBase<ViewTransform> +{ +public: + static const char name[]; + + explicit ViewTransform(const Context& ctx) : ObjectBase<ViewTransform>(ctx) {} + + struct New_t { + typedef ViewTransform Owner; + typedef ViewTransform::LocalRef ReturnType; + typedef ViewTransform::Param SetterType; + typedef mozilla::jni::Args< + float, + float, + float> Args; + static constexpr char name[] = "<init>"; + static constexpr char signature[] = + "(FFF)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto New(float, float, float) -> ViewTransform::LocalRef; + + struct FixedLayerMarginBottom_t { + typedef ViewTransform Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "fixedLayerMarginBottom"; + static constexpr char signature[] = + "F"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto FixedLayerMarginBottom() const -> float; + + auto FixedLayerMarginBottom(float) const -> void; + + struct FixedLayerMarginLeft_t { + typedef ViewTransform Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "fixedLayerMarginLeft"; + static constexpr char signature[] = + "F"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto FixedLayerMarginLeft() const -> float; + + auto FixedLayerMarginLeft(float) const -> void; + + struct FixedLayerMarginRight_t { + typedef ViewTransform Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "fixedLayerMarginRight"; + static constexpr char signature[] = + "F"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto FixedLayerMarginRight() const -> float; + + auto FixedLayerMarginRight(float) const -> void; + + struct FixedLayerMarginTop_t { + typedef ViewTransform Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "fixedLayerMarginTop"; + static constexpr char signature[] = + "F"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto FixedLayerMarginTop() const -> float; + + auto FixedLayerMarginTop(float) const -> void; + + struct Height_t { + typedef ViewTransform Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "height"; + static constexpr char signature[] = + "F"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Height() const -> float; + + auto Height(float) const -> void; + + struct Scale_t { + typedef ViewTransform Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "scale"; + static constexpr char signature[] = + "F"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Scale() const -> float; + + auto Scale(float) const -> void; + + struct Width_t { + typedef ViewTransform Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "width"; + static constexpr char signature[] = + "F"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Width() const -> float; + + auto Width(float) const -> void; + + struct X_t { + typedef ViewTransform Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "x"; + static constexpr char signature[] = + "F"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto X() const -> float; + + auto X(float) const -> void; + + struct Y_t { + typedef ViewTransform Owner; + typedef float ReturnType; + typedef float SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "y"; + static constexpr char signature[] = + "F"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Y() const -> float; + + auto Y(float) const -> void; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + +}; + +class Clipboard : public mozilla::jni::ObjectBase<Clipboard> +{ +public: + static const char name[]; + + explicit Clipboard(const Context& ctx) : ObjectBase<Clipboard>(ctx) {} + + struct ClearText_t { + typedef Clipboard Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "clearText"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto ClearText() -> void; + + struct GetText_t { + typedef Clipboard Owner; + typedef mozilla::jni::String::LocalRef ReturnType; + typedef mozilla::jni::String::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getText"; + static constexpr char signature[] = + "()Ljava/lang/String;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetText() -> mozilla::jni::String::LocalRef; + + struct HasText_t { + typedef Clipboard Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "hasText"; + static constexpr char signature[] = + "()Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto HasText() -> bool; + + struct SetText_t { + typedef Clipboard Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "setText"; + static constexpr char signature[] = + "(Ljava/lang/CharSequence;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto SetText(mozilla::jni::String::Param) -> void; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + +}; + +class HardwareCodecCapabilityUtils : public mozilla::jni::ObjectBase<HardwareCodecCapabilityUtils> +{ +public: + static const char name[]; + + explicit HardwareCodecCapabilityUtils(const Context& ctx) : ObjectBase<HardwareCodecCapabilityUtils>(ctx) {} + + struct HasHWVP9_t { + typedef HardwareCodecCapabilityUtils Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "HasHWVP9"; + static constexpr char signature[] = + "()Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto HasHWVP9() -> bool; + + struct FindDecoderCodecInfoForMimeType_t { + typedef HardwareCodecCapabilityUtils Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "findDecoderCodecInfoForMimeType"; + static constexpr char signature[] = + "(Ljava/lang/String;)Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto FindDecoderCodecInfoForMimeType(mozilla::jni::String::Param) -> bool; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + +}; + +class NativeJSContainer : public mozilla::jni::ObjectBase<NativeJSContainer> +{ +public: + static const char name[]; + + explicit NativeJSContainer(const Context& ctx) : ObjectBase<NativeJSContainer>(ctx) {} + + struct New_t { + typedef NativeJSContainer Owner; + typedef NativeJSContainer::LocalRef ReturnType; + typedef NativeJSContainer::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "<init>"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto New() -> NativeJSContainer::LocalRef; + + struct Clone2_t { + typedef NativeJSContainer Owner; + typedef NativeJSContainer::LocalRef ReturnType; + typedef NativeJSContainer::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "clone"; + static constexpr char signature[] = + "()Lorg/mozilla/gecko/util/NativeJSContainer;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct DisposeNative_t { + typedef NativeJSContainer Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "disposeNative"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + + template<class Impl> class Natives; +}; + +class NativeJSObject : public mozilla::jni::ObjectBase<NativeJSObject> +{ +public: + static const char name[]; + + explicit NativeJSObject(const Context& ctx) : ObjectBase<NativeJSObject>(ctx) {} + + struct New_t { + typedef NativeJSObject Owner; + typedef NativeJSObject::LocalRef ReturnType; + typedef NativeJSObject::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "<init>"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto New() -> NativeJSObject::LocalRef; + + struct DisposeNative_t { + typedef NativeJSObject Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "disposeNative"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto DisposeNative() const -> void; + + struct GetBoolean_t { + typedef NativeJSObject Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getBoolean"; + static constexpr char signature[] = + "(Ljava/lang/String;)Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct GetBooleanArray_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::BooleanArray::LocalRef ReturnType; + typedef mozilla::jni::BooleanArray::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getBooleanArray"; + static constexpr char signature[] = + "(Ljava/lang/String;)[Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct GetBundle_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::Object::LocalRef ReturnType; + typedef mozilla::jni::Object::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getBundle"; + static constexpr char signature[] = + "(Ljava/lang/String;)Landroid/os/Bundle;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct GetBundleArray_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::ObjectArray::LocalRef ReturnType; + typedef mozilla::jni::ObjectArray::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getBundleArray"; + static constexpr char signature[] = + "(Ljava/lang/String;)[Landroid/os/Bundle;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct GetDouble_t { + typedef NativeJSObject Owner; + typedef double ReturnType; + typedef double SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getDouble"; + static constexpr char signature[] = + "(Ljava/lang/String;)D"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct GetDoubleArray_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::DoubleArray::LocalRef ReturnType; + typedef mozilla::jni::DoubleArray::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getDoubleArray"; + static constexpr char signature[] = + "(Ljava/lang/String;)[D"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct GetInt_t { + typedef NativeJSObject Owner; + typedef int32_t ReturnType; + typedef int32_t SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getInt"; + static constexpr char signature[] = + "(Ljava/lang/String;)I"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct GetIntArray_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::IntArray::LocalRef ReturnType; + typedef mozilla::jni::IntArray::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getIntArray"; + static constexpr char signature[] = + "(Ljava/lang/String;)[I"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct GetObject_t { + typedef NativeJSObject Owner; + typedef NativeJSObject::LocalRef ReturnType; + typedef NativeJSObject::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getObject"; + static constexpr char signature[] = + "(Ljava/lang/String;)Lorg/mozilla/gecko/util/NativeJSObject;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct GetObjectArray_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::ObjectArray::LocalRef ReturnType; + typedef mozilla::jni::ObjectArray::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getObjectArray"; + static constexpr char signature[] = + "(Ljava/lang/String;)[Lorg/mozilla/gecko/util/NativeJSObject;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct GetString_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::String::LocalRef ReturnType; + typedef mozilla::jni::String::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getString"; + static constexpr char signature[] = + "(Ljava/lang/String;)Ljava/lang/String;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct GetStringArray_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::ObjectArray::LocalRef ReturnType; + typedef mozilla::jni::ObjectArray::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "getStringArray"; + static constexpr char signature[] = + "(Ljava/lang/String;)[Ljava/lang/String;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct Has_t { + typedef NativeJSObject Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "has"; + static constexpr char signature[] = + "(Ljava/lang/String;)Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OptBoolean_t { + typedef NativeJSObject Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + bool> Args; + static constexpr char name[] = "optBoolean"; + static constexpr char signature[] = + "(Ljava/lang/String;Z)Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OptBooleanArray_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::BooleanArray::LocalRef ReturnType; + typedef mozilla::jni::BooleanArray::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::BooleanArray::Param> Args; + static constexpr char name[] = "optBooleanArray"; + static constexpr char signature[] = + "(Ljava/lang/String;[Z)[Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OptBundle_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::Object::LocalRef ReturnType; + typedef mozilla::jni::Object::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "optBundle"; + static constexpr char signature[] = + "(Ljava/lang/String;Landroid/os/Bundle;)Landroid/os/Bundle;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OptBundleArray_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::ObjectArray::LocalRef ReturnType; + typedef mozilla::jni::ObjectArray::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::ObjectArray::Param> Args; + static constexpr char name[] = "optBundleArray"; + static constexpr char signature[] = + "(Ljava/lang/String;[Landroid/os/Bundle;)[Landroid/os/Bundle;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OptDouble_t { + typedef NativeJSObject Owner; + typedef double ReturnType; + typedef double SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + double> Args; + static constexpr char name[] = "optDouble"; + static constexpr char signature[] = + "(Ljava/lang/String;D)D"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OptDoubleArray_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::DoubleArray::LocalRef ReturnType; + typedef mozilla::jni::DoubleArray::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::DoubleArray::Param> Args; + static constexpr char name[] = "optDoubleArray"; + static constexpr char signature[] = + "(Ljava/lang/String;[D)[D"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OptInt_t { + typedef NativeJSObject Owner; + typedef int32_t ReturnType; + typedef int32_t SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + int32_t> Args; + static constexpr char name[] = "optInt"; + static constexpr char signature[] = + "(Ljava/lang/String;I)I"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OptIntArray_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::IntArray::LocalRef ReturnType; + typedef mozilla::jni::IntArray::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::IntArray::Param> Args; + static constexpr char name[] = "optIntArray"; + static constexpr char signature[] = + "(Ljava/lang/String;[I)[I"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OptObject_t { + typedef NativeJSObject Owner; + typedef NativeJSObject::LocalRef ReturnType; + typedef NativeJSObject::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + NativeJSObject::Param> Args; + static constexpr char name[] = "optObject"; + static constexpr char signature[] = + "(Ljava/lang/String;Lorg/mozilla/gecko/util/NativeJSObject;)Lorg/mozilla/gecko/util/NativeJSObject;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OptObjectArray_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::ObjectArray::LocalRef ReturnType; + typedef mozilla::jni::ObjectArray::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::ObjectArray::Param> Args; + static constexpr char name[] = "optObjectArray"; + static constexpr char signature[] = + "(Ljava/lang/String;[Lorg/mozilla/gecko/util/NativeJSObject;)[Lorg/mozilla/gecko/util/NativeJSObject;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OptString_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::String::LocalRef ReturnType; + typedef mozilla::jni::String::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "optString"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OptStringArray_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::ObjectArray::LocalRef ReturnType; + typedef mozilla::jni::ObjectArray::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::ObjectArray::Param> Args; + static constexpr char name[] = "optStringArray"; + static constexpr char signature[] = + "(Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct ToBundle_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::Object::LocalRef ReturnType; + typedef mozilla::jni::Object::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "toBundle"; + static constexpr char signature[] = + "()Landroid/os/Bundle;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct ToString_t { + typedef NativeJSObject Owner; + typedef mozilla::jni::String::LocalRef ReturnType; + typedef mozilla::jni::String::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "toString"; + static constexpr char signature[] = + "()Ljava/lang/String;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + + template<class Impl> class Natives; +}; + +} /* java */ +} /* mozilla */ +#endif // GeneratedJNIWrappers_h diff --git a/widget/android/GfxInfo.cpp b/widget/android/GfxInfo.cpp new file mode 100644 index 000000000..af63184a7 --- /dev/null +++ b/widget/android/GfxInfo.cpp @@ -0,0 +1,621 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "GfxInfo.h" +#include "GLContext.h" +#include "GLContextProvider.h" +#include "nsUnicharUtils.h" +#include "prenv.h" +#include "prprf.h" +#include "nsHashKeys.h" +#include "nsVersionComparator.h" +#include "AndroidBridge.h" +#include "nsIWindowWatcher.h" +#include "nsServiceManagerUtils.h" + +#if defined(MOZ_CRASHREPORTER) +#include "nsExceptionHandler.h" +#include "nsICrashReporter.h" +#define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1" +#endif + +namespace mozilla { +namespace widget { + +class GfxInfo::GLStrings +{ + nsCString mVendor; + nsCString mRenderer; + nsCString mVersion; + bool mReady; + +public: + GLStrings() + : mReady(false) + {} + + const nsCString& Vendor() { + EnsureInitialized(); + return mVendor; + } + + // This spoofed value wins, even if the environment variable + // MOZ_GFX_SPOOF_GL_VENDOR was set. + void SpoofVendor(const nsCString& s) { + mVendor = s; + } + + const nsCString& Renderer() { + EnsureInitialized(); + return mRenderer; + } + + // This spoofed value wins, even if the environment variable + // MOZ_GFX_SPOOF_GL_RENDERER was set. + void SpoofRenderer(const nsCString& s) { + mRenderer = s; + } + + const nsCString& Version() { + EnsureInitialized(); + return mVersion; + } + + // This spoofed value wins, even if the environment variable + // MOZ_GFX_SPOOF_GL_VERSION was set. + void SpoofVersion(const nsCString& s) { + mVersion = s; + } + + void EnsureInitialized() { + if (mReady) { + return; + } + + RefPtr<gl::GLContext> gl; + nsCString discardFailureId; + gl = gl::GLContextProvider::CreateHeadless(gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE, + &discardFailureId); + + if (!gl) { + // Setting mReady to true here means that we won't retry. Everything will + // remain blacklisted forever. Ideally, we would like to update that once + // any GLContext is successfully created, like the compositor's GLContext. + mReady = true; + return; + } + + gl->MakeCurrent(); + + if (mVendor.IsEmpty()) { + const char *spoofedVendor = PR_GetEnv("MOZ_GFX_SPOOF_GL_VENDOR"); + if (spoofedVendor) { + mVendor.Assign(spoofedVendor); + } else { + mVendor.Assign((const char*)gl->fGetString(LOCAL_GL_VENDOR)); + } + } + + if (mRenderer.IsEmpty()) { + const char *spoofedRenderer = PR_GetEnv("MOZ_GFX_SPOOF_GL_RENDERER"); + if (spoofedRenderer) { + mRenderer.Assign(spoofedRenderer); + } else { + mRenderer.Assign((const char*)gl->fGetString(LOCAL_GL_RENDERER)); + } + } + + if (mVersion.IsEmpty()) { + const char *spoofedVersion = PR_GetEnv("MOZ_GFX_SPOOF_GL_VERSION"); + if (spoofedVersion) { + mVersion.Assign(spoofedVersion); + } else { + mVersion.Assign((const char*)gl->fGetString(LOCAL_GL_VERSION)); + } + } + + mReady = true; + } +}; + +#ifdef DEBUG +NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug) +#endif + +GfxInfo::GfxInfo() + : mInitialized(false) + , mGLStrings(new GLStrings) + , mOSVersionInteger(0) + , mSDKVersion(0) +{ +} + +GfxInfo::~GfxInfo() +{ +} + +/* GetD2DEnabled and GetDwriteEnabled shouldn't be called until after gfxPlatform initialization + * has occurred because they depend on it for information. (See bug 591561) */ +nsresult +GfxInfo::GetD2DEnabled(bool *aEnabled) +{ + return NS_ERROR_FAILURE; +} + +nsresult +GfxInfo::GetDWriteEnabled(bool *aEnabled) +{ + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +GfxInfo::GetDWriteVersion(nsAString & aDwriteVersion) +{ + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +GfxInfo::GetCleartypeParameters(nsAString & aCleartypeParams) +{ + return NS_ERROR_FAILURE; +} + +void +GfxInfo::EnsureInitialized() +{ + if (mInitialized) + return; + + if (!mozilla::AndroidBridge::Bridge()) { + gfxWarning() << "AndroidBridge missing during initialization"; + return; + } + + if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "MODEL", mModel)) { + mAdapterDescription.AppendPrintf("Model: %s", NS_LossyConvertUTF16toASCII(mModel).get()); + } + + if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "PRODUCT", mProduct)) { + mAdapterDescription.AppendPrintf(", Product: %s", NS_LossyConvertUTF16toASCII(mProduct).get()); + } + + if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "MANUFACTURER", mManufacturer)) { + mAdapterDescription.AppendPrintf(", Manufacturer: %s", NS_LossyConvertUTF16toASCII(mManufacturer).get()); + } + + if (mozilla::AndroidBridge::Bridge()->GetStaticIntField("android/os/Build$VERSION", "SDK_INT", &mSDKVersion)) { + // the HARDWARE field isn't available on Android SDK < 8, but we require 9+ anyway. + MOZ_ASSERT(mSDKVersion >= 8); + if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "HARDWARE", mHardware)) { + mAdapterDescription.AppendPrintf(", Hardware: %s", NS_LossyConvertUTF16toASCII(mHardware).get()); + } + } else { + mSDKVersion = 0; + } + + nsString release; + mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build$VERSION", "RELEASE", release); + mOSVersion = NS_LossyConvertUTF16toASCII(release); + + mOSVersionInteger = 0; + char a[5], b[5], c[5], d[5]; + SplitDriverVersion(mOSVersion.get(), a, b, c, d); + uint8_t na = atoi(a); + uint8_t nb = atoi(b); + uint8_t nc = atoi(c); + uint8_t nd = atoi(d); + + mOSVersionInteger = (uint32_t(na) << 24) | + (uint32_t(nb) << 16) | + (uint32_t(nc) << 8) | + uint32_t(nd); + + mAdapterDescription.AppendPrintf(", OpenGL: %s -- %s -- %s", + mGLStrings->Vendor().get(), + mGLStrings->Renderer().get(), + mGLStrings->Version().get()); + + AddCrashReportAnnotations(); + + mInitialized = true; +} + +NS_IMETHODIMP +GfxInfo::GetAdapterDescription(nsAString & aAdapterDescription) +{ + EnsureInitialized(); + aAdapterDescription = NS_ConvertASCIItoUTF16(mAdapterDescription); + return NS_OK; +} + +NS_IMETHODIMP +GfxInfo::GetAdapterDescription2(nsAString & aAdapterDescription) +{ + EnsureInitialized(); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +GfxInfo::GetAdapterRAM(nsAString & aAdapterRAM) +{ + EnsureInitialized(); + aAdapterRAM.Truncate(); + return NS_OK; +} + +NS_IMETHODIMP +GfxInfo::GetAdapterRAM2(nsAString & aAdapterRAM) +{ + EnsureInitialized(); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +GfxInfo::GetAdapterDriver(nsAString & aAdapterDriver) +{ + EnsureInitialized(); + aAdapterDriver.Truncate(); + return NS_OK; +} + +NS_IMETHODIMP +GfxInfo::GetAdapterDriver2(nsAString & aAdapterDriver) +{ + EnsureInitialized(); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +GfxInfo::GetAdapterDriverVersion(nsAString & aAdapterDriverVersion) +{ + EnsureInitialized(); + aAdapterDriverVersion = NS_ConvertASCIItoUTF16(mGLStrings->Version()); + return NS_OK; +} + +NS_IMETHODIMP +GfxInfo::GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion) +{ + EnsureInitialized(); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +GfxInfo::GetAdapterDriverDate(nsAString & aAdapterDriverDate) +{ + EnsureInitialized(); + aAdapterDriverDate.Truncate(); + return NS_OK; +} + +NS_IMETHODIMP +GfxInfo::GetAdapterDriverDate2(nsAString & aAdapterDriverDate) +{ + EnsureInitialized(); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +GfxInfo::GetAdapterVendorID(nsAString & aAdapterVendorID) +{ + EnsureInitialized(); + aAdapterVendorID = NS_ConvertASCIItoUTF16(mGLStrings->Vendor()); + return NS_OK; +} + +NS_IMETHODIMP +GfxInfo::GetAdapterVendorID2(nsAString & aAdapterVendorID) +{ + EnsureInitialized(); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +GfxInfo::GetAdapterDeviceID(nsAString & aAdapterDeviceID) +{ + EnsureInitialized(); + aAdapterDeviceID = NS_ConvertASCIItoUTF16(mGLStrings->Renderer()); + return NS_OK; +} + +NS_IMETHODIMP +GfxInfo::GetAdapterDeviceID2(nsAString & aAdapterDeviceID) +{ + EnsureInitialized(); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +GfxInfo::GetAdapterSubsysID(nsAString & aAdapterSubsysID) +{ + EnsureInitialized(); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +GfxInfo::GetAdapterSubsysID2(nsAString & aAdapterSubsysID) +{ + EnsureInitialized(); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active) +{ + EnsureInitialized(); + return NS_ERROR_FAILURE; +} + +void +GfxInfo::AddCrashReportAnnotations() +{ +#if defined(MOZ_CRASHREPORTER) + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"), + mGLStrings->Vendor()); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"), + mGLStrings->Renderer()); + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDriverVersion"), + mGLStrings->Version()); + + /* Add an App Note for now so that we get the data immediately. These + * can go away after we store the above in the socorro db */ + nsAutoCString note; + note.AppendPrintf("AdapterDescription: '%s'\n", mAdapterDescription.get()); + + CrashReporter::AppendAppNotesToCrashReport(note); +#endif +} + +const nsTArray<GfxDriverInfo>& +GfxInfo::GetGfxDriverInfo() +{ + if (mDriverInfo->IsEmpty()) { + APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Android, + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAll), GfxDriverInfo::allDevices, + nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_STATUS_OK, + DRIVER_COMPARISON_IGNORED, GfxDriverInfo::allDriverVersions, + "FEATURE_OK_FORCE_OPENGL" ); + } + + return *mDriverInfo; +} + +nsresult +GfxInfo::GetFeatureStatusImpl(int32_t aFeature, + int32_t *aStatus, + nsAString &aSuggestedDriverVersion, + const nsTArray<GfxDriverInfo>& aDriverInfo, + nsACString &aFailureId, + OperatingSystem* aOS /* = nullptr */) +{ + NS_ENSURE_ARG_POINTER(aStatus); + aSuggestedDriverVersion.SetIsVoid(true); + *aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN; + OperatingSystem os = mOS; + if (aOS) + *aOS = os; + + // OpenGL layers are never blacklisted on Android. + // This early return is so we avoid potentially slow + // GLStrings initialization on startup when we initialize GL layers. + if (aFeature == nsIGfxInfo::FEATURE_OPENGL_LAYERS) { + *aStatus = nsIGfxInfo::FEATURE_STATUS_OK; + return NS_OK; + } + + EnsureInitialized(); + + if (mGLStrings->Vendor().IsEmpty() || mGLStrings->Renderer().IsEmpty()) { + *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; + return NS_OK; + } + + // Don't evaluate special cases when evaluating the downloaded blocklist. + if (aDriverInfo.IsEmpty()) { + if (aFeature == nsIGfxInfo::FEATURE_CANVAS2D_ACCELERATION) { + if (mSDKVersion < 11) { + // It's slower than software due to not having a compositing fast path + *aStatus = nsIGfxInfo::FEATURE_BLOCKED_OS_VERSION; + aFailureId = "FEATURE_FAILURE_CANVAS_2D_SDK"; + } else if (mGLStrings->Renderer().Find("Vivante GC1000") != -1) { + // Blocklist Vivante GC1000. See bug 1248183. + *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; + aFailureId = "FEATURE_FAILED_CANVAS_2D_HW"; + } else { + *aStatus = nsIGfxInfo::FEATURE_STATUS_OK; + } + return NS_OK; + } + + if (aFeature == FEATURE_WEBGL_OPENGL) { + if (mGLStrings->Renderer().Find("Adreno 200") != -1 || + mGLStrings->Renderer().Find("Adreno 205") != -1) + { + *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; + aFailureId = "FEATURE_FAILURE_ADRENO_20x"; + return NS_OK; + } + + if (mHardware.EqualsLiteral("ville")) { + *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; + aFailureId = "FEATURE_FAILURE_VILLE"; + return NS_OK; + } + } + + if (aFeature == FEATURE_STAGEFRIGHT) { + NS_LossyConvertUTF16toASCII cManufacturer(mManufacturer); + NS_LossyConvertUTF16toASCII cModel(mModel); + NS_LossyConvertUTF16toASCII cHardware(mHardware); + + if (cHardware.EqualsLiteral("antares") || + cHardware.EqualsLiteral("harmony") || + cHardware.EqualsLiteral("picasso") || + cHardware.EqualsLiteral("picasso_e") || + cHardware.EqualsLiteral("ventana") || + cHardware.EqualsLiteral("rk30board")) + { + *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; + aFailureId = "FEATURE_FAILURE_STAGE_HW"; + return NS_OK; + } + + if (CompareVersions(mOSVersion.get(), "4.1.0") < 0) + { + // Whitelist: + // All Samsung ICS devices, except for: + // Samsung SGH-I717 (Bug 845729) + // Samsung SGH-I727 (Bug 845729) + // Samsung SGH-I757 (Bug 845729) + // All Galaxy nexus ICS devices + // Sony Xperia Ion (LT28) ICS devices + bool isWhitelisted = + cModel.Equals("LT28h", nsCaseInsensitiveCStringComparator()) || + cManufacturer.Equals("samsung", nsCaseInsensitiveCStringComparator()) || + cModel.Equals("galaxy nexus", nsCaseInsensitiveCStringComparator()); // some Galaxy Nexus have manufacturer=amazon + + if (cModel.Find("SGH-I717", true) != -1 || + cModel.Find("SGH-I727", true) != -1 || + cModel.Find("SGH-I757", true) != -1) + { + isWhitelisted = false; + } + + if (!isWhitelisted) { + *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; + aFailureId = "FEATURE_FAILURE_4_1_HW"; + return NS_OK; + } + } + else if (CompareVersions(mOSVersion.get(), "4.2.0") < 0) + { + // Whitelist: + // All JB phones except for those in blocklist below + // Blocklist: + // Samsung devices from bug 812881 and 853522. + // Motorola XT890 from bug 882342. + bool isBlocklisted = + cModel.Find("GT-P3100", true) != -1 || + cModel.Find("GT-P3110", true) != -1 || + cModel.Find("GT-P3113", true) != -1 || + cModel.Find("GT-P5100", true) != -1 || + cModel.Find("GT-P5110", true) != -1 || + cModel.Find("GT-P5113", true) != -1 || + cModel.Find("XT890", true) != -1; + + if (isBlocklisted) { + *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; + aFailureId = "FEATURE_FAILURE_4_2_HW"; + return NS_OK; + } + } + else if (CompareVersions(mOSVersion.get(), "4.3.0") < 0) + { + // Blocklist all Sony devices + if (cManufacturer.Find("Sony", true) != -1) { + *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; + aFailureId = "FEATURE_FAILURE_4_3_SONY"; + return NS_OK; + } + } + } + + if (aFeature == FEATURE_WEBRTC_HW_ACCELERATION_ENCODE) { + if (mozilla::AndroidBridge::Bridge()) { + *aStatus = mozilla::AndroidBridge::Bridge()->GetHWEncoderCapability() ? nsIGfxInfo::FEATURE_STATUS_OK : nsIGfxInfo::FEATURE_BLOCKED_DEVICE; + aFailureId = "FEATURE_FAILURE_WEBRTC_ENCODE"; + return NS_OK; + } + } + if (aFeature == FEATURE_WEBRTC_HW_ACCELERATION_DECODE) { + if (mozilla::AndroidBridge::Bridge()) { + *aStatus = mozilla::AndroidBridge::Bridge()->GetHWDecoderCapability() ? nsIGfxInfo::FEATURE_STATUS_OK : nsIGfxInfo::FEATURE_BLOCKED_DEVICE; + aFailureId = "FEATURE_FAILURE_WEBRTC_DECODE"; + return NS_OK; + } + } + + if (aFeature == FEATURE_VP8_HW_DECODE || aFeature == FEATURE_VP9_HW_DECODE) { + NS_LossyConvertUTF16toASCII model(mModel); + bool isBlocked = + // GIFV crash, see bug 1232911. + model.Equals("GT-N8013", nsCaseInsensitiveCStringComparator()); + + if (isBlocked) { + *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; + aFailureId = "FEATURE_FAILURE_VPx"; + } else { + *aStatus = nsIGfxInfo::FEATURE_STATUS_OK; + } + return NS_OK; + } + } + + return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, aFailureId, &os); +} + +#ifdef DEBUG + +// Implement nsIGfxInfoDebug + +NS_IMETHODIMP GfxInfo::SpoofVendorID(const nsAString & aVendorID) +{ + mGLStrings->SpoofVendor(NS_LossyConvertUTF16toASCII(aVendorID)); + return NS_OK; +} + +NS_IMETHODIMP GfxInfo::SpoofDeviceID(const nsAString & aDeviceID) +{ + mGLStrings->SpoofRenderer(NS_LossyConvertUTF16toASCII(aDeviceID)); + return NS_OK; +} + +NS_IMETHODIMP GfxInfo::SpoofDriverVersion(const nsAString & aDriverVersion) +{ + mGLStrings->SpoofVersion(NS_LossyConvertUTF16toASCII(aDriverVersion)); + return NS_OK; +} + +NS_IMETHODIMP GfxInfo::SpoofOSVersion(uint32_t aVersion) +{ + EnsureInitialized(); + mOSVersion = aVersion; + return NS_OK; +} + +#endif + +nsString GfxInfo::Model() +{ + EnsureInitialized(); + return mModel; +} + +nsString GfxInfo::Hardware() +{ + EnsureInitialized(); + return mHardware; +} + +nsString GfxInfo::Product() +{ + EnsureInitialized(); + return mProduct; +} + +nsString GfxInfo::Manufacturer() +{ + EnsureInitialized(); + return mManufacturer; +} + +uint32_t GfxInfo::OperatingSystemVersion() +{ + EnsureInitialized(); + return mOSVersionInteger; +} + +} +} diff --git a/widget/android/GfxInfo.h b/widget/android/GfxInfo.h new file mode 100644 index 000000000..a3b06099b --- /dev/null +++ b/widget/android/GfxInfo.h @@ -0,0 +1,102 @@ +/* vim: se cin sw=2 ts=2 et : */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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_widget_GfxInfo_h__ +#define __mozilla_widget_GfxInfo_h__ + +#include "GfxInfoBase.h" +#include "GfxDriverInfo.h" + +#include "nsString.h" +#include "mozilla/UniquePtr.h" + +namespace mozilla { + +namespace widget { + +class GfxInfo : public GfxInfoBase +{ +private: + ~GfxInfo(); + +public: + GfxInfo(); + + // We only declare the subset of nsIGfxInfo that we actually implement. The + // rest is brought forward from GfxInfoBase. + NS_IMETHOD GetD2DEnabled(bool *aD2DEnabled) override; + NS_IMETHOD GetDWriteEnabled(bool *aDWriteEnabled) override; + NS_IMETHOD GetDWriteVersion(nsAString & aDwriteVersion) override; + NS_IMETHOD GetCleartypeParameters(nsAString & aCleartypeParams) override; + NS_IMETHOD GetAdapterDescription(nsAString & aAdapterDescription) override; + NS_IMETHOD GetAdapterDriver(nsAString & aAdapterDriver) override; + NS_IMETHOD GetAdapterVendorID(nsAString & aAdapterVendorID) override; + NS_IMETHOD GetAdapterDeviceID(nsAString & aAdapterDeviceID) override; + NS_IMETHOD GetAdapterSubsysID(nsAString & aAdapterSubsysID) override; + NS_IMETHOD GetAdapterRAM(nsAString & aAdapterRAM) override; + NS_IMETHOD GetAdapterDriverVersion(nsAString & aAdapterDriverVersion) override; + NS_IMETHOD GetAdapterDriverDate(nsAString & aAdapterDriverDate) override; + NS_IMETHOD GetAdapterDescription2(nsAString & aAdapterDescription) override; + NS_IMETHOD GetAdapterDriver2(nsAString & aAdapterDriver) override; + NS_IMETHOD GetAdapterVendorID2(nsAString & aAdapterVendorID) override; + NS_IMETHOD GetAdapterDeviceID2(nsAString & aAdapterDeviceID) override; + NS_IMETHOD GetAdapterSubsysID2(nsAString & aAdapterSubsysID) override; + NS_IMETHOD GetAdapterRAM2(nsAString & aAdapterRAM) override; + NS_IMETHOD GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion) override; + NS_IMETHOD GetAdapterDriverDate2(nsAString & aAdapterDriverDate) override; + NS_IMETHOD GetIsGPU2Active(bool *aIsGPU2Active) override; + using GfxInfoBase::GetFeatureStatus; + using GfxInfoBase::GetFeatureSuggestedDriverVersion; + using GfxInfoBase::GetWebGLParameter; + + void EnsureInitialized(); + + virtual nsString Model() override; + virtual nsString Hardware() override; + virtual nsString Product() override; + virtual nsString Manufacturer() override; + +#ifdef DEBUG + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIGFXINFODEBUG +#endif + + virtual uint32_t OperatingSystemVersion() override; + +protected: + + virtual nsresult GetFeatureStatusImpl(int32_t aFeature, + int32_t *aStatus, + nsAString & aSuggestedDriverVersion, + const nsTArray<GfxDriverInfo>& aDriverInfo, + nsACString &aFailureId, + OperatingSystem* aOS = nullptr) override; + virtual const nsTArray<GfxDriverInfo>& GetGfxDriverInfo() override; + +private: + + void AddCrashReportAnnotations(); + + bool mInitialized; + + class GLStrings; + UniquePtr<GLStrings> mGLStrings; + + nsCString mAdapterDescription; + + OperatingSystem mOS; + + nsString mModel, mHardware, mManufacturer, mProduct; + nsCString mOSVersion; + uint32_t mOSVersionInteger; + int32_t mSDKVersion; +}; + +} // namespace widget +} // namespace mozilla + +#endif /* __mozilla_widget_GfxInfo_h__ */ diff --git a/widget/android/NativeJSContainer.cpp b/widget/android/NativeJSContainer.cpp new file mode 100644 index 000000000..b8c434656 --- /dev/null +++ b/widget/android/NativeJSContainer.cpp @@ -0,0 +1,881 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 "NativeJSContainer.h" + +#include <jni.h> + +#include "Bundle.h" +#include "GeneratedJNINatives.h" +#include "MainThreadUtils.h" +#include "jsapi.h" +#include "nsJSUtils.h" + +#include <mozilla/Vector.h> +#include <mozilla/jni/Accessors.h> +#include <mozilla/jni/Refs.h> +#include <mozilla/jni/Utils.h> + +/** + * NativeJSContainer.cpp implements the native methods in both + * NativeJSContainer and NativeJSObject, using JSAPI to retrieve values from a + * JSObject and using JNI to return those values to Java code. + */ + +namespace mozilla { +namespace widget { + +namespace { + +bool CheckThread() +{ + if (!NS_IsMainThread()) { + jni::ThrowException("java/lang/IllegalThreadStateException", + "Not on Gecko thread"); + return false; + } + return true; +} + +template<class C, typename T> bool +CheckJNIArgument(const jni::Ref<C, T>& arg) +{ + if (!arg) { + jni::ThrowException("java/lang/IllegalArgumentException", + "Null argument"); + } + return !!arg; +} + +nsresult +CheckSDKCall(nsresult rv) +{ + if (NS_FAILED(rv)) { + jni::ThrowException("java/lang/UnsupportedOperationException", + "SDK JNI call failed"); + } + return rv; +} + +// Convert a JNI string to a char16_t string that JSAPI expects. +class JSJNIString final +{ + JNIEnv* const mEnv; + jni::String::Param mJNIString; + const char16_t* const mJSString; + +public: + JSJNIString(JNIEnv* env, jni::String::Param str) + : mEnv(env) + , mJNIString(str) + , mJSString(!str ? nullptr : reinterpret_cast<const char16_t*>( + mEnv->GetStringChars(str.Get(), nullptr))) + {} + + ~JSJNIString() { + if (mJNIString) { + mEnv->ReleaseStringChars(mJNIString.Get(), + reinterpret_cast<const jchar*>(mJSString)); + } + } + + operator const char16_t*() const { + return mJSString; + } + + size_t Length() const { + return static_cast<size_t>(mEnv->GetStringLength(mJNIString.Get())); + } +}; + +} // namepsace + +class NativeJSContainerImpl final + : public NativeJSObject::Natives<NativeJSContainerImpl> + , public NativeJSContainer::Natives<NativeJSContainerImpl> +{ + typedef NativeJSContainerImpl Self; + typedef NativeJSContainer::Natives<NativeJSContainerImpl> ContainerBase; + typedef NativeJSObject::Natives<NativeJSContainerImpl> ObjectBase; + + typedef JS::PersistentRooted<JSObject*> PersistentObject; + + JNIEnv* const mEnv; + // Context that the object is valid in + JSContext* const mJSContext; + // Root JS object + PersistentObject mJSObject; + // Children objects + Vector<NativeJSObject::GlobalRef, 0> mChildren; + + bool CheckObject() const + { + if (!mJSObject) { + jni::ThrowException("java/lang/NullPointerException", + "Null JSObject"); + } + return !!mJSObject; + } + + bool CheckJSCall(bool result) const + { + if (!result) { + JS_ClearPendingException(mJSContext); + jni::ThrowException("java/lang/UnsupportedOperationException", + "JSAPI call failed"); + } + return result; + } + + // Check that a JS Value contains a particular property type as indicaed by + // the property's InValue method (e.g. StringProperty::InValue). + bool CheckProperty(bool (Self::*InValue)(JS::HandleValue) const, + JS::HandleValue val) const + { + if (!(this->*InValue)(val)) { + // XXX this can happen when converting a double array inside a + // Bundle, because double arrays can be misidentified as an int + // array. The workaround is to add a dummy first element to the + // array that is a floating point value, i.e. [0.5, ...]. + jni::ThrowException( + "org/mozilla/gecko/util/NativeJSObject$InvalidPropertyException", + "Property type mismatch"); + return false; + } + return true; + } + + // Primitive properties + + template<bool (JS::Value::*IsType)() const> bool + PrimitiveInValue(JS::HandleValue val) const + { + return (static_cast<const JS::Value&>(val).*IsType)(); + } + + template<typename U, U (JS::Value::*ToType)() const> U + PrimitiveFromValue(JS::HandleValue val) const + { + return (static_cast<const JS::Value&>(val).*ToType)(); + } + + template<class Prop> typename Prop::NativeArray + PrimitiveNewArray(JS::HandleObject array, size_t length) const + { + typedef typename Prop::JNIType JNIType; + + // Fill up a temporary buffer for our array, then use + // JNIEnv::Set*ArrayRegion to fill out array in one go. + + UniquePtr<JNIType[]> buffer = MakeUnique<JNIType[]>(length); + for (size_t i = 0; i < length; i++) { + JS::RootedValue elem(mJSContext); + if (!CheckJSCall(JS_GetElement(mJSContext, array, i, &elem)) || + !CheckProperty(Prop::InValue, elem)) { + return nullptr; + } + buffer[i] = JNIType((this->*Prop::FromValue)(elem)); + } + auto jarray = Prop::NativeArray::Adopt( + mEnv, (mEnv->*Prop::NewJNIArray)(length)); + if (!jarray) { + return nullptr; + } + (mEnv->*Prop::SetJNIArrayRegion)( + jarray.Get(), 0, length, buffer.get()); + if (mEnv->ExceptionCheck()) { + return nullptr; + } + return jarray; + } + + template<typename U, typename UA, typename V, typename VA, + bool (JS::Value::*IsType)() const, + U (JS::Value::*ToType)() const, + VA (JNIEnv::*NewArray_)(jsize), + void (JNIEnv::*SetArrayRegion_)(VA, jsize, jsize, const V*)> + struct PrimitiveProperty + { + // C++ type for a primitive property (e.g. bool) + typedef U NativeType; + // C++ type for the fallback value used in opt* methods + typedef U NativeFallback; + // Type for an array of the primitive type (e.g. BooleanArray::LocalRef) + typedef typename UA::LocalRef NativeArray; + // Type for the fallback value used in opt*Array methods + typedef const typename UA::Ref ArrayFallback; + // JNI type (e.g. jboolean) + typedef V JNIType; + + // JNIEnv function to create a new JNI array of the primiive type + typedef decltype(NewArray_) NewJNIArray_t; + static constexpr NewJNIArray_t NewJNIArray = NewArray_; + + // JNIEnv function to fill a JNI array of the primiive type + typedef decltype(SetArrayRegion_) SetJNIArrayRegion_t; + static constexpr SetJNIArrayRegion_t SetJNIArrayRegion = SetArrayRegion_; + + // Function to determine if a JS Value contains the primitive type + typedef decltype(&Self::PrimitiveInValue<IsType>) InValue_t; + static constexpr InValue_t InValue = &Self::PrimitiveInValue<IsType>; + + // Function to convert a JS Value to the primitive type + typedef decltype(&Self::PrimitiveFromValue<U, ToType>) FromValue_t; + static constexpr FromValue_t FromValue + = &Self::PrimitiveFromValue<U, ToType>; + + // Function to convert a JS array to a JNI array + typedef decltype(&Self::PrimitiveNewArray<PrimitiveProperty>) NewArray_t; + static constexpr NewArray_t NewArray + = &Self::PrimitiveNewArray<PrimitiveProperty>; + }; + + // String properties + + bool StringInValue(JS::HandleValue val) const + { + return val.isString(); + } + + jni::String::LocalRef + StringFromValue(const JS::HandleString str) const + { + nsAutoJSString autoStr; + if (!CheckJSCall(autoStr.init(mJSContext, str))) { + return nullptr; + } + // StringParam can automatically convert a nsString to jstring. + return jni::StringParam(autoStr, mEnv); + } + + jni::String::LocalRef + StringFromValue(JS::HandleValue val) + { + const JS::RootedString str(mJSContext, val.toString()); + return StringFromValue(str); + } + + // Bundle properties + + sdk::Bundle::LocalRef + BundleFromValue(const JS::HandleObject obj) + { + JS::Rooted<JS::IdVector> ids(mJSContext, JS::IdVector(mJSContext)); + if (!CheckJSCall(JS_Enumerate(mJSContext, obj, &ids))) { + return nullptr; + } + + const size_t length = ids.length(); + sdk::Bundle::LocalRef newBundle(mEnv); + NS_ENSURE_SUCCESS(CheckSDKCall( + sdk::Bundle::New(length, &newBundle)), nullptr); + + // Iterate through each property of the JS object. For each property, + // determine its type from a list of supported types, and convert that + // proeprty to the supported type. + + for (size_t i = 0; i < ids.length(); i++) { + const JS::RootedId id(mJSContext, ids[i]); + JS::RootedValue idVal(mJSContext); + if (!CheckJSCall(JS_IdToValue(mJSContext, id, &idVal))) { + return nullptr; + } + + const JS::RootedString idStr(mJSContext, + JS::ToString(mJSContext, idVal)); + if (!CheckJSCall(!!idStr)) { + return nullptr; + } + + jni::String::LocalRef name = StringFromValue(idStr); + JS::RootedValue val(mJSContext); + if (!name || + !CheckJSCall(JS_GetPropertyById(mJSContext, obj, id, &val))) { + return nullptr; + } + +#define PUT_IN_BUNDLE_IF_TYPE_IS(TYPE) \ + if ((this->*TYPE##Property::InValue)(val)) { \ + auto jval = (this->*TYPE##Property::FromValue)(val); \ + if (mEnv->ExceptionCheck()) { \ + return nullptr; \ + } \ + NS_ENSURE_SUCCESS(CheckSDKCall( \ + newBundle->Put##TYPE(name, jval)), nullptr); \ + continue; \ + } \ + ((void) 0) // Accommodate trailing semicolon. + + // Scalar values are faster to check, so check them first. + PUT_IN_BUNDLE_IF_TYPE_IS(Boolean); + // Int can be casted to double, so check int first. + PUT_IN_BUNDLE_IF_TYPE_IS(Int); + PUT_IN_BUNDLE_IF_TYPE_IS(Double); + PUT_IN_BUNDLE_IF_TYPE_IS(String); + // There's no "putObject", so don't check ObjectProperty + + // Check for array types if scalar checks all failed. + // XXX empty arrays are treated as boolean arrays. Workaround is + // to always have a dummy element to create a non-empty array. + PUT_IN_BUNDLE_IF_TYPE_IS(BooleanArray); + // XXX because we only check the first element of an array, + // a double array can potentially be seen as an int array. + // When that happens, the Bundle conversion will fail. + PUT_IN_BUNDLE_IF_TYPE_IS(IntArray); + PUT_IN_BUNDLE_IF_TYPE_IS(DoubleArray); + PUT_IN_BUNDLE_IF_TYPE_IS(StringArray); + // There's no "putObjectArray", so don't check ObjectArrayProperty + // There's no "putBundleArray", so don't check BundleArrayProperty + + // Use Bundle as the default catch-all for objects + PUT_IN_BUNDLE_IF_TYPE_IS(Bundle); + +#undef PUT_IN_BUNDLE_IF_TYPE_IS + + // We tried all supported types; just bail. + jni::ThrowException("java/lang/UnsupportedOperationException", + "Unsupported property type"); + return nullptr; + } + return jni::Object::LocalRef::Adopt(newBundle.Env(), + newBundle.Forget()); + } + + sdk::Bundle::LocalRef + BundleFromValue(JS::HandleValue val) + { + if (val.isNull()) { + return nullptr; + } + JS::RootedObject object(mJSContext, &val.toObject()); + return BundleFromValue(object); + } + + // Object properties + + bool ObjectInValue(JS::HandleValue val) const + { + return val.isObjectOrNull(); + } + + NativeJSObject::LocalRef + ObjectFromValue(JS::HandleValue val) + { + if (val.isNull()) { + return nullptr; + } + JS::RootedObject object(mJSContext, &val.toObject()); + return CreateChild(object); + } + + template<class Prop> typename Prop::NativeArray + ObjectNewArray(JS::HandleObject array, size_t length) + { + auto jarray = Prop::NativeArray::Adopt(mEnv, mEnv->NewObjectArray( + length, typename Prop::ClassType::Context().ClassRef(), + nullptr)); + if (!jarray) { + return nullptr; + } + + // For object arrays, we have to set each element separately. + for (size_t i = 0; i < length; i++) { + JS::RootedValue elem(mJSContext); + if (!CheckJSCall(JS_GetElement(mJSContext, array, i, &elem)) || + !CheckProperty(Prop::InValue, elem)) { + return nullptr; + } + mEnv->SetObjectArrayElement( + jarray.Get(), i, (this->*Prop::FromValue)(elem).Get()); + if (mEnv->ExceptionCheck()) { + return nullptr; + } + } + return jarray; + } + + template<class Class, + bool (Self::*InValue_)(JS::HandleValue) const, + typename Class::LocalRef (Self::*FromValue_)(JS::HandleValue)> + struct BaseObjectProperty + { + // JNI class for the object type (e.g. jni::String) + typedef Class ClassType; + + // See comments in PrimitiveProperty. + typedef typename ClassType::LocalRef NativeType; + typedef const typename ClassType::Ref NativeFallback; + typedef typename jni::ObjectArray::LocalRef NativeArray; + typedef const jni::ObjectArray::Ref ArrayFallback; + + typedef decltype(InValue_) InValue_t; + static constexpr InValue_t InValue = InValue_; + + typedef decltype(FromValue_) FromValue_t; + static constexpr FromValue_t FromValue = FromValue_; + + typedef decltype(&Self::ObjectNewArray<BaseObjectProperty>) NewArray_t; + static constexpr NewArray_t NewArray + = &Self::ObjectNewArray<BaseObjectProperty>; + }; + + // Array properties + + template<class Prop> bool + ArrayInValue(JS::HandleValue val) const + { + if (!val.isObject()) { + return false; + } + JS::RootedObject obj(mJSContext, &val.toObject()); + bool isArray; + uint32_t length = 0; + if (!JS_IsArrayObject(mJSContext, obj, &isArray) || + !isArray || + !JS_GetArrayLength(mJSContext, obj, &length)) { + JS_ClearPendingException(mJSContext); + return false; + } + if (!length) { + // Empty arrays are always okay. + return true; + } + // We only check to see the first element is the target type. If the + // array has mixed types, we'll throw an error during actual conversion. + JS::RootedValue element(mJSContext); + if (!JS_GetElement(mJSContext, obj, 0, &element)) { + JS_ClearPendingException(mJSContext); + return false; + } + return (this->*Prop::InValue)(element); + } + + template<class Prop> typename Prop::NativeArray + ArrayFromValue(JS::HandleValue val) + { + JS::RootedObject obj(mJSContext, &val.toObject()); + uint32_t length = 0; + if (!CheckJSCall(JS_GetArrayLength(mJSContext, obj, &length))) { + return nullptr; + } + return (this->*Prop::NewArray)(obj, length); + } + + template<class Prop> + struct ArrayProperty + { + // See comments in PrimitiveProperty. + typedef typename Prop::NativeArray NativeType; + typedef typename Prop::ArrayFallback NativeFallback; + + typedef decltype(&Self::ArrayInValue<Prop>) InValue_t; + static constexpr InValue_t InValue + = &Self::ArrayInValue<Prop>; + + typedef decltype(&Self::ArrayFromValue<Prop>) FromValue_t; + static constexpr FromValue_t FromValue + = &Self::ArrayFromValue<Prop>; + }; + + // "Has" property is a special property type that is used to implement + // NativeJSObject.has, by returning true from InValue and FromValue for + // every existing property, and having false as the fallback value for + // when a property doesn't exist. + + bool HasValue(JS::HandleValue val) const + { + return true; + } + + struct HasProperty + { + // See comments in PrimitiveProperty. + typedef bool NativeType; + typedef bool NativeFallback; + + typedef decltype(&Self::HasValue) HasValue_t; + static constexpr HasValue_t InValue = &Self::HasValue; + static constexpr HasValue_t FromValue = &Self::HasValue; + }; + + // Statically cast from bool to jboolean (unsigned char); it works + // since false and JNI_FALSE have the same value (0), and true and + // JNI_TRUE have the same value (1). + typedef PrimitiveProperty< + bool, jni::BooleanArray, jboolean, jbooleanArray, + &JS::Value::isBoolean, &JS::Value::toBoolean, + &JNIEnv::NewBooleanArray, &JNIEnv::SetBooleanArrayRegion> + BooleanProperty; + + typedef PrimitiveProperty< + double, jni::DoubleArray, jdouble, jdoubleArray, + &JS::Value::isNumber, &JS::Value::toNumber, + &JNIEnv::NewDoubleArray, &JNIEnv::SetDoubleArrayRegion> + DoubleProperty; + + typedef PrimitiveProperty< + int32_t, jni::IntArray, jint, jintArray, + &JS::Value::isInt32, &JS::Value::toInt32, + &JNIEnv::NewIntArray, &JNIEnv::SetIntArrayRegion> + IntProperty; + + typedef BaseObjectProperty< + jni::String, &Self::StringInValue, &Self::StringFromValue> + StringProperty; + + typedef BaseObjectProperty< + sdk::Bundle, &Self::ObjectInValue, &Self::BundleFromValue> + BundleProperty; + + typedef BaseObjectProperty< + NativeJSObject, &Self::ObjectInValue, &Self::ObjectFromValue> + ObjectProperty; + + typedef ArrayProperty<BooleanProperty> BooleanArrayProperty; + typedef ArrayProperty<DoubleProperty> DoubleArrayProperty; + typedef ArrayProperty<IntProperty> IntArrayProperty; + typedef ArrayProperty<StringProperty> StringArrayProperty; + typedef ArrayProperty<BundleProperty> BundleArrayProperty; + typedef ArrayProperty<ObjectProperty> ObjectArrayProperty; + + template<class Prop> + typename Prop::NativeType + GetProperty(jni::String::Param name, + typename Prop::NativeFallback* fallback = nullptr) + { + if (!CheckThread() || !CheckObject()) { + return typename Prop::NativeType(); + } + + const JSJNIString nameStr(mEnv, name); + JS::RootedValue val(mJSContext); + + if (!CheckJNIArgument(name) || + !CheckJSCall(JS_GetUCProperty( + mJSContext, mJSObject, nameStr, nameStr.Length(), &val))) { + return typename Prop::NativeType(); + } + + // Strictly, null is different from undefined in JS. However, in + // practice, null is often used to indicate a property doesn't exist in + // the same manner as undefined. Therefore, we treat null in the same + // way as undefined when checking property existence (bug 1014965). + if (val.isUndefined() || val.isNull()) { + if (fallback) { + return mozilla::Move(*fallback); + } + jni::ThrowException( + "org/mozilla/gecko/util/NativeJSObject$InvalidPropertyException", + "Property does not exist"); + return typename Prop::NativeType(); + } + + if (!CheckProperty(Prop::InValue, val)) { + return typename Prop::NativeType(); + } + return (this->*Prop::FromValue)(val); + } + + NativeJSObject::LocalRef CreateChild(JS::HandleObject object) + { + auto instance = NativeJSObject::New(); + mozilla::UniquePtr<NativeJSContainerImpl> impl( + new NativeJSContainerImpl(instance.Env(), mJSContext, object)); + + ObjectBase::AttachNative(instance, mozilla::Move(impl)); + if (!mChildren.append(NativeJSObject::GlobalRef(instance))) { + MOZ_CRASH(); + } + return instance; + } + + NativeJSContainerImpl(JNIEnv* env, JSContext* cx, JS::HandleObject object) + : mEnv(env) + , mJSContext(cx) + , mJSObject(cx, object) + {} + +public: + ~NativeJSContainerImpl() + { + // Dispose of all children on destruction. The children will in turn + // dispose any of their children (i.e. our grandchildren) and so on. + NativeJSObject::LocalRef child(mEnv); + for (size_t i = 0; i < mChildren.length(); i++) { + child = mChildren[i]; + ObjectBase::GetNative(child)->ObjectBase::DisposeNative(child); + } + } + + static NativeJSContainer::LocalRef + CreateInstance(JSContext* cx, JS::HandleObject object) + { + auto instance = NativeJSContainer::New(); + mozilla::UniquePtr<NativeJSContainerImpl> impl( + new NativeJSContainerImpl(instance.Env(), cx, object)); + + ContainerBase::AttachNative(instance, mozilla::Move(impl)); + return instance; + } + + // NativeJSContainer methods + + void DisposeNative(const NativeJSContainer::LocalRef& instance) + { + if (!CheckThread()) { + return; + } + ContainerBase::DisposeNative(instance); + } + + NativeJSContainer::LocalRef Clone() + { + if (!CheckThread()) { + return nullptr; + } + return CreateInstance(mJSContext, mJSObject); + } + + // NativeJSObject methods + + bool GetBoolean(jni::String::Param name) + { + return GetProperty<BooleanProperty>(name); + } + + bool OptBoolean(jni::String::Param name, bool fallback) + { + return GetProperty<BooleanProperty>(name, &fallback); + } + + jni::BooleanArray::LocalRef + GetBooleanArray(jni::String::Param name) + { + return GetProperty<BooleanArrayProperty>(name); + } + + jni::BooleanArray::LocalRef + OptBooleanArray(jni::String::Param name, jni::BooleanArray::Param fallback) + { + return GetProperty<BooleanArrayProperty>(name, &fallback); + } + + jni::Object::LocalRef + GetBundle(jni::String::Param name) + { + return GetProperty<BundleProperty>(name); + } + + jni::Object::LocalRef + OptBundle(jni::String::Param name, jni::Object::Param fallback) + { + // Because the GetProperty expects a sdk::Bundle::Param, + // we have to do conversions here from jni::Object::Param. + const auto& fb = sdk::Bundle::Ref::From(fallback.Get()); + return GetProperty<BundleProperty>(name, &fb); + } + + jni::ObjectArray::LocalRef + GetBundleArray(jni::String::Param name) + { + return GetProperty<BundleArrayProperty>(name); + } + + jni::ObjectArray::LocalRef + OptBundleArray(jni::String::Param name, jni::ObjectArray::Param fallback) + { + return GetProperty<BundleArrayProperty>(name, &fallback); + } + + double GetDouble(jni::String::Param name) + { + return GetProperty<DoubleProperty>(name); + } + + double OptDouble(jni::String::Param name, double fallback) + { + return GetProperty<DoubleProperty>(name, &fallback); + } + + jni::DoubleArray::LocalRef + GetDoubleArray(jni::String::Param name) + { + return GetProperty<DoubleArrayProperty>(name); + } + + jni::DoubleArray::LocalRef + OptDoubleArray(jni::String::Param name, jni::DoubleArray::Param fallback) + { + jni::DoubleArray::LocalRef fb(fallback); + return GetProperty<DoubleArrayProperty>(name, &fb); + } + + int GetInt(jni::String::Param name) + { + return GetProperty<IntProperty>(name); + } + + int OptInt(jni::String::Param name, int fallback) + { + return GetProperty<IntProperty>(name, &fallback); + } + + jni::IntArray::LocalRef + GetIntArray(jni::String::Param name) + { + return GetProperty<IntArrayProperty>(name); + } + + jni::IntArray::LocalRef + OptIntArray(jni::String::Param name, jni::IntArray::Param fallback) + { + jni::IntArray::LocalRef fb(fallback); + return GetProperty<IntArrayProperty>(name, &fb); + } + + NativeJSObject::LocalRef + GetObject(jni::String::Param name) + { + return GetProperty<ObjectProperty>(name); + } + + NativeJSObject::LocalRef + OptObject(jni::String::Param name, NativeJSObject::Param fallback) + { + return GetProperty<ObjectProperty>(name, &fallback); + } + + jni::ObjectArray::LocalRef + GetObjectArray(jni::String::Param name) + { + return GetProperty<ObjectArrayProperty>(name); + } + + jni::ObjectArray::LocalRef + OptObjectArray(jni::String::Param name, jni::ObjectArray::Param fallback) + { + return GetProperty<ObjectArrayProperty>(name, &fallback); + } + + jni::String::LocalRef + GetString(jni::String::Param name) + { + return GetProperty<StringProperty>(name); + } + + jni::String::LocalRef + OptString(jni::String::Param name, jni::String::Param fallback) + { + return GetProperty<StringProperty>(name, &fallback); + } + + jni::ObjectArray::LocalRef + GetStringArray(jni::String::Param name) + { + return GetProperty<StringArrayProperty>(name); + } + + jni::ObjectArray::LocalRef + OptStringArray(jni::String::Param name, jni::ObjectArray::Param fallback) + { + return GetProperty<StringArrayProperty>(name, &fallback); + } + + bool Has(jni::String::Param name) + { + bool no = false; + // Fallback to false indicating no such property. + return GetProperty<HasProperty>(name, &no); + } + + jni::Object::LocalRef ToBundle() + { + if (!CheckThread() || !CheckObject()) { + return nullptr; + } + return BundleFromValue(mJSObject); + } + +private: + static bool AppendJSON(const char16_t* buf, uint32_t len, void* data) + { + static_cast<nsAutoString*>(data)->Append(buf, len); + return true; + } + +public: + jni::String::LocalRef ToString() + { + if (!CheckThread() || !CheckObject()) { + return nullptr; + } + + JS::RootedValue value(mJSContext, JS::ObjectValue(*mJSObject)); + nsAutoString json; + if (!CheckJSCall(JS_Stringify(mJSContext, &value, nullptr, + JS::NullHandleValue, AppendJSON, &json))) { + return nullptr; + } + return jni::StringParam(json, mEnv); + } +}; + + +// Define the "static constexpr" members of our property types (e.g. +// PrimitiveProperty<>::InValue). This is tricky because there are a lot of +// template parameters, so we use macros to make it simpler. + +#define DEFINE_PRIMITIVE_PROPERTY_MEMBER(Name) \ + template<typename U, typename UA, typename V, typename VA, \ + bool (JS::Value::*I)() const, \ + U (JS::Value::*T)() const, \ + VA (JNIEnv::*N)(jsize), \ + void (JNIEnv::*S)(VA, jsize, jsize, const V*)> \ + constexpr typename NativeJSContainerImpl \ + ::PrimitiveProperty<U, UA, V, VA, I, T, N, S>::Name##_t \ + NativeJSContainerImpl::PrimitiveProperty<U, UA, V, VA, I, T, N, S>::Name + +DEFINE_PRIMITIVE_PROPERTY_MEMBER(NewJNIArray); +DEFINE_PRIMITIVE_PROPERTY_MEMBER(SetJNIArrayRegion); +DEFINE_PRIMITIVE_PROPERTY_MEMBER(InValue); +DEFINE_PRIMITIVE_PROPERTY_MEMBER(FromValue); +DEFINE_PRIMITIVE_PROPERTY_MEMBER(NewArray); + +#undef DEFINE_PRIMITIVE_PROPERTY_MEMBER + +#define DEFINE_OBJECT_PROPERTY_MEMBER(Name) \ + template<class C, \ + bool (NativeJSContainerImpl::*I)(JS::HandleValue) const, \ + typename C::LocalRef (NativeJSContainerImpl::*F)(JS::HandleValue)> \ + constexpr typename NativeJSContainerImpl \ + ::BaseObjectProperty<C, I, F>::Name##_t \ + NativeJSContainerImpl::BaseObjectProperty<C, I, F>::Name + +DEFINE_OBJECT_PROPERTY_MEMBER(InValue); +DEFINE_OBJECT_PROPERTY_MEMBER(FromValue); +DEFINE_OBJECT_PROPERTY_MEMBER(NewArray); + +#undef DEFINE_OBJECT_PROPERTY_MEMBER + +template<class P> constexpr typename NativeJSContainerImpl::ArrayProperty<P> + ::InValue_t NativeJSContainerImpl::ArrayProperty<P>::InValue; +template<class P> constexpr typename NativeJSContainerImpl::ArrayProperty<P> + ::FromValue_t NativeJSContainerImpl::ArrayProperty<P>::FromValue; + +constexpr NativeJSContainerImpl::HasProperty::HasValue_t + NativeJSContainerImpl::HasProperty::InValue; +constexpr NativeJSContainerImpl::HasProperty::HasValue_t + NativeJSContainerImpl::HasProperty::FromValue; + + +NativeJSContainer::LocalRef +CreateNativeJSContainer(JSContext* cx, JS::HandleObject object) +{ + return NativeJSContainerImpl::CreateInstance(cx, object); +} + +} // namespace widget +} // namespace mozilla + diff --git a/widget/android/NativeJSContainer.h b/widget/android/NativeJSContainer.h new file mode 100644 index 000000000..bebf75f1b --- /dev/null +++ b/widget/android/NativeJSContainer.h @@ -0,0 +1,22 @@ +/* -*- Mode: c++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4; -*- */ +/* 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 NativeJSObject_h__ +#define NativeJSObject_h__ + +#include "GeneratedJNIWrappers.h" +#include "jsapi.h" + +namespace mozilla { +namespace widget { + +java::NativeJSContainer::LocalRef +CreateNativeJSContainer(JSContext* cx, JS::HandleObject object); + +} // namespace widget +} // namespace mozilla + +#endif // NativeJSObject_h__ + diff --git a/widget/android/PrefsHelper.h b/widget/android/PrefsHelper.h new file mode 100644 index 000000000..b053c979a --- /dev/null +++ b/widget/android/PrefsHelper.h @@ -0,0 +1,324 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 PrefsHelper_h +#define PrefsHelper_h + +#include "GeneratedJNINatives.h" +#include "MainThreadUtils.h" +#include "nsAppShell.h" +#include "nsCOMPtr.h" +#include "nsVariant.h" + +#include "mozilla/Preferences.h" +#include "mozilla/Services.h" + +namespace mozilla { + +class PrefsHelper + : public java::PrefsHelper::Natives<PrefsHelper> +{ + PrefsHelper() = delete; + + static bool GetVariantPref(nsIObserverService* aObsServ, + nsIWritableVariant* aVariant, + jni::Object::Param aPrefHandler, + const jni::String::LocalRef& aPrefName) + { + if (NS_FAILED(aObsServ->NotifyObservers(aVariant, "android-get-pref", + aPrefName->ToString().get()))) { + return false; + } + + uint16_t varType = nsIDataType::VTYPE_EMPTY; + if (NS_FAILED(aVariant->GetDataType(&varType))) { + return false; + } + + int32_t type = java::PrefsHelper::PREF_INVALID; + bool boolVal = false; + int32_t intVal = 0; + nsAutoString strVal; + + switch (varType) { + case nsIDataType::VTYPE_BOOL: + type = java::PrefsHelper::PREF_BOOL; + if (NS_FAILED(aVariant->GetAsBool(&boolVal))) { + return false; + } + break; + case nsIDataType::VTYPE_INT32: + type = java::PrefsHelper::PREF_INT; + if (NS_FAILED(aVariant->GetAsInt32(&intVal))) { + return false; + } + break; + case nsIDataType::VTYPE_ASTRING: + type = java::PrefsHelper::PREF_STRING; + if (NS_FAILED(aVariant->GetAsAString(strVal))) { + return false; + } + break; + default: + return false; + } + + jni::StringParam jstrVal(type == java::PrefsHelper::PREF_STRING ? + jni::StringParam(strVal, aPrefName.Env()) : + jni::StringParam(nullptr)); + + if (aPrefHandler) { + java::PrefsHelper::CallPrefHandler( + aPrefHandler, type, aPrefName, + boolVal, intVal, jstrVal); + } else { + java::PrefsHelper::OnPrefChange( + aPrefName, type, boolVal, intVal, jstrVal); + } + return true; + } + + static bool SetVariantPref(nsIObserverService* aObsServ, + nsIWritableVariant* aVariant, + jni::String::Param aPrefName, + bool aFlush, + int32_t aType, + bool aBoolVal, + int32_t aIntVal, + jni::String::Param aStrVal) + { + nsresult rv = NS_ERROR_FAILURE; + + switch (aType) { + case java::PrefsHelper::PREF_BOOL: + rv = aVariant->SetAsBool(aBoolVal); + break; + case java::PrefsHelper::PREF_INT: + rv = aVariant->SetAsInt32(aIntVal); + break; + case java::PrefsHelper::PREF_STRING: + rv = aVariant->SetAsAString(aStrVal->ToString()); + break; + } + + if (NS_SUCCEEDED(rv)) { + rv = aObsServ->NotifyObservers(aVariant, "android-set-pref", + aPrefName->ToString().get()); + } + + uint16_t varType = nsIDataType::VTYPE_EMPTY; + if (NS_SUCCEEDED(rv)) { + rv = aVariant->GetDataType(&varType); + } + + // We use set-to-empty to signal the pref was handled. + const bool handled = varType == nsIDataType::VTYPE_EMPTY; + + if (NS_SUCCEEDED(rv) && handled && aFlush) { + rv = Preferences::GetService()->SavePrefFile(nullptr); + } + + if (NS_SUCCEEDED(rv)) { + return handled; + } + + NS_WARNING(nsPrintfCString("Failed to set pref %s", + aPrefName->ToCString().get()).get()); + // Pretend we handled the pref. + return true; + } + +public: + static void GetPrefs(const jni::Class::LocalRef& aCls, + jni::ObjectArray::Param aPrefNames, + jni::Object::Param aPrefHandler) + { + nsTArray<jni::Object::LocalRef> nameRefArray(aPrefNames->GetElements()); + nsCOMPtr<nsIObserverService> obsServ; + nsCOMPtr<nsIWritableVariant> value; + nsAdoptingString strVal; + + for (jni::Object::LocalRef& nameRef : nameRefArray) { + jni::String::LocalRef nameStr(mozilla::Move(nameRef)); + const nsCString& name = nameStr->ToCString(); + + int32_t type = java::PrefsHelper::PREF_INVALID; + bool boolVal = false; + int32_t intVal = 0; + + switch (Preferences::GetType(name.get())) { + case nsIPrefBranch::PREF_BOOL: + type = java::PrefsHelper::PREF_BOOL; + boolVal = Preferences::GetBool(name.get()); + break; + + case nsIPrefBranch::PREF_INT: + type = java::PrefsHelper::PREF_INT; + intVal = Preferences::GetInt(name.get()); + break; + + case nsIPrefBranch::PREF_STRING: + type = java::PrefsHelper::PREF_STRING; + strVal = Preferences::GetLocalizedString(name.get()); + if (!strVal) { + strVal = Preferences::GetString(name.get()); + } + break; + + default: + // Pref not found; try to find it. + if (!obsServ) { + obsServ = services::GetObserverService(); + if (!obsServ) { + continue; + } + } + if (value) { + value->SetAsEmpty(); + } else { + value = new nsVariant(); + } + if (!GetVariantPref(obsServ, value, + aPrefHandler, nameStr)) { + NS_WARNING(nsPrintfCString("Failed to get pref %s", + name.get()).get()); + } + continue; + } + + java::PrefsHelper::CallPrefHandler( + aPrefHandler, type, nameStr, boolVal, intVal, + jni::StringParam(type == java::PrefsHelper::PREF_STRING ? + jni::StringParam(strVal, aCls.Env()) : + jni::StringParam(nullptr))); + } + + java::PrefsHelper::CallPrefHandler( + aPrefHandler, java::PrefsHelper::PREF_FINISH, + nullptr, false, 0, nullptr); + } + + static void SetPref(jni::String::Param aPrefName, + bool aFlush, + int32_t aType, + bool aBoolVal, + int32_t aIntVal, + jni::String::Param aStrVal) + { + const nsCString& name = aPrefName->ToCString(); + + if (Preferences::GetType(name.get()) == nsIPrefBranch::PREF_INVALID) { + // No pref; try asking first. + nsCOMPtr<nsIObserverService> obsServ = + services::GetObserverService(); + nsCOMPtr<nsIWritableVariant> value = new nsVariant(); + if (obsServ && SetVariantPref(obsServ, value, aPrefName, aFlush, + aType, aBoolVal, aIntVal, aStrVal)) { + // The "pref" has changed; send a notification. + GetVariantPref(obsServ, value, nullptr, + jni::String::LocalRef(aPrefName)); + return; + } + } + + switch (aType) { + case java::PrefsHelper::PREF_BOOL: + Preferences::SetBool(name.get(), aBoolVal); + break; + case java::PrefsHelper::PREF_INT: + Preferences::SetInt(name.get(), aIntVal); + break; + case java::PrefsHelper::PREF_STRING: + Preferences::SetString(name.get(), aStrVal->ToString()); + break; + default: + MOZ_ASSERT(false, "Invalid pref type"); + } + + if (aFlush) { + Preferences::GetService()->SavePrefFile(nullptr); + } + } + + static void AddObserver(const jni::Class::LocalRef& aCls, + jni::ObjectArray::Param aPrefNames, + jni::Object::Param aPrefHandler, + jni::ObjectArray::Param aPrefsToObserve) + { + // Call observer immediately with existing pref values. + GetPrefs(aCls, aPrefNames, aPrefHandler); + + if (!aPrefsToObserve) { + return; + } + + nsTArray<jni::Object::LocalRef> nameRefArray( + aPrefsToObserve->GetElements()); + nsAppShell* const appShell = nsAppShell::Get(); + MOZ_ASSERT(appShell); + + for (jni::Object::LocalRef& nameRef : nameRefArray) { + jni::String::LocalRef nameStr(mozilla::Move(nameRef)); + MOZ_ALWAYS_SUCCEEDS(Preferences::AddStrongObserver( + appShell, nameStr->ToCString().get())); + } + } + + static void RemoveObserver(const jni::Class::LocalRef& aCls, + jni::ObjectArray::Param aPrefsToUnobserve) + { + nsTArray<jni::Object::LocalRef> nameRefArray( + aPrefsToUnobserve->GetElements()); + nsAppShell* const appShell = nsAppShell::Get(); + MOZ_ASSERT(appShell); + + for (jni::Object::LocalRef& nameRef : nameRefArray) { + jni::String::LocalRef nameStr(mozilla::Move(nameRef)); + MOZ_ALWAYS_SUCCEEDS(Preferences::RemoveObserver( + appShell, nameStr->ToCString().get())); + } + } + + static void OnPrefChange(const char16_t* aData) + { + const nsCString& name = NS_LossyConvertUTF16toASCII(aData); + + int32_t type = -1; + bool boolVal = false; + int32_t intVal = false; + nsAdoptingString strVal; + + switch (Preferences::GetType(name.get())) { + case nsIPrefBranch::PREF_BOOL: + type = java::PrefsHelper::PREF_BOOL; + boolVal = Preferences::GetBool(name.get()); + break; + case nsIPrefBranch::PREF_INT: + type = java::PrefsHelper::PREF_INT; + intVal = Preferences::GetInt(name.get()); + break; + case nsIPrefBranch::PREF_STRING: + type = java::PrefsHelper::PREF_STRING; + strVal = Preferences::GetLocalizedString(name.get()); + if (!strVal) { + strVal = Preferences::GetString(name.get()); + } + break; + default: + NS_WARNING(nsPrintfCString("Invalid pref %s", + name.get()).get()); + return; + } + + java::PrefsHelper::OnPrefChange( + name, type, boolVal, intVal, + jni::StringParam(type == java::PrefsHelper::PREF_STRING ? + jni::StringParam(strVal) : jni::StringParam(nullptr))); + } +}; + +} // namespace + +#endif // PrefsHelper_h diff --git a/widget/android/bindings/AndroidRect-classes.txt b/widget/android/bindings/AndroidRect-classes.txt new file mode 100644 index 000000000..cbacca81e --- /dev/null +++ b/widget/android/bindings/AndroidRect-classes.txt @@ -0,0 +1,2 @@ +android.graphics.Rect +android.graphics.RectF diff --git a/widget/android/bindings/Bundle-classes.txt b/widget/android/bindings/Bundle-classes.txt new file mode 100644 index 000000000..9f535cddb --- /dev/null +++ b/widget/android/bindings/Bundle-classes.txt @@ -0,0 +1 @@ +android.os.Bundle diff --git a/widget/android/bindings/KeyEvent-classes.txt b/widget/android/bindings/KeyEvent-classes.txt new file mode 100644 index 000000000..b73e621ef --- /dev/null +++ b/widget/android/bindings/KeyEvent-classes.txt @@ -0,0 +1 @@ +android.view.KeyEvent diff --git a/widget/android/bindings/Makefile.in b/widget/android/bindings/Makefile.in new file mode 100644 index 000000000..ea66e6022 --- /dev/null +++ b/widget/android/bindings/Makefile.in @@ -0,0 +1,27 @@ +# 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/. + +# Bug 1099345 - The SDK's lint code (used by the code generator) does not enjoy +# concurrent access to a cache that it generates. +.NOTPARALLEL: + +annotation_processor_jar_files := \ + $(DEPTH)/build/annotationProcessors/annotationProcessors.jar \ + $(ANDROID_TOOLS)/lib/lint.jar \ + $(ANDROID_TOOLS)/lib/lint-checks.jar \ + $(NULL) + +sdk_processor := \ + $(JAVA) \ + -Dcom.android.tools.lint.bindir='$(ANDROID_TOOLS)' \ + -classpath $(subst $(NULL) ,:,$(strip $(annotation_processor_jar_files))) \ + org.mozilla.gecko.annotationProcessors.SDKProcessor + +# For the benefit of readers: the following pattern rule says that, +# for example, MediaCodec.cpp and MediaCodec.h can be produced from +# MediaCodec-classes.txt. This formulation invokes the SDK processor +# at most once. + +%.cpp %.h: $(ANDROID_SDK)/android.jar %-classes.txt $(annotation_processor_jar_files) + $(sdk_processor) $(ANDROID_SDK)/android.jar $(srcdir)/$*-classes.txt $(CURDIR) $* 16 diff --git a/widget/android/bindings/MediaCodec-classes.txt b/widget/android/bindings/MediaCodec-classes.txt new file mode 100644 index 000000000..ea26029af --- /dev/null +++ b/widget/android/bindings/MediaCodec-classes.txt @@ -0,0 +1,5 @@ +android.media.MediaCodec +android.media.MediaCodec$BufferInfo +android.media.MediaCodec$CryptoInfo +android.media.MediaDrm$KeyStatus +android.media.MediaFormat diff --git a/widget/android/bindings/MotionEvent-classes.txt b/widget/android/bindings/MotionEvent-classes.txt new file mode 100644 index 000000000..dd38dc000 --- /dev/null +++ b/widget/android/bindings/MotionEvent-classes.txt @@ -0,0 +1 @@ +android.view.MotionEvent diff --git a/widget/android/bindings/SurfaceTexture-classes.txt b/widget/android/bindings/SurfaceTexture-classes.txt new file mode 100644 index 000000000..5c7ca8968 --- /dev/null +++ b/widget/android/bindings/SurfaceTexture-classes.txt @@ -0,0 +1,2 @@ +android.graphics.SurfaceTexture +android.view.Surface diff --git a/widget/android/bindings/ViewConfiguration-classes.txt b/widget/android/bindings/ViewConfiguration-classes.txt new file mode 100644 index 000000000..e6601e65f --- /dev/null +++ b/widget/android/bindings/ViewConfiguration-classes.txt @@ -0,0 +1 @@ +android.view.ViewConfiguration diff --git a/widget/android/bindings/moz.build b/widget/android/bindings/moz.build new file mode 100644 index 000000000..1bd71fa95 --- /dev/null +++ b/widget/android/bindings/moz.build @@ -0,0 +1,41 @@ +# -*- 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/. + +# List of stems to generate .cpp and .h files for. To add a stem, add it to +# this list and ensure that $(stem)-classes.txt exists in this directory. +generated = [ + 'AndroidRect', + 'Bundle', + 'KeyEvent', + 'MediaCodec', + 'MotionEvent', + 'SurfaceTexture', + 'ViewConfiguration' +] + +SOURCES += ['!%s.cpp' % stem for stem in generated] + +EXPORTS += ['!%s.h' % stem for stem in generated] + +# We'd like to add these to a future GENERATED_EXPORTS list, but for now we mark +# them as generated here and manually install them in Makefile.in. +GENERATED_FILES += [stem + '.h' for stem in generated] + +# There is an unfortunate race condition when using generated SOURCES and +# pattern rules (see Makefile.in) that manifests itself as a VPATH resolution +# conflict: MediaCodec.o looks for MediaCodec.cpp and $(CURDIR)/MediaCodec.cpp, +# and the pattern rule is matched but doesn't resolve both sources, causing a +# failure. Adding the SOURCES to GENERATED_FILES causes the sources +# to be built at export time, which is before MediaCodec.o needs them; and by +# the time MediaCodec.o is built, the source is in place and the VPATH +# resolution works as expected. +GENERATED_FILES += [f[1:] for f in SOURCES] + +FINAL_LIBRARY = 'xul' + +LOCAL_INCLUDES += [ + '/widget/android', +] diff --git a/widget/android/fennec/FennecJNINatives.h b/widget/android/fennec/FennecJNINatives.h new file mode 100644 index 000000000..9d0cdd77c --- /dev/null +++ b/widget/android/fennec/FennecJNINatives.h @@ -0,0 +1,244 @@ +// GENERATED CODE +// Generated by the Java program at /build/annotationProcessors at compile time +// from annotations on Java methods. To update, change the annotations on the +// corresponding Java methods and rerun the build. Manually updating this file +// will cause your build to fail. + +#ifndef FennecJNINatives_h +#define FennecJNINatives_h + +#include "FennecJNIWrappers.h" +#include "mozilla/jni/Natives.h" + +namespace mozilla { +namespace java { + +template<class Impl> +class ANRReporter::Natives : public mozilla::jni::NativeImpl<ANRReporter, Impl> +{ +public: + static const JNINativeMethod methods[3]; +}; + +template<class Impl> +const JNINativeMethod ANRReporter::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<ANRReporter::GetNativeStack_t>( + mozilla::jni::NativeStub<ANRReporter::GetNativeStack_t, Impl> + ::template Wrap<&Impl::GetNativeStack>), + + mozilla::jni::MakeNativeMethod<ANRReporter::ReleaseNativeStack_t>( + mozilla::jni::NativeStub<ANRReporter::ReleaseNativeStack_t, Impl> + ::template Wrap<&Impl::ReleaseNativeStack>), + + mozilla::jni::MakeNativeMethod<ANRReporter::RequestNativeStack_t>( + mozilla::jni::NativeStub<ANRReporter::RequestNativeStack_t, Impl> + ::template Wrap<&Impl::RequestNativeStack>) +}; + +template<class Impl> +class GeckoJavaSampler::Natives : public mozilla::jni::NativeImpl<GeckoJavaSampler, Impl> +{ +public: + static const JNINativeMethod methods[1]; +}; + +template<class Impl> +const JNINativeMethod GeckoJavaSampler::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<GeckoJavaSampler::GetProfilerTime_t>( + mozilla::jni::NativeStub<GeckoJavaSampler::GetProfilerTime_t, Impl> + ::template Wrap<&Impl::GetProfilerTime>) +}; + +template<class Impl> +class MemoryMonitor::Natives : public mozilla::jni::NativeImpl<MemoryMonitor, Impl> +{ +public: + static const JNINativeMethod methods[1]; +}; + +template<class Impl> +const JNINativeMethod MemoryMonitor::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<MemoryMonitor::DispatchMemoryPressure_t>( + mozilla::jni::NativeStub<MemoryMonitor::DispatchMemoryPressure_t, Impl> + ::template Wrap<&Impl::DispatchMemoryPressure>) +}; + +template<class Impl> +class PresentationMediaPlayerManager::Natives : public mozilla::jni::NativeImpl<PresentationMediaPlayerManager, Impl> +{ +public: + static const JNINativeMethod methods[3]; +}; + +template<class Impl> +const JNINativeMethod PresentationMediaPlayerManager::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<PresentationMediaPlayerManager::AddPresentationSurface_t>( + mozilla::jni::NativeStub<PresentationMediaPlayerManager::AddPresentationSurface_t, Impl> + ::template Wrap<&Impl::AddPresentationSurface>), + + mozilla::jni::MakeNativeMethod<PresentationMediaPlayerManager::InvalidateAndScheduleComposite_t>( + mozilla::jni::NativeStub<PresentationMediaPlayerManager::InvalidateAndScheduleComposite_t, Impl> + ::template Wrap<&Impl::InvalidateAndScheduleComposite>), + + mozilla::jni::MakeNativeMethod<PresentationMediaPlayerManager::RemovePresentationSurface_t>( + mozilla::jni::NativeStub<PresentationMediaPlayerManager::RemovePresentationSurface_t, Impl> + ::template Wrap<&Impl::RemovePresentationSurface>) +}; + +template<class Impl> +class ScreenManagerHelper::Natives : public mozilla::jni::NativeImpl<ScreenManagerHelper, Impl> +{ +public: + static const JNINativeMethod methods[2]; +}; + +template<class Impl> +const JNINativeMethod ScreenManagerHelper::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<ScreenManagerHelper::AddDisplay_t>( + mozilla::jni::NativeStub<ScreenManagerHelper::AddDisplay_t, Impl> + ::template Wrap<&Impl::AddDisplay>), + + mozilla::jni::MakeNativeMethod<ScreenManagerHelper::RemoveDisplay_t>( + mozilla::jni::NativeStub<ScreenManagerHelper::RemoveDisplay_t, Impl> + ::template Wrap<&Impl::RemoveDisplay>) +}; + +template<class Impl> +class Telemetry::Natives : public mozilla::jni::NativeImpl<Telemetry, Impl> +{ +public: + static const JNINativeMethod methods[5]; +}; + +template<class Impl> +const JNINativeMethod Telemetry::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<Telemetry::AddHistogram_t>( + mozilla::jni::NativeStub<Telemetry::AddHistogram_t, Impl> + ::template Wrap<&Impl::AddHistogram>), + + mozilla::jni::MakeNativeMethod<Telemetry::AddKeyedHistogram_t>( + mozilla::jni::NativeStub<Telemetry::AddKeyedHistogram_t, Impl> + ::template Wrap<&Impl::AddKeyedHistogram>), + + mozilla::jni::MakeNativeMethod<Telemetry::AddUIEvent_t>( + mozilla::jni::NativeStub<Telemetry::AddUIEvent_t, Impl> + ::template Wrap<&Impl::AddUIEvent>), + + mozilla::jni::MakeNativeMethod<Telemetry::StartUISession_t>( + mozilla::jni::NativeStub<Telemetry::StartUISession_t, Impl> + ::template Wrap<&Impl::StartUISession>), + + mozilla::jni::MakeNativeMethod<Telemetry::StopUISession_t>( + mozilla::jni::NativeStub<Telemetry::StopUISession_t, Impl> + ::template Wrap<&Impl::StopUISession>) +}; + +template<class Impl> +class ThumbnailHelper::Natives : public mozilla::jni::NativeImpl<ThumbnailHelper, Impl> +{ +public: + static const JNINativeMethod methods[1]; +}; + +template<class Impl> +const JNINativeMethod ThumbnailHelper::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<ThumbnailHelper::RequestThumbnail_t>( + mozilla::jni::NativeStub<ThumbnailHelper::RequestThumbnail_t, Impl> + ::template Wrap<&Impl::RequestThumbnail>) +}; + +template<class Impl> +class ZoomedView::Natives : public mozilla::jni::NativeImpl<ZoomedView, Impl> +{ +public: + static const JNINativeMethod methods[1]; +}; + +template<class Impl> +const JNINativeMethod ZoomedView::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<ZoomedView::RequestZoomedViewData_t>( + mozilla::jni::NativeStub<ZoomedView::RequestZoomedViewData_t, Impl> + ::template Wrap<&Impl::RequestZoomedViewData>) +}; + +template<class Impl> +class CodecProxy::NativeCallbacks::Natives : public mozilla::jni::NativeImpl<NativeCallbacks, Impl> +{ +public: + static const JNINativeMethod methods[5]; +}; + +template<class Impl> +const JNINativeMethod CodecProxy::NativeCallbacks::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<CodecProxy::NativeCallbacks::DisposeNative_t>( + mozilla::jni::NativeStub<CodecProxy::NativeCallbacks::DisposeNative_t, Impl> + ::template Wrap<&Impl::DisposeNative>), + + mozilla::jni::MakeNativeMethod<CodecProxy::NativeCallbacks::OnError_t>( + mozilla::jni::NativeStub<CodecProxy::NativeCallbacks::OnError_t, Impl> + ::template Wrap<&Impl::OnError>), + + mozilla::jni::MakeNativeMethod<CodecProxy::NativeCallbacks::OnInputExhausted_t>( + mozilla::jni::NativeStub<CodecProxy::NativeCallbacks::OnInputExhausted_t, Impl> + ::template Wrap<&Impl::OnInputExhausted>), + + mozilla::jni::MakeNativeMethod<CodecProxy::NativeCallbacks::OnOutput_t>( + mozilla::jni::NativeStub<CodecProxy::NativeCallbacks::OnOutput_t, Impl> + ::template Wrap<&Impl::OnOutput>), + + mozilla::jni::MakeNativeMethod<CodecProxy::NativeCallbacks::OnOutputFormatChanged_t>( + mozilla::jni::NativeStub<CodecProxy::NativeCallbacks::OnOutputFormatChanged_t, Impl> + ::template Wrap<&Impl::OnOutputFormatChanged>) +}; + +template<class Impl> +class MediaDrmProxy::NativeMediaDrmProxyCallbacks::Natives : public mozilla::jni::NativeImpl<NativeMediaDrmProxyCallbacks, Impl> +{ +public: + static const JNINativeMethod methods[7]; +}; + +template<class Impl> +const JNINativeMethod MediaDrmProxy::NativeMediaDrmProxyCallbacks::Natives<Impl>::methods[] = { + + mozilla::jni::MakeNativeMethod<MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnRejectPromise_t>( + mozilla::jni::NativeStub<MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnRejectPromise_t, Impl> + ::template Wrap<&Impl::OnRejectPromise>), + + mozilla::jni::MakeNativeMethod<MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionBatchedKeyChanged_t>( + mozilla::jni::NativeStub<MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionBatchedKeyChanged_t, Impl> + ::template Wrap<&Impl::OnSessionBatchedKeyChanged>), + + mozilla::jni::MakeNativeMethod<MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionClosed_t>( + mozilla::jni::NativeStub<MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionClosed_t, Impl> + ::template Wrap<&Impl::OnSessionClosed>), + + mozilla::jni::MakeNativeMethod<MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionCreated_t>( + mozilla::jni::NativeStub<MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionCreated_t, Impl> + ::template Wrap<&Impl::OnSessionCreated>), + + mozilla::jni::MakeNativeMethod<MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionError_t>( + mozilla::jni::NativeStub<MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionError_t, Impl> + ::template Wrap<&Impl::OnSessionError>), + + mozilla::jni::MakeNativeMethod<MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionMessage_t>( + mozilla::jni::NativeStub<MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionMessage_t, Impl> + ::template Wrap<&Impl::OnSessionMessage>), + + mozilla::jni::MakeNativeMethod<MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionUpdated_t>( + mozilla::jni::NativeStub<MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionUpdated_t, Impl> + ::template Wrap<&Impl::OnSessionUpdated>) +}; + +} /* java */ +} /* mozilla */ +#endif // FennecJNINatives_h diff --git a/widget/android/fennec/FennecJNIWrappers.cpp b/widget/android/fennec/FennecJNIWrappers.cpp new file mode 100644 index 000000000..f8be6833b --- /dev/null +++ b/widget/android/fennec/FennecJNIWrappers.cpp @@ -0,0 +1,443 @@ +// GENERATED CODE +// Generated by the Java program at /build/annotationProcessors at compile time +// from annotations on Java methods. To update, change the annotations on the +// corresponding Java methods and rerun the build. Manually updating this file +// will cause your build to fail. + +#include "FennecJNIWrappers.h" +#include "mozilla/jni/Accessors.h" + +namespace mozilla { +namespace java { + +const char ANRReporter::name[] = + "org/mozilla/gecko/ANRReporter"; + +constexpr char ANRReporter::GetNativeStack_t::name[]; +constexpr char ANRReporter::GetNativeStack_t::signature[]; + +constexpr char ANRReporter::ReleaseNativeStack_t::name[]; +constexpr char ANRReporter::ReleaseNativeStack_t::signature[]; + +constexpr char ANRReporter::RequestNativeStack_t::name[]; +constexpr char ANRReporter::RequestNativeStack_t::signature[]; + +const char DownloadsIntegration::name[] = + "org/mozilla/gecko/DownloadsIntegration"; + +constexpr char DownloadsIntegration::GetTemporaryDownloadDirectory_t::name[]; +constexpr char DownloadsIntegration::GetTemporaryDownloadDirectory_t::signature[]; + +auto DownloadsIntegration::GetTemporaryDownloadDirectory() -> mozilla::jni::String::LocalRef +{ + return mozilla::jni::Method<GetTemporaryDownloadDirectory_t>::Call(DownloadsIntegration::Context(), nullptr); +} + +constexpr char DownloadsIntegration::ScanMedia_t::name[]; +constexpr char DownloadsIntegration::ScanMedia_t::signature[]; + +auto DownloadsIntegration::ScanMedia(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1) -> void +{ + return mozilla::jni::Method<ScanMedia_t>::Call(DownloadsIntegration::Context(), nullptr, a0, a1); +} + +const char GeckoJavaSampler::name[] = + "org/mozilla/gecko/GeckoJavaSampler"; + +constexpr char GeckoJavaSampler::GetFrameName_t::name[]; +constexpr char GeckoJavaSampler::GetFrameName_t::signature[]; + +auto GeckoJavaSampler::GetFrameName(int32_t a0, int32_t a1, int32_t a2) -> mozilla::jni::String::LocalRef +{ + return mozilla::jni::Method<GetFrameName_t>::Call(GeckoJavaSampler::Context(), nullptr, a0, a1, a2); +} + +constexpr char GeckoJavaSampler::GetProfilerTime_t::name[]; +constexpr char GeckoJavaSampler::GetProfilerTime_t::signature[]; + +constexpr char GeckoJavaSampler::GetSampleTime_t::name[]; +constexpr char GeckoJavaSampler::GetSampleTime_t::signature[]; + +auto GeckoJavaSampler::GetSampleTime(int32_t a0, int32_t a1) -> double +{ + return mozilla::jni::Method<GetSampleTime_t>::Call(GeckoJavaSampler::Context(), nullptr, a0, a1); +} + +constexpr char GeckoJavaSampler::GetThreadName_t::name[]; +constexpr char GeckoJavaSampler::GetThreadName_t::signature[]; + +auto GeckoJavaSampler::GetThreadName(int32_t a0) -> mozilla::jni::String::LocalRef +{ + return mozilla::jni::Method<GetThreadName_t>::Call(GeckoJavaSampler::Context(), nullptr, a0); +} + +constexpr char GeckoJavaSampler::Pause_t::name[]; +constexpr char GeckoJavaSampler::Pause_t::signature[]; + +auto GeckoJavaSampler::Pause() -> void +{ + return mozilla::jni::Method<Pause_t>::Call(GeckoJavaSampler::Context(), nullptr); +} + +constexpr char GeckoJavaSampler::Start_t::name[]; +constexpr char GeckoJavaSampler::Start_t::signature[]; + +auto GeckoJavaSampler::Start(int32_t a0, int32_t a1) -> void +{ + return mozilla::jni::Method<Start_t>::Call(GeckoJavaSampler::Context(), nullptr, a0, a1); +} + +constexpr char GeckoJavaSampler::Stop_t::name[]; +constexpr char GeckoJavaSampler::Stop_t::signature[]; + +auto GeckoJavaSampler::Stop() -> void +{ + return mozilla::jni::Method<Stop_t>::Call(GeckoJavaSampler::Context(), nullptr); +} + +constexpr char GeckoJavaSampler::Unpause_t::name[]; +constexpr char GeckoJavaSampler::Unpause_t::signature[]; + +auto GeckoJavaSampler::Unpause() -> void +{ + return mozilla::jni::Method<Unpause_t>::Call(GeckoJavaSampler::Context(), nullptr); +} + +const char MemoryMonitor::name[] = + "org/mozilla/gecko/MemoryMonitor"; + +constexpr char MemoryMonitor::DispatchMemoryPressure_t::name[]; +constexpr char MemoryMonitor::DispatchMemoryPressure_t::signature[]; + +const char PresentationMediaPlayerManager::name[] = + "org/mozilla/gecko/PresentationMediaPlayerManager"; + +constexpr char PresentationMediaPlayerManager::AddPresentationSurface_t::name[]; +constexpr char PresentationMediaPlayerManager::AddPresentationSurface_t::signature[]; + +constexpr char PresentationMediaPlayerManager::InvalidateAndScheduleComposite_t::name[]; +constexpr char PresentationMediaPlayerManager::InvalidateAndScheduleComposite_t::signature[]; + +constexpr char PresentationMediaPlayerManager::RemovePresentationSurface_t::name[]; +constexpr char PresentationMediaPlayerManager::RemovePresentationSurface_t::signature[]; + +const char ScreenManagerHelper::name[] = + "org/mozilla/gecko/ScreenManagerHelper"; + +constexpr char ScreenManagerHelper::AddDisplay_t::name[]; +constexpr char ScreenManagerHelper::AddDisplay_t::signature[]; + +constexpr char ScreenManagerHelper::RemoveDisplay_t::name[]; +constexpr char ScreenManagerHelper::RemoveDisplay_t::signature[]; + +const char Telemetry::name[] = + "org/mozilla/gecko/Telemetry"; + +constexpr char Telemetry::AddHistogram_t::name[]; +constexpr char Telemetry::AddHistogram_t::signature[]; + +constexpr char Telemetry::AddKeyedHistogram_t::name[]; +constexpr char Telemetry::AddKeyedHistogram_t::signature[]; + +constexpr char Telemetry::AddUIEvent_t::name[]; +constexpr char Telemetry::AddUIEvent_t::signature[]; + +constexpr char Telemetry::StartUISession_t::name[]; +constexpr char Telemetry::StartUISession_t::signature[]; + +constexpr char Telemetry::StopUISession_t::name[]; +constexpr char Telemetry::StopUISession_t::signature[]; + +const char ThumbnailHelper::name[] = + "org/mozilla/gecko/ThumbnailHelper"; + +constexpr char ThumbnailHelper::NotifyThumbnail_t::name[]; +constexpr char ThumbnailHelper::NotifyThumbnail_t::signature[]; + +auto ThumbnailHelper::NotifyThumbnail(mozilla::jni::ByteBuffer::Param a0, mozilla::jni::Object::Param a1, bool a2, bool a3) -> void +{ + return mozilla::jni::Method<NotifyThumbnail_t>::Call(ThumbnailHelper::Context(), nullptr, a0, a1, a2, a3); +} + +constexpr char ThumbnailHelper::RequestThumbnail_t::name[]; +constexpr char ThumbnailHelper::RequestThumbnail_t::signature[]; + +const char ZoomedView::name[] = + "org/mozilla/gecko/ZoomedView"; + +constexpr char ZoomedView::RequestZoomedViewData_t::name[]; +constexpr char ZoomedView::RequestZoomedViewData_t::signature[]; + +const char AudioFocusAgent::name[] = + "org/mozilla/gecko/media/AudioFocusAgent"; + +constexpr char AudioFocusAgent::NotifyStartedPlaying_t::name[]; +constexpr char AudioFocusAgent::NotifyStartedPlaying_t::signature[]; + +auto AudioFocusAgent::NotifyStartedPlaying() -> void +{ + return mozilla::jni::Method<NotifyStartedPlaying_t>::Call(AudioFocusAgent::Context(), nullptr); +} + +constexpr char AudioFocusAgent::NotifyStoppedPlaying_t::name[]; +constexpr char AudioFocusAgent::NotifyStoppedPlaying_t::signature[]; + +auto AudioFocusAgent::NotifyStoppedPlaying() -> void +{ + return mozilla::jni::Method<NotifyStoppedPlaying_t>::Call(AudioFocusAgent::Context(), nullptr); +} + +const char CodecProxy::name[] = + "org/mozilla/gecko/media/CodecProxy"; + +constexpr char CodecProxy::Create_t::name[]; +constexpr char CodecProxy::Create_t::signature[]; + +auto CodecProxy::Create(mozilla::jni::Object::Param a0, mozilla::jni::Object::Param a1, mozilla::jni::Object::Param a2) -> CodecProxy::LocalRef +{ + return mozilla::jni::Method<Create_t>::Call(CodecProxy::Context(), nullptr, a0, a1, a2); +} + +constexpr char CodecProxy::Flush_t::name[]; +constexpr char CodecProxy::Flush_t::signature[]; + +auto CodecProxy::Flush() const -> bool +{ + return mozilla::jni::Method<Flush_t>::Call(CodecProxy::mCtx, nullptr); +} + +constexpr char CodecProxy::Input_t::name[]; +constexpr char CodecProxy::Input_t::signature[]; + +auto CodecProxy::Input(mozilla::jni::ByteBuffer::Param a0, mozilla::jni::Object::Param a1, mozilla::jni::Object::Param a2) const -> bool +{ + return mozilla::jni::Method<Input_t>::Call(CodecProxy::mCtx, nullptr, a0, a1, a2); +} + +constexpr char CodecProxy::Release_t::name[]; +constexpr char CodecProxy::Release_t::signature[]; + +auto CodecProxy::Release() const -> bool +{ + return mozilla::jni::Method<Release_t>::Call(CodecProxy::mCtx, nullptr); +} + +const char CodecProxy::NativeCallbacks::name[] = + "org/mozilla/gecko/media/CodecProxy$NativeCallbacks"; + +constexpr char CodecProxy::NativeCallbacks::New_t::name[]; +constexpr char CodecProxy::NativeCallbacks::New_t::signature[]; + +auto CodecProxy::NativeCallbacks::New() -> NativeCallbacks::LocalRef +{ + return mozilla::jni::Constructor<New_t>::Call(NativeCallbacks::Context(), nullptr); +} + +constexpr char CodecProxy::NativeCallbacks::DisposeNative_t::name[]; +constexpr char CodecProxy::NativeCallbacks::DisposeNative_t::signature[]; + +constexpr char CodecProxy::NativeCallbacks::OnError_t::name[]; +constexpr char CodecProxy::NativeCallbacks::OnError_t::signature[]; + +constexpr char CodecProxy::NativeCallbacks::OnInputExhausted_t::name[]; +constexpr char CodecProxy::NativeCallbacks::OnInputExhausted_t::signature[]; + +constexpr char CodecProxy::NativeCallbacks::OnOutput_t::name[]; +constexpr char CodecProxy::NativeCallbacks::OnOutput_t::signature[]; + +constexpr char CodecProxy::NativeCallbacks::OnOutputFormatChanged_t::name[]; +constexpr char CodecProxy::NativeCallbacks::OnOutputFormatChanged_t::signature[]; + +const char MediaDrmProxy::name[] = + "org/mozilla/gecko/media/MediaDrmProxy"; + +constexpr char MediaDrmProxy::CanDecode_t::name[]; +constexpr char MediaDrmProxy::CanDecode_t::signature[]; + +auto MediaDrmProxy::CanDecode(mozilla::jni::String::Param a0) -> bool +{ + return mozilla::jni::Method<CanDecode_t>::Call(MediaDrmProxy::Context(), nullptr, a0); +} + +constexpr char MediaDrmProxy::IsCryptoSchemeSupported_t::name[]; +constexpr char MediaDrmProxy::IsCryptoSchemeSupported_t::signature[]; + +auto MediaDrmProxy::IsCryptoSchemeSupported(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1) -> bool +{ + return mozilla::jni::Method<IsCryptoSchemeSupported_t>::Call(MediaDrmProxy::Context(), nullptr, a0, a1); +} + +constexpr char MediaDrmProxy::CloseSession_t::name[]; +constexpr char MediaDrmProxy::CloseSession_t::signature[]; + +auto MediaDrmProxy::CloseSession(int32_t a0, mozilla::jni::String::Param a1) const -> void +{ + return mozilla::jni::Method<CloseSession_t>::Call(MediaDrmProxy::mCtx, nullptr, a0, a1); +} + +constexpr char MediaDrmProxy::Create_t::name[]; +constexpr char MediaDrmProxy::Create_t::signature[]; + +auto MediaDrmProxy::Create(mozilla::jni::String::Param a0, mozilla::jni::Object::Param a1, bool a2) -> MediaDrmProxy::LocalRef +{ + return mozilla::jni::Method<Create_t>::Call(MediaDrmProxy::Context(), nullptr, a0, a1, a2); +} + +constexpr char MediaDrmProxy::CreateSession_t::name[]; +constexpr char MediaDrmProxy::CreateSession_t::signature[]; + +auto MediaDrmProxy::CreateSession(int32_t a0, int32_t a1, mozilla::jni::String::Param a2, mozilla::jni::ByteArray::Param a3) const -> void +{ + return mozilla::jni::Method<CreateSession_t>::Call(MediaDrmProxy::mCtx, nullptr, a0, a1, a2, a3); +} + +constexpr char MediaDrmProxy::Destroy_t::name[]; +constexpr char MediaDrmProxy::Destroy_t::signature[]; + +auto MediaDrmProxy::Destroy() const -> void +{ + return mozilla::jni::Method<Destroy_t>::Call(MediaDrmProxy::mCtx, nullptr); +} + +constexpr char MediaDrmProxy::IsSchemeSupported_t::name[]; +constexpr char MediaDrmProxy::IsSchemeSupported_t::signature[]; + +auto MediaDrmProxy::IsSchemeSupported(mozilla::jni::String::Param a0) -> bool +{ + return mozilla::jni::Method<IsSchemeSupported_t>::Call(MediaDrmProxy::Context(), nullptr, a0); +} + +constexpr char MediaDrmProxy::UpdateSession_t::name[]; +constexpr char MediaDrmProxy::UpdateSession_t::signature[]; + +auto MediaDrmProxy::UpdateSession(int32_t a0, mozilla::jni::String::Param a1, mozilla::jni::ByteArray::Param a2) const -> void +{ + return mozilla::jni::Method<UpdateSession_t>::Call(MediaDrmProxy::mCtx, nullptr, a0, a1, a2); +} + +const char16_t MediaDrmProxy::AAC[] = u"audio/mp4a-latm"; + +const char16_t MediaDrmProxy::AVC[] = u"video/avc"; + +const char16_t MediaDrmProxy::OPUS[] = u"audio/opus"; + +const char16_t MediaDrmProxy::VORBIS[] = u"audio/vorbis"; + +const char16_t MediaDrmProxy::VP8[] = u"video/x-vnd.on2.vp8"; + +const char16_t MediaDrmProxy::VP9[] = u"video/x-vnd.on2.vp9"; + +const char MediaDrmProxy::NativeMediaDrmProxyCallbacks::name[] = + "org/mozilla/gecko/media/MediaDrmProxy$NativeMediaDrmProxyCallbacks"; + +constexpr char MediaDrmProxy::NativeMediaDrmProxyCallbacks::New_t::name[]; +constexpr char MediaDrmProxy::NativeMediaDrmProxyCallbacks::New_t::signature[]; + +auto MediaDrmProxy::NativeMediaDrmProxyCallbacks::New() -> NativeMediaDrmProxyCallbacks::LocalRef +{ + return mozilla::jni::Constructor<New_t>::Call(NativeMediaDrmProxyCallbacks::Context(), nullptr); +} + +constexpr char MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnRejectPromise_t::name[]; +constexpr char MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnRejectPromise_t::signature[]; + +constexpr char MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionBatchedKeyChanged_t::name[]; +constexpr char MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionBatchedKeyChanged_t::signature[]; + +constexpr char MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionClosed_t::name[]; +constexpr char MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionClosed_t::signature[]; + +constexpr char MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionCreated_t::name[]; +constexpr char MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionCreated_t::signature[]; + +constexpr char MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionError_t::name[]; +constexpr char MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionError_t::signature[]; + +constexpr char MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionMessage_t::name[]; +constexpr char MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionMessage_t::signature[]; + +constexpr char MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionUpdated_t::name[]; +constexpr char MediaDrmProxy::NativeMediaDrmProxyCallbacks::OnSessionUpdated_t::signature[]; + +const char Sample::name[] = + "org/mozilla/gecko/media/Sample"; + +constexpr char Sample::WriteToByteBuffer_t::name[]; +constexpr char Sample::WriteToByteBuffer_t::signature[]; + +auto Sample::WriteToByteBuffer(mozilla::jni::ByteBuffer::Param a0) const -> void +{ + return mozilla::jni::Method<WriteToByteBuffer_t>::Call(Sample::mCtx, nullptr, a0); +} + +constexpr char Sample::Info_t::name[]; +constexpr char Sample::Info_t::signature[]; + +auto Sample::Info() const -> mozilla::jni::Object::LocalRef +{ + return mozilla::jni::Field<Info_t>::Get(Sample::mCtx, nullptr); +} + +auto Sample::Info(mozilla::jni::Object::Param a0) const -> void +{ + return mozilla::jni::Field<Info_t>::Set(Sample::mCtx, nullptr, a0); +} + +const char SessionKeyInfo::name[] = + "org/mozilla/gecko/media/SessionKeyInfo"; + +constexpr char SessionKeyInfo::New_t::name[]; +constexpr char SessionKeyInfo::New_t::signature[]; + +auto SessionKeyInfo::New(mozilla::jni::ByteArray::Param a0, int32_t a1) -> SessionKeyInfo::LocalRef +{ + return mozilla::jni::Constructor<New_t>::Call(SessionKeyInfo::Context(), nullptr, a0, a1); +} + +constexpr char SessionKeyInfo::KeyId_t::name[]; +constexpr char SessionKeyInfo::KeyId_t::signature[]; + +auto SessionKeyInfo::KeyId() const -> mozilla::jni::ByteArray::LocalRef +{ + return mozilla::jni::Field<KeyId_t>::Get(SessionKeyInfo::mCtx, nullptr); +} + +auto SessionKeyInfo::KeyId(mozilla::jni::ByteArray::Param a0) const -> void +{ + return mozilla::jni::Field<KeyId_t>::Set(SessionKeyInfo::mCtx, nullptr, a0); +} + +constexpr char SessionKeyInfo::Status_t::name[]; +constexpr char SessionKeyInfo::Status_t::signature[]; + +auto SessionKeyInfo::Status() const -> int32_t +{ + return mozilla::jni::Field<Status_t>::Get(SessionKeyInfo::mCtx, nullptr); +} + +auto SessionKeyInfo::Status(int32_t a0) const -> void +{ + return mozilla::jni::Field<Status_t>::Set(SessionKeyInfo::mCtx, nullptr, a0); +} + +const char Restrictions::name[] = + "org/mozilla/gecko/restrictions/Restrictions"; + +constexpr char Restrictions::IsAllowed_t::name[]; +constexpr char Restrictions::IsAllowed_t::signature[]; + +auto Restrictions::IsAllowed(int32_t a0, mozilla::jni::String::Param a1) -> bool +{ + return mozilla::jni::Method<IsAllowed_t>::Call(Restrictions::Context(), nullptr, a0, a1); +} + +constexpr char Restrictions::IsUserRestricted_t::name[]; +constexpr char Restrictions::IsUserRestricted_t::signature[]; + +auto Restrictions::IsUserRestricted() -> bool +{ + return mozilla::jni::Method<IsUserRestricted_t>::Call(Restrictions::Context(), nullptr); +} + +} /* java */ +} /* mozilla */ diff --git a/widget/android/fennec/FennecJNIWrappers.h b/widget/android/fennec/FennecJNIWrappers.h new file mode 100644 index 000000000..bb94cd142 --- /dev/null +++ b/widget/android/fennec/FennecJNIWrappers.h @@ -0,0 +1,1469 @@ +// GENERATED CODE +// Generated by the Java program at /build/annotationProcessors at compile time +// from annotations on Java methods. To update, change the annotations on the +// corresponding Java methods and rerun the build. Manually updating this file +// will cause your build to fail. + +#ifndef FennecJNIWrappers_h +#define FennecJNIWrappers_h + +#include "mozilla/jni/Refs.h" + +namespace mozilla { +namespace java { + +class ANRReporter : public mozilla::jni::ObjectBase<ANRReporter> +{ +public: + static const char name[]; + + explicit ANRReporter(const Context& ctx) : ObjectBase<ANRReporter>(ctx) {} + + struct GetNativeStack_t { + typedef ANRReporter Owner; + typedef mozilla::jni::String::LocalRef ReturnType; + typedef mozilla::jni::String::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getNativeStack"; + static constexpr char signature[] = + "()Ljava/lang/String;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct ReleaseNativeStack_t { + typedef ANRReporter Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "releaseNativeStack"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct RequestNativeStack_t { + typedef ANRReporter Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + bool> Args; + static constexpr char name[] = "requestNativeStack"; + static constexpr char signature[] = + "(Z)Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class DownloadsIntegration : public mozilla::jni::ObjectBase<DownloadsIntegration> +{ +public: + static const char name[]; + + explicit DownloadsIntegration(const Context& ctx) : ObjectBase<DownloadsIntegration>(ctx) {} + + struct GetTemporaryDownloadDirectory_t { + typedef DownloadsIntegration Owner; + typedef mozilla::jni::String::LocalRef ReturnType; + typedef mozilla::jni::String::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getTemporaryDownloadDirectory"; + static constexpr char signature[] = + "()Ljava/lang/String;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetTemporaryDownloadDirectory() -> mozilla::jni::String::LocalRef; + + struct ScanMedia_t { + typedef DownloadsIntegration Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "scanMedia"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto ScanMedia(mozilla::jni::String::Param, mozilla::jni::String::Param) -> void; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + +}; + +class GeckoJavaSampler : public mozilla::jni::ObjectBase<GeckoJavaSampler> +{ +public: + static const char name[]; + + explicit GeckoJavaSampler(const Context& ctx) : ObjectBase<GeckoJavaSampler>(ctx) {} + + struct GetFrameName_t { + typedef GeckoJavaSampler Owner; + typedef mozilla::jni::String::LocalRef ReturnType; + typedef mozilla::jni::String::Param SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + int32_t> Args; + static constexpr char name[] = "getFrameName"; + static constexpr char signature[] = + "(III)Ljava/lang/String;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetFrameName(int32_t, int32_t, int32_t) -> mozilla::jni::String::LocalRef; + + struct GetProfilerTime_t { + typedef GeckoJavaSampler Owner; + typedef double ReturnType; + typedef double SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "getProfilerTime"; + static constexpr char signature[] = + "()D"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct GetSampleTime_t { + typedef GeckoJavaSampler Owner; + typedef double ReturnType; + typedef double SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t> Args; + static constexpr char name[] = "getSampleTime"; + static constexpr char signature[] = + "(II)D"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetSampleTime(int32_t, int32_t) -> double; + + struct GetThreadName_t { + typedef GeckoJavaSampler Owner; + typedef mozilla::jni::String::LocalRef ReturnType; + typedef mozilla::jni::String::Param SetterType; + typedef mozilla::jni::Args< + int32_t> Args; + static constexpr char name[] = "getThreadName"; + static constexpr char signature[] = + "(I)Ljava/lang/String;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto GetThreadName(int32_t) -> mozilla::jni::String::LocalRef; + + struct Pause_t { + typedef GeckoJavaSampler Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "pause"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto Pause() -> void; + + struct Start_t { + typedef GeckoJavaSampler Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t> Args; + static constexpr char name[] = "start"; + static constexpr char signature[] = + "(II)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto Start(int32_t, int32_t) -> void; + + struct Stop_t { + typedef GeckoJavaSampler Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "stop"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto Stop() -> void; + + struct Unpause_t { + typedef GeckoJavaSampler Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "unpause"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto Unpause() -> void; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class MemoryMonitor : public mozilla::jni::ObjectBase<MemoryMonitor> +{ +public: + static const char name[]; + + explicit MemoryMonitor(const Context& ctx) : ObjectBase<MemoryMonitor>(ctx) {} + + struct DispatchMemoryPressure_t { + typedef MemoryMonitor Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "dispatchMemoryPressure"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + + template<class Impl> class Natives; +}; + +class PresentationMediaPlayerManager : public mozilla::jni::ObjectBase<PresentationMediaPlayerManager> +{ +public: + static const char name[]; + + explicit PresentationMediaPlayerManager(const Context& ctx) : ObjectBase<PresentationMediaPlayerManager>(ctx) {} + + struct AddPresentationSurface_t { + typedef PresentationMediaPlayerManager Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param, + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "addPresentationSurface"; + static constexpr char signature[] = + "(Lorg/mozilla/gecko/GeckoView;Landroid/view/Surface;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct InvalidateAndScheduleComposite_t { + typedef PresentationMediaPlayerManager Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "invalidateAndScheduleComposite"; + static constexpr char signature[] = + "(Lorg/mozilla/gecko/GeckoView;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct RemovePresentationSurface_t { + typedef PresentationMediaPlayerManager Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "removePresentationSurface"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::UI; + + template<class Impl> class Natives; +}; + +class ScreenManagerHelper : public mozilla::jni::ObjectBase<ScreenManagerHelper> +{ +public: + static const char name[]; + + explicit ScreenManagerHelper(const Context& ctx) : ObjectBase<ScreenManagerHelper>(ctx) {} + + struct AddDisplay_t { + typedef ScreenManagerHelper Owner; + typedef int32_t ReturnType; + typedef int32_t SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + int32_t, + float> Args; + static constexpr char name[] = "addDisplay"; + static constexpr char signature[] = + "(IIIF)I"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct RemoveDisplay_t { + typedef ScreenManagerHelper Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t> Args; + static constexpr char name[] = "removeDisplay"; + static constexpr char signature[] = + "(I)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class Telemetry : public mozilla::jni::ObjectBase<Telemetry> +{ +public: + static const char name[]; + + explicit Telemetry(const Context& ctx) : ObjectBase<Telemetry>(ctx) {} + + struct AddHistogram_t { + typedef Telemetry Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + int32_t> Args; + static constexpr char name[] = "nativeAddHistogram"; + static constexpr char signature[] = + "(Ljava/lang/String;I)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct AddKeyedHistogram_t { + typedef Telemetry Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param, + int32_t> Args; + static constexpr char name[] = "nativeAddKeyedHistogram"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;I)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct AddUIEvent_t { + typedef Telemetry Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param, + int64_t, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "nativeAddUiEvent"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;JLjava/lang/String;)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct StartUISession_t { + typedef Telemetry Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + int64_t> Args; + static constexpr char name[] = "nativeStartUiSession"; + static constexpr char signature[] = + "(Ljava/lang/String;J)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct StopUISession_t { + typedef Telemetry Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param, + int64_t> Args; + static constexpr char name[] = "nativeStopUiSession"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;J)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class ThumbnailHelper : public mozilla::jni::ObjectBase<ThumbnailHelper> +{ +public: + static const char name[]; + + explicit ThumbnailHelper(const Context& ctx) : ObjectBase<ThumbnailHelper>(ctx) {} + + struct NotifyThumbnail_t { + typedef ThumbnailHelper Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::ByteBuffer::Param, + mozilla::jni::Object::Param, + bool, + bool> Args; + static constexpr char name[] = "notifyThumbnail"; + static constexpr char signature[] = + "(Ljava/nio/ByteBuffer;Lorg/mozilla/gecko/Tab;ZZ)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto NotifyThumbnail(mozilla::jni::ByteBuffer::Param, mozilla::jni::Object::Param, bool, bool) -> void; + + struct RequestThumbnail_t { + typedef ThumbnailHelper Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::ByteBuffer::Param, + mozilla::jni::Object::Param, + int32_t, + int32_t, + int32_t> Args; + static constexpr char name[] = "requestThumbnailLocked"; + static constexpr char signature[] = + "(Ljava/nio/ByteBuffer;Lorg/mozilla/gecko/Tab;III)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::PROXY; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class ZoomedView : public mozilla::jni::ObjectBase<ZoomedView> +{ +public: + static const char name[]; + + explicit ZoomedView(const Context& ctx) : ObjectBase<ZoomedView>(ctx) {} + + struct RequestZoomedViewData_t { + typedef ZoomedView Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::ByteBuffer::Param, + int32_t, + int32_t, + int32_t, + int32_t, + int32_t, + float> Args; + static constexpr char name[] = "requestZoomedViewData"; + static constexpr char signature[] = + "(Ljava/nio/ByteBuffer;IIIIIF)V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class AudioFocusAgent : public mozilla::jni::ObjectBase<AudioFocusAgent> +{ +public: + static const char name[]; + + explicit AudioFocusAgent(const Context& ctx) : ObjectBase<AudioFocusAgent>(ctx) {} + + struct NotifyStartedPlaying_t { + typedef AudioFocusAgent Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "notifyStartedPlaying"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto NotifyStartedPlaying() -> void; + + struct NotifyStoppedPlaying_t { + typedef AudioFocusAgent Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "notifyStoppedPlaying"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto NotifyStoppedPlaying() -> void; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + +}; + +class CodecProxy : public mozilla::jni::ObjectBase<CodecProxy> +{ +public: + static const char name[]; + + explicit CodecProxy(const Context& ctx) : ObjectBase<CodecProxy>(ctx) {} + + class NativeCallbacks; + + struct Create_t { + typedef CodecProxy Owner; + typedef CodecProxy::LocalRef ReturnType; + typedef CodecProxy::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param, + mozilla::jni::Object::Param, + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "create"; + static constexpr char signature[] = + "(Landroid/media/MediaFormat;Landroid/view/Surface;Lorg/mozilla/gecko/media/CodecProxy$Callbacks;)Lorg/mozilla/gecko/media/CodecProxy;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto Create(mozilla::jni::Object::Param, mozilla::jni::Object::Param, mozilla::jni::Object::Param) -> CodecProxy::LocalRef; + + struct Flush_t { + typedef CodecProxy Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "flush"; + static constexpr char signature[] = + "()Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Flush() const -> bool; + + struct Input_t { + typedef CodecProxy Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + mozilla::jni::ByteBuffer::Param, + mozilla::jni::Object::Param, + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "input"; + static constexpr char signature[] = + "(Ljava/nio/ByteBuffer;Landroid/media/MediaCodec$BufferInfo;Landroid/media/MediaCodec$CryptoInfo;)Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Input(mozilla::jni::ByteBuffer::Param, mozilla::jni::Object::Param, mozilla::jni::Object::Param) const -> bool; + + struct Release_t { + typedef CodecProxy Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "release"; + static constexpr char signature[] = + "()Z"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Release() const -> bool; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + +}; + +class CodecProxy::NativeCallbacks : public mozilla::jni::ObjectBase<NativeCallbacks> +{ +public: + static const char name[]; + + explicit NativeCallbacks(const Context& ctx) : ObjectBase<NativeCallbacks>(ctx) {} + + struct New_t { + typedef NativeCallbacks Owner; + typedef NativeCallbacks::LocalRef ReturnType; + typedef NativeCallbacks::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "<init>"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto New() -> NativeCallbacks::LocalRef; + + struct DisposeNative_t { + typedef NativeCallbacks Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "disposeNative"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OnError_t { + typedef NativeCallbacks Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + bool> Args; + static constexpr char name[] = "onError"; + static constexpr char signature[] = + "(Z)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OnInputExhausted_t { + typedef NativeCallbacks Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "onInputExhausted"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OnOutput_t { + typedef NativeCallbacks Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "onOutput"; + static constexpr char signature[] = + "(Lorg/mozilla/gecko/media/Sample;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + struct OnOutputFormatChanged_t { + typedef NativeCallbacks Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "onOutputFormatChanged"; + static constexpr char signature[] = + "(Landroid/media/MediaFormat;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class MediaDrmProxy : public mozilla::jni::ObjectBase<MediaDrmProxy> +{ +public: + static const char name[]; + + explicit MediaDrmProxy(const Context& ctx) : ObjectBase<MediaDrmProxy>(ctx) {} + + class NativeMediaDrmProxyCallbacks; + + struct CanDecode_t { + typedef MediaDrmProxy Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "CanDecode"; + static constexpr char signature[] = + "(Ljava/lang/String;)Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto CanDecode(mozilla::jni::String::Param) -> bool; + + struct IsCryptoSchemeSupported_t { + typedef MediaDrmProxy Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "IsCryptoSchemeSupported"; + static constexpr char signature[] = + "(Ljava/lang/String;Ljava/lang/String;)Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto IsCryptoSchemeSupported(mozilla::jni::String::Param, mozilla::jni::String::Param) -> bool; + + struct CloseSession_t { + typedef MediaDrmProxy Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "closeSession"; + static constexpr char signature[] = + "(ILjava/lang/String;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto CloseSession(int32_t, mozilla::jni::String::Param) const -> void; + + struct Create_t { + typedef MediaDrmProxy Owner; + typedef MediaDrmProxy::LocalRef ReturnType; + typedef MediaDrmProxy::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param, + mozilla::jni::Object::Param, + bool> Args; + static constexpr char name[] = "create"; + static constexpr char signature[] = + "(Ljava/lang/String;Lorg/mozilla/gecko/media/MediaDrmProxy$Callbacks;Z)Lorg/mozilla/gecko/media/MediaDrmProxy;"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto Create(mozilla::jni::String::Param, mozilla::jni::Object::Param, bool) -> MediaDrmProxy::LocalRef; + + struct CreateSession_t { + typedef MediaDrmProxy Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + mozilla::jni::String::Param, + mozilla::jni::ByteArray::Param> Args; + static constexpr char name[] = "createSession"; + static constexpr char signature[] = + "(IILjava/lang/String;[B)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto CreateSession(int32_t, int32_t, mozilla::jni::String::Param, mozilla::jni::ByteArray::Param) const -> void; + + struct Destroy_t { + typedef MediaDrmProxy Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "destroy"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Destroy() const -> void; + + struct IsSchemeSupported_t { + typedef MediaDrmProxy Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + mozilla::jni::String::Param> Args; + static constexpr char name[] = "isSchemeSupported"; + static constexpr char signature[] = + "(Ljava/lang/String;)Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto IsSchemeSupported(mozilla::jni::String::Param) -> bool; + + struct UpdateSession_t { + typedef MediaDrmProxy Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + mozilla::jni::String::Param, + mozilla::jni::ByteArray::Param> Args; + static constexpr char name[] = "updateSession"; + static constexpr char signature[] = + "(ILjava/lang/String;[B)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto UpdateSession(int32_t, mozilla::jni::String::Param, mozilla::jni::ByteArray::Param) const -> void; + + static const char16_t AAC[]; + + static const char16_t AVC[]; + + static const char16_t OPUS[]; + + static const char16_t VORBIS[]; + + static const char16_t VP8[]; + + static const char16_t VP9[]; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + +}; + +class MediaDrmProxy::NativeMediaDrmProxyCallbacks : public mozilla::jni::ObjectBase<NativeMediaDrmProxyCallbacks> +{ +public: + static const char name[]; + + explicit NativeMediaDrmProxyCallbacks(const Context& ctx) : ObjectBase<NativeMediaDrmProxyCallbacks>(ctx) {} + + struct New_t { + typedef NativeMediaDrmProxyCallbacks Owner; + typedef NativeMediaDrmProxyCallbacks::LocalRef ReturnType; + typedef NativeMediaDrmProxyCallbacks::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "<init>"; + static constexpr char signature[] = + "()V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto New() -> NativeMediaDrmProxyCallbacks::LocalRef; + + struct OnRejectPromise_t { + typedef NativeMediaDrmProxyCallbacks Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "onRejectPromise"; + static constexpr char signature[] = + "(ILjava/lang/String;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct OnSessionBatchedKeyChanged_t { + typedef NativeMediaDrmProxyCallbacks Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::ByteArray::Param, + mozilla::jni::ObjectArray::Param> Args; + static constexpr char name[] = "onSessionBatchedKeyChanged"; + static constexpr char signature[] = + "([B[Lorg/mozilla/gecko/media/SessionKeyInfo;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct OnSessionClosed_t { + typedef NativeMediaDrmProxyCallbacks Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + mozilla::jni::ByteArray::Param> Args; + static constexpr char name[] = "onSessionClosed"; + static constexpr char signature[] = + "(I[B)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct OnSessionCreated_t { + typedef NativeMediaDrmProxyCallbacks Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + int32_t, + mozilla::jni::ByteArray::Param, + mozilla::jni::ByteArray::Param> Args; + static constexpr char name[] = "onSessionCreated"; + static constexpr char signature[] = + "(II[B[B)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct OnSessionError_t { + typedef NativeMediaDrmProxyCallbacks Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::ByteArray::Param, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "onSessionError"; + static constexpr char signature[] = + "([BLjava/lang/String;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct OnSessionMessage_t { + typedef NativeMediaDrmProxyCallbacks Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::ByteArray::Param, + int32_t, + mozilla::jni::ByteArray::Param> Args; + static constexpr char name[] = "onSessionMessage"; + static constexpr char signature[] = + "([BI[B)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + struct OnSessionUpdated_t { + typedef NativeMediaDrmProxyCallbacks Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + int32_t, + mozilla::jni::ByteArray::Param> Args; + static constexpr char name[] = "onSessionUpdated"; + static constexpr char signature[] = + "(I[B)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::GECKO; + }; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + + template<class Impl> class Natives; +}; + +class Sample : public mozilla::jni::ObjectBase<Sample> +{ +public: + static const char name[]; + + explicit Sample(const Context& ctx) : ObjectBase<Sample>(ctx) {} + + struct WriteToByteBuffer_t { + typedef Sample Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::ByteBuffer::Param> Args; + static constexpr char name[] = "writeToByteBuffer"; + static constexpr char signature[] = + "(Ljava/nio/ByteBuffer;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto WriteToByteBuffer(mozilla::jni::ByteBuffer::Param) const -> void; + + struct Info_t { + typedef Sample Owner; + typedef mozilla::jni::Object::LocalRef ReturnType; + typedef mozilla::jni::Object::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "info"; + static constexpr char signature[] = + "Landroid/media/MediaCodec$BufferInfo;"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Info() const -> mozilla::jni::Object::LocalRef; + + auto Info(mozilla::jni::Object::Param) const -> void; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + +}; + +class SessionKeyInfo : public mozilla::jni::ObjectBase<SessionKeyInfo> +{ +public: + static const char name[]; + + explicit SessionKeyInfo(const Context& ctx) : ObjectBase<SessionKeyInfo>(ctx) {} + + struct New_t { + typedef SessionKeyInfo Owner; + typedef SessionKeyInfo::LocalRef ReturnType; + typedef SessionKeyInfo::Param SetterType; + typedef mozilla::jni::Args< + mozilla::jni::ByteArray::Param, + int32_t> Args; + static constexpr char name[] = "<init>"; + static constexpr char signature[] = + "([BI)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto New(mozilla::jni::ByteArray::Param, int32_t) -> SessionKeyInfo::LocalRef; + + struct KeyId_t { + typedef SessionKeyInfo Owner; + typedef mozilla::jni::ByteArray::LocalRef ReturnType; + typedef mozilla::jni::ByteArray::Param SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "keyId"; + static constexpr char signature[] = + "[B"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto KeyId() const -> mozilla::jni::ByteArray::LocalRef; + + auto KeyId(mozilla::jni::ByteArray::Param) const -> void; + + struct Status_t { + typedef SessionKeyInfo Owner; + typedef int32_t ReturnType; + typedef int32_t SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "status"; + static constexpr char signature[] = + "I"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto Status() const -> int32_t; + + auto Status(int32_t) const -> void; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + +}; + +class Restrictions : public mozilla::jni::ObjectBase<Restrictions> +{ +public: + static const char name[]; + + explicit Restrictions(const Context& ctx) : ObjectBase<Restrictions>(ctx) {} + + struct IsAllowed_t { + typedef Restrictions Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args< + int32_t, + mozilla::jni::String::Param> Args; + static constexpr char name[] = "isAllowed"; + static constexpr char signature[] = + "(ILjava/lang/String;)Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto IsAllowed(int32_t, mozilla::jni::String::Param) -> bool; + + struct IsUserRestricted_t { + typedef Restrictions Owner; + typedef bool ReturnType; + typedef bool SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "isUserRestricted"; + static constexpr char signature[] = + "()Z"; + static const bool isStatic = true; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + static auto IsUserRestricted() -> bool; + + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + +}; + +} /* java */ +} /* mozilla */ +#endif // FennecJNIWrappers_h diff --git a/widget/android/fennec/MemoryMonitor.h b/widget/android/fennec/MemoryMonitor.h new file mode 100644 index 000000000..c87538424 --- /dev/null +++ b/widget/android/fennec/MemoryMonitor.h @@ -0,0 +1,27 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 MemoryMonitor_h +#define MemoryMonitor_h + +#include "FennecJNINatives.h" +#include "nsMemoryPressure.h" + +namespace mozilla { + +class MemoryMonitor final + : public java::MemoryMonitor::Natives<MemoryMonitor> +{ +public: + static void + DispatchMemoryPressure() + { + NS_DispatchMemoryPressure(MemoryPressureState::MemPressure_New); + } +}; + +} // namespace mozilla + +#endif // MemoryMonitor_h diff --git a/widget/android/fennec/Telemetry.h b/widget/android/fennec/Telemetry.h new file mode 100644 index 000000000..c72735496 --- /dev/null +++ b/widget/android/fennec/Telemetry.h @@ -0,0 +1,100 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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_widget_Telemetry_h__ +#define mozilla_widget_Telemetry_h__ + +#include "FennecJNINatives.h" +#include "nsAppShell.h" +#include "nsIAndroidBridge.h" + +#include "mozilla/Telemetry.h" + +namespace mozilla { +namespace widget { + +class Telemetry final + : public java::Telemetry::Natives<Telemetry> +{ + Telemetry() = delete; + + static already_AddRefed<nsIUITelemetryObserver> + GetObserver() + { + nsAppShell* const appShell = nsAppShell::Get(); + if (!appShell) { + return nullptr; + } + + nsCOMPtr<nsIAndroidBrowserApp> browserApp = appShell->GetBrowserApp(); + nsCOMPtr<nsIUITelemetryObserver> obs; + + if (!browserApp || NS_FAILED(browserApp->GetUITelemetryObserver( + getter_AddRefs(obs))) || !obs) { + return nullptr; + } + + return obs.forget(); + } + +public: + static void + AddHistogram(jni::String::Param aName, int32_t aValue) + { + MOZ_ASSERT(aName); + mozilla::Telemetry::Accumulate(aName->ToCString().get(), aValue); + } + + static void + AddKeyedHistogram(jni::String::Param aName, jni::String::Param aKey, + int32_t aValue) + { + MOZ_ASSERT(aName && aKey); + mozilla::Telemetry::Accumulate(aName->ToCString().get(), + aKey->ToCString(), aValue); + } + + static void + StartUISession(jni::String::Param aName, int64_t aTimestamp) + { + MOZ_ASSERT(aName); + nsCOMPtr<nsIUITelemetryObserver> obs = GetObserver(); + if (obs) { + obs->StartSession(aName->ToString().get(), aTimestamp); + } + } + + static void + StopUISession(jni::String::Param aName, jni::String::Param aReason, + int64_t aTimestamp) + { + MOZ_ASSERT(aName); + nsCOMPtr<nsIUITelemetryObserver> obs = GetObserver(); + if (obs) { + obs->StopSession(aName->ToString().get(), + aReason ? aReason->ToString().get() : nullptr, + aTimestamp); + } + } + + static void + AddUIEvent(jni::String::Param aAction, jni::String::Param aMethod, + int64_t aTimestamp, jni::String::Param aExtras) + { + MOZ_ASSERT(aAction); + nsCOMPtr<nsIUITelemetryObserver> obs = GetObserver(); + if (obs) { + obs->AddEvent(aAction->ToString().get(), + aMethod ? aMethod->ToString().get() : nullptr, + aTimestamp, + aExtras ? aExtras->ToString().get() : nullptr); + } + } +}; + +} // namespace widget +} // namespace mozilla + +#endif // mozilla_widget_Telemetry_h__ diff --git a/widget/android/fennec/ThumbnailHelper.h b/widget/android/fennec/ThumbnailHelper.h new file mode 100644 index 000000000..08fae787e --- /dev/null +++ b/widget/android/fennec/ThumbnailHelper.h @@ -0,0 +1,302 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 ThumbnailHelper_h +#define ThumbnailHelper_h + +#include "AndroidBridge.h" +#include "FennecJNINatives.h" +#include "gfxPlatform.h" +#include "mozIDOMWindow.h" +#include "nsAppShell.h" +#include "nsCOMPtr.h" +#include "nsIChannel.h" +#include "nsIDOMWindowUtils.h" +#include "nsIDOMClientRect.h" +#include "nsIDocShell.h" +#include "nsIHttpChannel.h" +#include "nsIPresShell.h" +#include "nsIURI.h" +#include "nsPIDOMWindow.h" +#include "nsPresContext.h" + +#include "mozilla/Preferences.h" + +namespace mozilla { + +class ThumbnailHelper final + : public java::ThumbnailHelper::Natives<ThumbnailHelper> + , public java::ZoomedView::Natives<ThumbnailHelper> +{ + ThumbnailHelper() = delete; + + static already_AddRefed<mozIDOMWindowProxy> + GetWindowForTab(int32_t aTabId) + { + nsAppShell* const appShell = nsAppShell::Get(); + if (!appShell) { + return nullptr; + } + + nsCOMPtr<nsIAndroidBrowserApp> browserApp = appShell->GetBrowserApp(); + if (!browserApp) { + return nullptr; + } + + nsCOMPtr<mozIDOMWindowProxy> window; + nsCOMPtr<nsIBrowserTab> tab; + + if (NS_FAILED(browserApp->GetBrowserTab(aTabId, getter_AddRefs(tab))) || + !tab || + NS_FAILED(tab->GetWindow(getter_AddRefs(window))) || + !window) { + return nullptr; + } + + return window.forget(); + } + + // Decides if we should store thumbnails for a given docshell based on the + // presence of a Cache-Control: no-store header and the + // "browser.cache.disk_cache_ssl" pref. + static bool + ShouldStoreThumbnail(nsIDocShell* docShell) + { + nsCOMPtr<nsIChannel> channel; + if (NS_FAILED(docShell->GetCurrentDocumentChannel( + getter_AddRefs(channel))) || !channel) { + return false; + } + + nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel); + if (!httpChannel) { + // Allow storing non-HTTP thumbnails. + return true; + } + + // Don't store thumbnails for sites that didn't load or have + // Cache-Control: no-store. + uint32_t responseStatus = 0; + bool isNoStoreResponse = false; + + if (NS_FAILED(httpChannel->GetResponseStatus(&responseStatus)) || + (responseStatus / 100) != 2 || + NS_FAILED(httpChannel->IsNoStoreResponse(&isNoStoreResponse)) || + isNoStoreResponse) { + return false; + } + + // Deny storage if we're viewing a HTTPS page with a 'Cache-Control' + // header having a value that is not 'public', unless enabled by user. + nsCOMPtr<nsIURI> uri; + bool isHttps = false; + + if (NS_FAILED(channel->GetURI(getter_AddRefs(uri))) || + !uri || + NS_FAILED(uri->SchemeIs("https", &isHttps))) { + return false; + } + + if (!isHttps || + Preferences::GetBool("browser.cache.disk_cache_ssl", false)) { + // Allow storing non-HTTPS thumbnails, and HTTPS ones if enabled by + // user. + return true; + } + + nsAutoCString cacheControl; + if (NS_FAILED(httpChannel->GetResponseHeader( + NS_LITERAL_CSTRING("Cache-Control"), cacheControl))) { + return false; + } + + if (cacheControl.IsEmpty() || + cacheControl.LowerCaseEqualsLiteral("public")) { + // Allow no cache-control, or public cache-control. + return true; + } + return false; + } + + // Return a non-null nsIDocShell to indicate success. + static already_AddRefed<nsIDocShell> + GetThumbnailAndDocShell(mozIDOMWindowProxy* aWindow, + jni::ByteBuffer::Param aData, + int32_t aThumbWidth, int32_t aThumbHeight, + const CSSRect& aPageRect, float aZoomFactor) + { + nsCOMPtr<nsPIDOMWindowOuter> win = nsPIDOMWindowOuter::From(aWindow); + nsCOMPtr<nsIDocShell> docShell = win->GetDocShell(); + RefPtr<nsPresContext> presContext; + + if (!docShell || NS_FAILED(docShell->GetPresContext( + getter_AddRefs(presContext))) || !presContext) { + return nullptr; + } + + uint8_t* const data = static_cast<uint8_t*>(aData->Address()); + if (!data) { + return nullptr; + } + + const bool is24bit = !AndroidBridge::Bridge() || + AndroidBridge::Bridge()->GetScreenDepth() == 24; + const uint32_t stride = aThumbWidth * (is24bit ? 4 : 2); + + RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->CreateDrawTargetForData( + data, + IntSize(aThumbWidth, aThumbHeight), + stride, + is24bit ? SurfaceFormat::B8G8R8A8 + : SurfaceFormat::R5G6B5_UINT16); + + if (!dt || !dt->IsValid()) { + return nullptr; + } + + nsCOMPtr<nsIPresShell> presShell = presContext->PresShell(); + RefPtr<gfxContext> context = gfxContext::CreateOrNull(dt); + MOZ_ASSERT(context); // checked the draw target above + + context->SetMatrix(context->CurrentMatrix().Scale( + aZoomFactor * float(aThumbWidth) / aPageRect.width, + aZoomFactor * float(aThumbHeight) / aPageRect.height)); + + const nsRect drawRect( + nsPresContext::CSSPixelsToAppUnits(aPageRect.x), + nsPresContext::CSSPixelsToAppUnits(aPageRect.y), + nsPresContext::CSSPixelsToAppUnits(aPageRect.width), + nsPresContext::CSSPixelsToAppUnits(aPageRect.height)); + const uint32_t renderDocFlags = + nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING | + nsIPresShell::RENDER_DOCUMENT_RELATIVE; + const nscolor bgColor = NS_RGB(255, 255, 255); + + if (NS_FAILED(presShell->RenderDocument( + drawRect, renderDocFlags, bgColor, context))) { + return nullptr; + } + + if (is24bit) { + gfxUtils::ConvertBGRAtoRGBA(data, stride * aThumbHeight); + } + + return docShell.forget(); + } + +public: + static void Init() + { + java::ThumbnailHelper::Natives<ThumbnailHelper>::Init(); + java::ZoomedView::Natives<ThumbnailHelper>::Init(); + } + + template<class Functor> + static void OnNativeCall(Functor&& aCall) + { + class IdleEvent : public nsAppShell::LambdaEvent<Functor> + { + using Base = nsAppShell::LambdaEvent<Functor>; + + public: + IdleEvent(Functor&& aCall) + : Base(Forward<Functor>(aCall)) + {} + + void Run() override + { + MessageLoop::current()->PostIdleTask( + NS_NewRunnableFunction(Move(Base::lambda))); + } + }; + + // Invoke RequestThumbnail on the main thread when the thread is idle. + nsAppShell::PostEvent(MakeUnique<IdleEvent>(Forward<Functor>(aCall))); + } + + static void + RequestThumbnail(jni::ByteBuffer::Param aData, jni::Object::Param aTab, + int32_t aTabId, int32_t aWidth, int32_t aHeight) + { + nsCOMPtr<mozIDOMWindowProxy> window = GetWindowForTab(aTabId); + if (!window || !aData) { + java::ThumbnailHelper::NotifyThumbnail( + aData, aTab, /* success */ false, /* store */ false); + return; + } + + // take a screenshot, as wide as possible, proportional to the destination size + nsCOMPtr<nsIDOMWindowUtils> utils = do_GetInterface(window); + nsCOMPtr<nsIDOMClientRect> rect; + float pageLeft = 0.0f, pageTop = 0.0f, pageWidth = 0.0f, pageHeight = 0.0f; + + if (!utils || + NS_FAILED(utils->GetRootBounds(getter_AddRefs(rect))) || + !rect || + NS_FAILED(rect->GetLeft(&pageLeft)) || + NS_FAILED(rect->GetTop(&pageTop)) || + NS_FAILED(rect->GetWidth(&pageWidth)) || + NS_FAILED(rect->GetHeight(&pageHeight)) || + int32_t(pageWidth) == 0 || int32_t(pageHeight) == 0) { + java::ThumbnailHelper::NotifyThumbnail( + aData, aTab, /* success */ false, /* store */ false); + return; + } + + const float aspectRatio = float(aWidth) / float(aHeight); + if (pageWidth / aspectRatio < pageHeight) { + pageHeight = pageWidth / aspectRatio; + } else { + pageWidth = pageHeight * aspectRatio; + } + + nsCOMPtr<nsIDocShell> docShell = GetThumbnailAndDocShell( + window, aData, aWidth, aHeight, + CSSRect(pageLeft, pageTop, pageWidth, pageHeight), + /* aZoomFactor */ 1.0f); + const bool success = !!docShell; + const bool store = success ? ShouldStoreThumbnail(docShell) : false; + + java::ThumbnailHelper::NotifyThumbnail(aData, aTab, success, store); + } + + static void + RequestZoomedViewData(jni::ByteBuffer::Param aData, int32_t aTabId, + int32_t aX, int32_t aY, + int32_t aWidth, int32_t aHeight, float aScale) + { + nsCOMPtr<mozIDOMWindowProxy> window = GetWindowForTab(aTabId); + if (!window || !aData) { + return; + } + + nsCOMPtr<nsPIDOMWindowOuter> win = nsPIDOMWindowOuter::From(window); + nsCOMPtr<nsIDocShell> docShell = win->GetDocShell(); + RefPtr<nsPresContext> presContext; + + if (!docShell || NS_FAILED(docShell->GetPresContext( + getter_AddRefs(presContext))) || !presContext) { + return; + } + + nsCOMPtr<nsIPresShell> presShell = presContext->PresShell(); + LayoutDeviceRect rect = LayoutDeviceRect(aX, aY, aWidth, aHeight); + const float resolution = presShell->GetCumulativeResolution(); + rect.Scale(1.0f / LayoutDeviceToLayerScale(resolution).scale); + + docShell = GetThumbnailAndDocShell( + window, aData, aWidth, aHeight, CSSRect::FromAppUnits( + rect.ToAppUnits(rect, presContext->AppUnitsPerDevPixel())), + aScale); + + if (docShell) { + java::LayerView::UpdateZoomedView(aData); + } + } +}; + +} // namespace mozilla + +#endif // ThumbnailHelper_h diff --git a/widget/android/fennec/moz.build b/widget/android/fennec/moz.build new file mode 100644 index 000000000..0d6a8e0cd --- /dev/null +++ b/widget/android/fennec/moz.build @@ -0,0 +1,21 @@ +# -*- 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 += [ + 'FennecJNINatives.h', + 'FennecJNIWrappers.h', +] + +UNIFIED_SOURCES += [ + 'FennecJNIWrappers.cpp', +] + +FINAL_LIBRARY = 'xul' + +LOCAL_INCLUDES += [ + '/widget', + '/widget/android', +] diff --git a/widget/android/jni/Accessors.h b/widget/android/jni/Accessors.h new file mode 100644 index 000000000..fe2cbc9d4 --- /dev/null +++ b/widget/android/jni/Accessors.h @@ -0,0 +1,274 @@ +#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 new file mode 100644 index 000000000..511d96a87 --- /dev/null +++ b/widget/android/jni/Natives.h @@ -0,0 +1,707 @@ +#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 new file mode 100644 index 000000000..9f54ee5cd --- /dev/null +++ b/widget/android/jni/Refs.h @@ -0,0 +1,953 @@ +#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 new file mode 100644 index 000000000..a083d3e50 --- /dev/null +++ b/widget/android/jni/Types.h @@ -0,0 +1,140 @@ +#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 new file mode 100644 index 000000000..145f7e9ea --- /dev/null +++ b/widget/android/jni/Utils.cpp @@ -0,0 +1,301 @@ +#include "Utils.h" +#include "Types.h" + +#include <android/log.h> +#include <pthread.h> + +#include "mozilla/Assertions.h" + +#include "GeneratedJNIWrappers.h" +#include "nsAppShell.h" + +#ifdef MOZ_CRASHREPORTER +#include "nsExceptionHandler.h" +#endif + +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; + +#ifdef MOZ_CRASHREPORTER + result &= NS_SUCCEEDED(CrashReporter::AnnotateCrashReport( + NS_LITERAL_CSTRING("JavaStackTrace"), + String::Ref::From(aStack)->ToCString())); +#endif // MOZ_CRASHREPORTER + + 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 new file mode 100644 index 000000000..38e0b6b0c --- /dev/null +++ b/widget/android/jni/Utils.h @@ -0,0 +1,147 @@ +#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 new file mode 100644 index 000000000..31d7d32e6 --- /dev/null +++ b/widget/android/jni/moz.build @@ -0,0 +1,24 @@ +# -*- 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', +] diff --git a/widget/android/moz.build b/widget/android/moz.build new file mode 100644 index 000000000..e80ed01c1 --- /dev/null +++ b/widget/android/moz.build @@ -0,0 +1,73 @@ +# -*- 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/. + +DIRS += [ + 'bindings', + 'fennec', + 'jni', +] + +XPIDL_SOURCES += [ + 'nsIAndroidBridge.idl', +] + +XPIDL_MODULE = 'widget_android' + +EXPORTS += [ + 'AndroidBridge.h', + 'AndroidJavaWrappers.h', + 'AndroidJNIWrapper.h', + 'GeneratedJNINatives.h', + 'GeneratedJNIWrappers.h', +] + +EXPORTS.mozilla.widget += [ + 'AndroidCompositorWidget.h', +] + +UNIFIED_SOURCES += [ + 'AndroidAlerts.cpp', + 'AndroidBridge.cpp', + 'AndroidCompositorWidget.cpp', + 'AndroidContentController.cpp', + 'AndroidJavaWrappers.cpp', + 'AndroidJNI.cpp', + 'AndroidJNIWrapper.cpp', + 'ANRReporter.cpp', + 'GeneratedJNIWrappers.cpp', + 'GfxInfo.cpp', + 'NativeJSContainer.cpp', + 'nsAndroidProtocolHandler.cpp', + 'nsAppShell.cpp', + 'nsClipboard.cpp', + 'nsDeviceContextAndroid.cpp', + 'nsIdleServiceAndroid.cpp', + 'nsLookAndFeel.cpp', + 'nsPrintOptionsAndroid.cpp', + 'nsScreenManagerAndroid.cpp', + 'nsWidgetFactory.cpp', + 'nsWindow.cpp', +] + +include('/ipc/chromium/chromium-config.mozbuild') + +FINAL_LIBRARY = 'xul' + +LOCAL_INCLUDES += [ + '/docshell/base', + '/dom/base', + '/dom/system/android', + '/netwerk/base', + '/netwerk/cache', + '/widget', +] + +CXXFLAGS += ['-Wno-error=shadow'] + +OS_LIBS += ['android'] + +#DEFINES['DEBUG_WIDGETS'] = True + diff --git a/widget/android/nsAndroidProtocolHandler.cpp b/widget/android/nsAndroidProtocolHandler.cpp new file mode 100644 index 000000000..e59a5d5cf --- /dev/null +++ b/widget/android/nsAndroidProtocolHandler.cpp @@ -0,0 +1,183 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim:set ts=4 sw=4 sts=4 et cin: */ +/* 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 "nsAndroidProtocolHandler.h" +#include "nsCOMPtr.h" +#include "nsIChannel.h" +#include "nsIIOService.h" +#include "nsIStandardURL.h" +#include "nsIURL.h" +#include "android/log.h" +#include "nsBaseChannel.h" +#include "AndroidBridge.h" +#include "GeneratedJNIWrappers.h" + +using namespace mozilla; + +class AndroidInputStream : public nsIInputStream +{ +public: + AndroidInputStream(jni::Object::Param connection) { + mBridgeInputStream = java::GeckoAppShell::CreateInputStream(connection); + mBridgeChannel = AndroidBridge::ChannelCreate(mBridgeInputStream); + } + +private: + virtual ~AndroidInputStream() { + } + +public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIINPUTSTREAM + +private: + jni::Object::GlobalRef mBridgeInputStream; + jni::Object::GlobalRef mBridgeChannel; +}; + +NS_IMPL_ISUPPORTS(AndroidInputStream, nsIInputStream) + +NS_IMETHODIMP AndroidInputStream::Close(void) { + AndroidBridge::InputStreamClose(mBridgeInputStream); + return NS_OK; +} + +NS_IMETHODIMP AndroidInputStream::Available(uint64_t *_retval) { + *_retval = AndroidBridge::InputStreamAvailable(mBridgeInputStream); + return NS_OK; +} + +NS_IMETHODIMP AndroidInputStream::Read(char *aBuf, uint32_t aCount, uint32_t *_retval) { + return AndroidBridge::InputStreamRead(mBridgeChannel, aBuf, aCount, _retval); +} + +NS_IMETHODIMP AndroidInputStream::ReadSegments(nsWriteSegmentFun aWriter, void *aClosure, uint32_t aCount, uint32_t *_retval) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP AndroidInputStream::IsNonBlocking(bool *_retval) { + *_retval = false; + return NS_OK; +} + + +class AndroidChannel : public nsBaseChannel +{ +private: + AndroidChannel(nsIURI *aURI, jni::Object::Param aConnection) { + mConnection = aConnection; + SetURI(aURI); + + auto type = java::GeckoAppShell::ConnectionGetMimeType(mConnection); + if (type) { + SetContentType(type->ToCString()); + } + } + +public: + static AndroidChannel* CreateChannel(nsIURI *aURI) { + nsCString spec; + aURI->GetSpec(spec); + + auto connection = java::GeckoAppShell::GetConnection(spec); + return connection ? new AndroidChannel(aURI, connection) : nullptr; + } + + virtual ~AndroidChannel() { + } + + virtual nsresult OpenContentStream(bool async, nsIInputStream **result, + nsIChannel** channel) { + nsCOMPtr<nsIInputStream> stream = new AndroidInputStream(mConnection); + NS_ADDREF(*result = stream); + return NS_OK; + } + +private: + jni::Object::GlobalRef mConnection; +}; + +NS_IMPL_ISUPPORTS(nsAndroidProtocolHandler, + nsIProtocolHandler, + nsISupportsWeakReference) + + +NS_IMETHODIMP +nsAndroidProtocolHandler::GetScheme(nsACString &result) +{ + result.AssignLiteral("android"); + return NS_OK; +} + +NS_IMETHODIMP +nsAndroidProtocolHandler::GetDefaultPort(int32_t *result) +{ + *result = -1; // no port for android: URLs + return NS_OK; +} + +NS_IMETHODIMP +nsAndroidProtocolHandler::AllowPort(int32_t port, const char *scheme, bool *_retval) +{ + // don't override anything. + *_retval = false; + return NS_OK; +} + +NS_IMETHODIMP +nsAndroidProtocolHandler::GetProtocolFlags(uint32_t *result) +{ + *result = URI_STD | URI_IS_UI_RESOURCE | URI_IS_LOCAL_RESOURCE | URI_NORELATIVE | URI_DANGEROUS_TO_LOAD; + return NS_OK; +} + +NS_IMETHODIMP +nsAndroidProtocolHandler::NewURI(const nsACString &aSpec, + const char *aCharset, + nsIURI *aBaseURI, + nsIURI **result) +{ + nsresult rv; + + nsCOMPtr<nsIStandardURL> surl(do_CreateInstance(NS_STANDARDURL_CONTRACTID, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = surl->Init(nsIStandardURL::URLTYPE_STANDARD, -1, aSpec, aCharset, aBaseURI); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr<nsIURL> url(do_QueryInterface(surl, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + surl->SetMutable(false); + + NS_ADDREF(*result = url); + return NS_OK; +} + +NS_IMETHODIMP +nsAndroidProtocolHandler::NewChannel2(nsIURI* aURI, + nsILoadInfo* aLoadInfo, + nsIChannel** aResult) +{ + nsCOMPtr<nsIChannel> channel = AndroidChannel::CreateChannel(aURI); + if (!channel) + return NS_ERROR_FAILURE; + + // set the loadInfo on the new channel + nsresult rv = channel->SetLoadInfo(aLoadInfo); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ADDREF(*aResult = channel); + return NS_OK; +} + +NS_IMETHODIMP +nsAndroidProtocolHandler::NewChannel(nsIURI* aURI, + nsIChannel* *aResult) +{ + return NewChannel2(aURI, nullptr, aResult); +} diff --git a/widget/android/nsAndroidProtocolHandler.h b/widget/android/nsAndroidProtocolHandler.h new file mode 100644 index 000000000..11705dd0a --- /dev/null +++ b/widget/android/nsAndroidProtocolHandler.h @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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 nsAndroidProtocolHandler_h___ +#define nsAndroidProtocolHandler_h___ + +#include "nsIProtocolHandler.h" +#include "nsWeakReference.h" +#include "mozilla/Attributes.h" + +#define NS_ANDROIDPROTOCOLHANDLER_CID \ +{ /* e9cd2b7f-8386-441b-aaf5-0b371846bfd0 */ \ + 0xe9cd2b7f, \ + 0x8386, \ + 0x441b, \ + {0x0b, 0x37, 0x18, 0x46, 0xbf, 0xd0} \ +} + +class nsAndroidProtocolHandler final : public nsIProtocolHandler, + public nsSupportsWeakReference +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + + // nsIProtocolHandler methods: + NS_DECL_NSIPROTOCOLHANDLER + + // nsAndroidProtocolHandler methods: + nsAndroidProtocolHandler() {} + +private: + ~nsAndroidProtocolHandler() {} +}; + +#endif /* nsAndroidProtocolHandler_h___ */ diff --git a/widget/android/nsAppShell.cpp b/widget/android/nsAppShell.cpp new file mode 100644 index 000000000..fefd711d0 --- /dev/null +++ b/widget/android/nsAppShell.cpp @@ -0,0 +1,688 @@ +/* -*- Mode: c++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4; -*- */ +/* 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 "nsAppShell.h" + +#include "base/basictypes.h" +#include "base/message_loop.h" +#include "base/task.h" +#include "mozilla/Hal.h" +#include "nsIScreen.h" +#include "nsIScreenManager.h" +#include "nsWindow.h" +#include "nsThreadUtils.h" +#include "nsICommandLineRunner.h" +#include "nsIObserverService.h" +#include "nsIAppStartup.h" +#include "nsIGeolocationProvider.h" +#include "nsCacheService.h" +#include "nsIDOMEventListener.h" +#include "nsIDOMClientRectList.h" +#include "nsIDOMClientRect.h" +#include "nsIDOMWakeLockListener.h" +#include "nsIPowerManagerService.h" +#include "nsISpeculativeConnect.h" +#include "nsIURIFixup.h" +#include "nsCategoryManagerUtils.h" +#include "nsCDefaultURIFixup.h" +#include "nsToolkitCompsCID.h" +#include "nsGeoPosition.h" + +#include "mozilla/Services.h" +#include "mozilla/Preferences.h" +#include "mozilla/Hal.h" +#include "prenv.h" + +#include "AndroidBridge.h" +#include "AndroidBridgeUtilities.h" +#include "GeneratedJNINatives.h" +#include <android/log.h> +#include <pthread.h> +#include <wchar.h> + +#include "GeckoProfiler.h" +#ifdef MOZ_ANDROID_HISTORY +#include "nsNetUtil.h" +#include "nsIURI.h" +#include "IHistory.h" +#endif + +#ifdef MOZ_LOGGING +#include "mozilla/Logging.h" +#endif + +#ifdef MOZ_CRASHREPORTER +#include "nsICrashReporter.h" +#include "nsExceptionHandler.h" +#endif + +#include "AndroidAlerts.h" +#include "ANRReporter.h" +#include "GeckoBatteryManager.h" +#include "GeckoNetworkManager.h" +#include "GeckoScreenOrientation.h" +#include "PrefsHelper.h" +#include "fennec/MemoryMonitor.h" +#include "fennec/Telemetry.h" +#include "fennec/ThumbnailHelper.h" + +#ifdef DEBUG_ANDROID_EVENTS +#define EVLOG(args...) ALOG(args) +#else +#define EVLOG(args...) do { } while (0) +#endif + +using namespace mozilla; + +nsIGeolocationUpdate *gLocationCallback = nullptr; + +nsAppShell* nsAppShell::sAppShell; +StaticAutoPtr<Mutex> nsAppShell::sAppShellLock; + +NS_IMPL_ISUPPORTS_INHERITED(nsAppShell, nsBaseAppShell, nsIObserver) + +class WakeLockListener final : public nsIDOMMozWakeLockListener { +private: + ~WakeLockListener() {} + +public: + NS_DECL_ISUPPORTS; + + nsresult Callback(const nsAString& topic, const nsAString& state) override { + java::GeckoAppShell::NotifyWakeLockChanged(topic, state); + return NS_OK; + } +}; + +NS_IMPL_ISUPPORTS(WakeLockListener, nsIDOMMozWakeLockListener) +nsCOMPtr<nsIPowerManagerService> sPowerManagerService = nullptr; +StaticRefPtr<WakeLockListener> sWakeLockListener; + + +class GeckoThreadSupport final + : public java::GeckoThread::Natives<GeckoThreadSupport> +{ + // When this number goes above 0, the app is paused. When less than or + // equal to zero, the app is resumed. + static int32_t sPauseCount; + +public: + static void SpeculativeConnect(jni::String::Param aUriStr) + { + if (!NS_IsMainThread()) { + // We will be on the main thread if the call was queued on the Java + // side during startup. Otherwise, the call was not queued, which + // means Gecko is already sufficiently loaded, and we don't really + // care about speculative connections at this point. + return; + } + + nsCOMPtr<nsIIOService> ioServ = do_GetIOService(); + nsCOMPtr<nsISpeculativeConnect> specConn = do_QueryInterface(ioServ); + if (!specConn) { + return; + } + + nsCOMPtr<nsIURI> uri = nsAppShell::ResolveURI(aUriStr->ToCString()); + if (!uri) { + return; + } + specConn->SpeculativeConnect(uri, nullptr); + } + + static void WaitOnGecko() + { + struct NoOpEvent : nsAppShell::Event { + void Run() override {} + }; + nsAppShell::SyncRunEvent(NoOpEvent()); + } + + static void OnPause() + { + MOZ_ASSERT(NS_IsMainThread()); + + sPauseCount++; + // If sPauseCount is now 1, we just crossed the threshold from "resumed" + // "paused". so we should notify observers and so on. + if (sPauseCount != 1) { + return; + } + + nsCOMPtr<nsIObserverService> obsServ = + mozilla::services::GetObserverService(); + obsServ->NotifyObservers(nullptr, "application-background", nullptr); + + NS_NAMED_LITERAL_STRING(minimize, "heap-minimize"); + obsServ->NotifyObservers(nullptr, "memory-pressure", minimize.get()); + + // If we are OOM killed with the disk cache enabled, the entire + // cache will be cleared (bug 105843), so shut down the cache here + // and re-init on foregrounding + if (nsCacheService::GlobalInstance()) { + nsCacheService::GlobalInstance()->Shutdown(); + } + + // We really want to send a notification like profile-before-change, + // but profile-before-change ends up shutting some things down instead + // of flushing data + nsIPrefService* prefs = Preferences::GetService(); + if (prefs) { + prefs->SavePrefFile(nullptr); + } + } + + static void OnResume() + { + MOZ_ASSERT(NS_IsMainThread()); + + sPauseCount--; + // If sPauseCount is now 0, we just crossed the threshold from "paused" + // to "resumed", so we should notify observers and so on. + if (sPauseCount != 0) { + return; + } + + // If we are OOM killed with the disk cache enabled, the entire + // cache will be cleared (bug 105843), so shut down cache on backgrounding + // and re-init here + if (nsCacheService::GlobalInstance()) { + nsCacheService::GlobalInstance()->Init(); + } + + // We didn't return from one of our own activities, so restore + // to foreground status + nsCOMPtr<nsIObserverService> obsServ = + mozilla::services::GetObserverService(); + obsServ->NotifyObservers(nullptr, "application-foreground", nullptr); + } + + static void CreateServices(jni::String::Param aCategory, jni::String::Param aData) + { + MOZ_ASSERT(NS_IsMainThread()); + + nsCString category(aCategory->ToCString()); + + NS_CreateServicesFromCategory( + category.get(), + nullptr, // aOrigin + category.get(), + aData ? aData->ToString().get() : nullptr); + } + + static int64_t RunUiThreadCallback() + { + if (!AndroidBridge::Bridge()) { + return -1; + } + + return AndroidBridge::Bridge()->RunDelayedUiThreadTasks(); + } +}; + +int32_t GeckoThreadSupport::sPauseCount; + + +class GeckoAppShellSupport final + : public java::GeckoAppShell::Natives<GeckoAppShellSupport> +{ +public: + static void ReportJavaCrash(const jni::Class::LocalRef& aCls, + jni::Throwable::Param aException, + jni::String::Param aStack) + { + if (!jni::ReportException(aCls.Env(), aException.Get(), aStack.Get())) { + // Only crash below if crash reporter is initialized and annotation + // succeeded. Otherwise try other means of reporting the crash in + // Java. + return; + } + + MOZ_CRASH("Uncaught Java exception"); + } + + static void SyncNotifyObservers(jni::String::Param aTopic, + jni::String::Param aData) + { + MOZ_RELEASE_ASSERT(NS_IsMainThread()); + NotifyObservers(aTopic, aData); + } + + static void NotifyObservers(jni::String::Param aTopic, + jni::String::Param aData) + { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aTopic); + + nsCOMPtr<nsIObserverService> obsServ = services::GetObserverService(); + if (!obsServ) { + return; + } + + obsServ->NotifyObservers(nullptr, aTopic->ToCString().get(), + aData ? aData->ToString().get() : nullptr); + } + + static void OnSensorChanged(int32_t aType, float aX, float aY, float aZ, + float aW, int32_t aAccuracy, int64_t aTime) + { + AutoTArray<float, 4> values; + + switch (aType) { + // Bug 938035, transfer HAL data for orientation sensor to meet w3c + // spec, ex: HAL report alpha=90 means East but alpha=90 means West + // in w3c spec + case hal::SENSOR_ORIENTATION: + values.AppendElement(360.0f - aX); + values.AppendElement(-aY); + values.AppendElement(-aZ); + break; + + case hal::SENSOR_LINEAR_ACCELERATION: + case hal::SENSOR_ACCELERATION: + case hal::SENSOR_GYROSCOPE: + case hal::SENSOR_PROXIMITY: + values.AppendElement(aX); + values.AppendElement(aY); + values.AppendElement(aZ); + break; + + case hal::SENSOR_LIGHT: + values.AppendElement(aX); + break; + + case hal::SENSOR_ROTATION_VECTOR: + case hal::SENSOR_GAME_ROTATION_VECTOR: + values.AppendElement(aX); + values.AppendElement(aY); + values.AppendElement(aZ); + values.AppendElement(aW); + break; + + default: + __android_log_print(ANDROID_LOG_ERROR, "Gecko", + "Unknown sensor type %d", aType); + } + + hal::SensorData sdata(hal::SensorType(aType), aTime, values, + hal::SensorAccuracyType(aAccuracy)); + hal::NotifySensorChange(sdata); + } + + static void OnLocationChanged(double aLatitude, double aLongitude, + double aAltitude, float aAccuracy, + float aBearing, float aSpeed, int64_t aTime) + { + if (!gLocationCallback) { + return; + } + + RefPtr<nsIDOMGeoPosition> geoPosition( + new nsGeoPosition(aLatitude, aLongitude, aAltitude, aAccuracy, + aAccuracy, aBearing, aSpeed, aTime)); + gLocationCallback->Update(geoPosition); + } + + static void NotifyUriVisited(jni::String::Param aUri) + { +#ifdef MOZ_ANDROID_HISTORY + nsCOMPtr<IHistory> history = services::GetHistoryService(); + nsCOMPtr<nsIURI> visitedURI; + if (history && + NS_SUCCEEDED(NS_NewURI(getter_AddRefs(visitedURI), + aUri->ToString()))) { + history->NotifyVisited(visitedURI); + } +#endif + } + + static void NotifyAlertListener(jni::String::Param aName, + jni::String::Param aTopic, + jni::String::Param aCookie) + { + if (!aName || !aTopic || !aCookie) { + return; + } + + AndroidAlerts::NotifyListener( + aName->ToString(), aTopic->ToCString().get(), + aCookie->ToString().get()); + } + + static void OnFullScreenPluginHidden(jni::Object::Param aView) + { + nsPluginInstanceOwner::ExitFullScreen(aView.Get()); + } +}; + +nsAppShell::nsAppShell() + : mSyncRunFinished(*(sAppShellLock = new Mutex("nsAppShell")), + "nsAppShell.SyncRun") + , mSyncRunQuit(false) +{ + { + MutexAutoLock lock(*sAppShellLock); + sAppShell = this; + } + + if (!XRE_IsParentProcess()) { + return; + } + + if (jni::IsAvailable()) { + // Initialize JNI and Set the corresponding state in GeckoThread. + AndroidBridge::ConstructBridge(); + GeckoAppShellSupport::Init(); + GeckoThreadSupport::Init(); + mozilla::GeckoBatteryManager::Init(); + mozilla::GeckoNetworkManager::Init(); + mozilla::GeckoScreenOrientation::Init(); + mozilla::PrefsHelper::Init(); + nsWindow::InitNatives(); + + if (jni::IsFennec()) { + mozilla::ANRReporter::Init(); + mozilla::MemoryMonitor::Init(); + mozilla::widget::Telemetry::Init(); + mozilla::ThumbnailHelper::Init(); + } + + java::GeckoThread::SetState(java::GeckoThread::State::JNI_READY()); + } + + sPowerManagerService = do_GetService(POWERMANAGERSERVICE_CONTRACTID); + + if (sPowerManagerService) { + sWakeLockListener = new WakeLockListener(); + } else { + NS_WARNING("Failed to retrieve PowerManagerService, wakelocks will be broken!"); + } +} + +nsAppShell::~nsAppShell() +{ + { + MutexAutoLock lock(*sAppShellLock); + sAppShell = nullptr; + } + + while (mEventQueue.Pop(/* mayWait */ false)) { + NS_WARNING("Discarded event on shutdown"); + } + + if (sPowerManagerService) { + sPowerManagerService->RemoveWakeLockListener(sWakeLockListener); + + sPowerManagerService = nullptr; + sWakeLockListener = nullptr; + } + + if (jni::IsAvailable()) { + AndroidBridge::DeconstructBridge(); + } +} + +void +nsAppShell::NotifyNativeEvent() +{ + mEventQueue.Signal(); +} + +#define PREFNAME_COALESCE_TOUCHES "dom.event.touch.coalescing.enabled" +static const char* kObservedPrefs[] = { + PREFNAME_COALESCE_TOUCHES, + nullptr +}; + +nsresult +nsAppShell::Init() +{ + nsresult rv = nsBaseAppShell::Init(); + nsCOMPtr<nsIObserverService> obsServ = + mozilla::services::GetObserverService(); + if (obsServ) { + obsServ->AddObserver(this, "browser-delayed-startup-finished", false); + obsServ->AddObserver(this, "profile-after-change", false); + obsServ->AddObserver(this, "chrome-document-loaded", false); + obsServ->AddObserver(this, "quit-application-granted", false); + obsServ->AddObserver(this, "xpcom-shutdown", false); + } + + if (sPowerManagerService) + sPowerManagerService->AddWakeLockListener(sWakeLockListener); + + Preferences::AddStrongObservers(this, kObservedPrefs); + mAllowCoalescingTouches = Preferences::GetBool(PREFNAME_COALESCE_TOUCHES, true); + return rv; +} + +NS_IMETHODIMP +nsAppShell::Observe(nsISupports* aSubject, + const char* aTopic, + const char16_t* aData) +{ + bool removeObserver = false; + + if (!strcmp(aTopic, "xpcom-shutdown")) { + { + // Release any thread waiting for a sync call to finish. + mozilla::MutexAutoLock shellLock(*sAppShellLock); + mSyncRunQuit = true; + mSyncRunFinished.NotifyAll(); + } + // We need to ensure no observers stick around after XPCOM shuts down + // or we'll see crashes, as the app shell outlives XPConnect. + mObserversHash.Clear(); + return nsBaseAppShell::Observe(aSubject, aTopic, aData); + + } else if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) && + aData && + nsDependentString(aData).Equals(NS_LITERAL_STRING(PREFNAME_COALESCE_TOUCHES))) { + mAllowCoalescingTouches = Preferences::GetBool(PREFNAME_COALESCE_TOUCHES, true); + return NS_OK; + + } else if (!strcmp(aTopic, "browser-delayed-startup-finished")) { + NS_CreateServicesFromCategory("browser-delayed-startup-finished", nullptr, + "browser-delayed-startup-finished"); + + } else if (!strcmp(aTopic, "profile-after-change")) { + if (jni::IsAvailable()) { + // See if we want to force 16-bit color before doing anything + if (Preferences::GetBool("gfx.android.rgb16.force", false)) { + java::GeckoAppShell::SetScreenDepthOverride(16); + } + + java::GeckoThread::SetState( + java::GeckoThread::State::PROFILE_READY()); + + // Gecko on Android follows the Android app model where it never + // stops until it is killed by the system or told explicitly to + // quit. Therefore, we should *not* exit Gecko when there is no + // window or the last window is closed. nsIAppStartup::Quit will + // still force Gecko to exit. + nsCOMPtr<nsIAppStartup> appStartup = + do_GetService(NS_APPSTARTUP_CONTRACTID); + if (appStartup) { + appStartup->EnterLastWindowClosingSurvivalArea(); + } + } + removeObserver = true; + + } else if (!strcmp(aTopic, "chrome-document-loaded")) { + if (jni::IsAvailable()) { + // Our first window has loaded, assume any JS initialization has run. + java::GeckoThread::CheckAndSetState( + java::GeckoThread::State::PROFILE_READY(), + java::GeckoThread::State::RUNNING()); + } + removeObserver = true; + + } else if (!strcmp(aTopic, "quit-application-granted")) { + if (jni::IsAvailable()) { + java::GeckoThread::SetState( + java::GeckoThread::State::EXITING()); + + // We are told explicitly to quit, perhaps due to + // nsIAppStartup::Quit being called. We should release our hold on + // nsIAppStartup and let it continue to quit. + nsCOMPtr<nsIAppStartup> appStartup = + do_GetService(NS_APPSTARTUP_CONTRACTID); + if (appStartup) { + appStartup->ExitLastWindowClosingSurvivalArea(); + } + } + removeObserver = true; + + } else if (!strcmp(aTopic, "nsPref:changed")) { + if (jni::IsAvailable()) { + mozilla::PrefsHelper::OnPrefChange(aData); + } + } + + if (removeObserver) { + nsCOMPtr<nsIObserverService> obsServ = + mozilla::services::GetObserverService(); + if (obsServ) { + obsServ->RemoveObserver(this, aTopic); + } + } + return NS_OK; +} + +bool +nsAppShell::ProcessNextNativeEvent(bool mayWait) +{ + EVLOG("nsAppShell::ProcessNextNativeEvent %d", mayWait); + + PROFILER_LABEL("nsAppShell", "ProcessNextNativeEvent", + js::ProfileEntry::Category::EVENTS); + + mozilla::UniquePtr<Event> curEvent; + + { + curEvent = mEventQueue.Pop(/* mayWait */ false); + + if (!curEvent && mayWait) { + // This processes messages in the Android Looper. Note that we only + // get here if the normal Gecko event loop has been awoken + // (bug 750713). Looper messages effectively have the lowest + // priority because we only process them before we're about to + // wait for new events. + if (jni::IsAvailable() && + AndroidBridge::Bridge()->PumpMessageLoop()) { + return true; + } + + PROFILER_LABEL("nsAppShell", "ProcessNextNativeEvent::Wait", + js::ProfileEntry::Category::EVENTS); + mozilla::HangMonitor::Suspend(); + + curEvent = mEventQueue.Pop(/* mayWait */ true); + } + } + + if (!curEvent) + return false; + + mozilla::HangMonitor::NotifyActivity(curEvent->ActivityType()); + + curEvent->Run(); + return true; +} + +void +nsAppShell::SyncRunEvent(Event&& event, + UniquePtr<Event>(*eventFactory)(UniquePtr<Event>&&)) +{ + // Perform the call on the Gecko thread in a separate lambda, and wait + // on the monitor on the current thread. + MOZ_ASSERT(!NS_IsMainThread()); + + // This is the lock to check that app shell is still alive, + // and to wait on for the sync call to complete. + mozilla::MutexAutoLock shellLock(*sAppShellLock); + nsAppShell* const appShell = sAppShell; + + if (MOZ_UNLIKELY(!appShell)) { + // Post-shutdown. + return; + } + + bool finished = false; + auto runAndNotify = [&event, &finished] { + mozilla::MutexAutoLock shellLock(*sAppShellLock); + nsAppShell* const appShell = sAppShell; + if (MOZ_UNLIKELY(!appShell || appShell->mSyncRunQuit)) { + return; + } + event.Run(); + finished = true; + appShell->mSyncRunFinished.NotifyAll(); + }; + + UniquePtr<Event> runAndNotifyEvent = mozilla::MakeUnique< + LambdaEvent<decltype(runAndNotify)>>(mozilla::Move(runAndNotify)); + + if (eventFactory) { + runAndNotifyEvent = (*eventFactory)(mozilla::Move(runAndNotifyEvent)); + } + + appShell->mEventQueue.Post(mozilla::Move(runAndNotifyEvent)); + + while (!finished && MOZ_LIKELY(sAppShell && !sAppShell->mSyncRunQuit)) { + appShell->mSyncRunFinished.Wait(); + } +} + +already_AddRefed<nsIURI> +nsAppShell::ResolveURI(const nsCString& aUriStr) +{ + nsCOMPtr<nsIIOService> ioServ = do_GetIOService(); + nsCOMPtr<nsIURI> uri; + + if (NS_SUCCEEDED(ioServ->NewURI(aUriStr, nullptr, + nullptr, getter_AddRefs(uri)))) { + return uri.forget(); + } + + nsCOMPtr<nsIURIFixup> fixup = do_GetService(NS_URIFIXUP_CONTRACTID); + if (fixup && NS_SUCCEEDED( + fixup->CreateFixupURI(aUriStr, 0, nullptr, getter_AddRefs(uri)))) { + return uri.forget(); + } + return nullptr; +} + +nsresult +nsAppShell::AddObserver(const nsAString &aObserverKey, nsIObserver *aObserver) +{ + NS_ASSERTION(aObserver != nullptr, "nsAppShell::AddObserver: aObserver is null!"); + mObserversHash.Put(aObserverKey, aObserver); + return NS_OK; +} + +// Used by IPC code +namespace mozilla { + +bool ProcessNextEvent() +{ + nsAppShell* const appShell = nsAppShell::Get(); + if (!appShell) { + return false; + } + + return appShell->ProcessNextNativeEvent(true) ? true : false; +} + +void NotifyEvent() +{ + nsAppShell* const appShell = nsAppShell::Get(); + if (!appShell) { + return; + } + appShell->NotifyNativeEvent(); +} + +} diff --git a/widget/android/nsAppShell.h b/widget/android/nsAppShell.h new file mode 100644 index 000000000..42453999d --- /dev/null +++ b/widget/android/nsAppShell.h @@ -0,0 +1,223 @@ +/* -*- Mode: c++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4; -*- */ +/* 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 nsAppShell_h__ +#define nsAppShell_h__ + +#include "mozilla/HangMonitor.h" +#include "mozilla/LinkedList.h" +#include "mozilla/Monitor.h" +#include "mozilla/Move.h" +#include "mozilla/StaticPtr.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/Unused.h" +#include "mozilla/jni/Natives.h" +#include "nsBaseAppShell.h" +#include "nsCOMPtr.h" +#include "nsTArray.h" +#include "nsInterfaceHashtable.h" +#include "nsIAndroidBridge.h" + +namespace mozilla { +bool ProcessNextEvent(); +void NotifyEvent(); +} + +class nsWindow; + +class nsAppShell : + public nsBaseAppShell +{ +public: + struct Event : mozilla::LinkedListElement<Event> + { + typedef mozilla::HangMonitor::ActivityType Type; + + bool HasSameTypeAs(const Event* other) const + { + // Compare vtable addresses to determine same type. + return *reinterpret_cast<const uintptr_t*>(this) + == *reinterpret_cast<const uintptr_t*>(other); + } + + virtual ~Event() {} + virtual void Run() = 0; + + virtual void PostTo(mozilla::LinkedList<Event>& queue) + { + queue.insertBack(this); + } + + virtual Type ActivityType() const + { + return Type::kGeneralActivity; + } + }; + + template<typename T> + class LambdaEvent : public Event + { + protected: + T lambda; + + public: + LambdaEvent(T&& l) : lambda(mozilla::Move(l)) {} + void Run() override { return lambda(); } + }; + + class ProxyEvent : public Event + { + protected: + mozilla::UniquePtr<Event> baseEvent; + + public: + ProxyEvent(mozilla::UniquePtr<Event>&& event) + : baseEvent(mozilla::Move(event)) + {} + + void PostTo(mozilla::LinkedList<Event>& queue) override + { + baseEvent->PostTo(queue); + } + + void Run() override + { + baseEvent->Run(); + } + }; + + static nsAppShell* Get() + { + MOZ_ASSERT(NS_IsMainThread()); + return sAppShell; + } + + nsAppShell(); + + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIOBSERVER + + nsresult Init(); + + void NotifyNativeEvent(); + bool ProcessNextNativeEvent(bool mayWait) override; + + // Post a subclass of Event. + // e.g. PostEvent(mozilla::MakeUnique<MyEvent>()); + template<typename T, typename D> + static void PostEvent(mozilla::UniquePtr<T, D>&& event) + { + mozilla::MutexAutoLock lock(*sAppShellLock); + if (!sAppShell) { + return; + } + sAppShell->mEventQueue.Post(mozilla::Move(event)); + } + + // Post a event that will call a lambda + // e.g. PostEvent([=] { /* do something */ }); + template<typename T> + static void PostEvent(T&& lambda) + { + mozilla::MutexAutoLock lock(*sAppShellLock); + if (!sAppShell) { + return; + } + sAppShell->mEventQueue.Post(mozilla::MakeUnique<LambdaEvent<T>>( + mozilla::Move(lambda))); + } + + // Post a event and wait for it to finish running on the Gecko thread. + static void SyncRunEvent(Event&& event, + mozilla::UniquePtr<Event>(*eventFactory)( + mozilla::UniquePtr<Event>&&) = nullptr); + + static already_AddRefed<nsIURI> ResolveURI(const nsCString& aUriStr); + + void SetBrowserApp(nsIAndroidBrowserApp* aBrowserApp) { + mBrowserApp = aBrowserApp; + } + + nsIAndroidBrowserApp* GetBrowserApp() { + return mBrowserApp; + } + +protected: + static nsAppShell* sAppShell; + static mozilla::StaticAutoPtr<mozilla::Mutex> sAppShellLock; + + virtual ~nsAppShell(); + + nsresult AddObserver(const nsAString &aObserverKey, nsIObserver *aObserver); + + class NativeCallbackEvent : public Event + { + // Capturing the nsAppShell instance is safe because if the app + // shell is detroyed, this lambda will not be called either. + nsAppShell* const appShell; + + public: + NativeCallbackEvent(nsAppShell* as) : appShell(as) {} + void Run() override { appShell->NativeEventCallback(); } + }; + + void ScheduleNativeEventCallback() override + { + mEventQueue.Post(mozilla::MakeUnique<NativeCallbackEvent>(this)); + } + + class Queue + { + private: + mozilla::Monitor mMonitor; + mozilla::LinkedList<Event> mQueue; + + public: + Queue() : mMonitor("nsAppShell.Queue") + {} + + void Signal() + { + mozilla::MonitorAutoLock lock(mMonitor); + lock.NotifyAll(); + } + + void Post(mozilla::UniquePtr<Event>&& event) + { + MOZ_ASSERT(event && !event->isInList()); + + mozilla::MonitorAutoLock lock(mMonitor); + event->PostTo(mQueue); + if (event->isInList()) { + // Ownership of event object transfers to the queue. + mozilla::Unused << event.release(); + } + lock.NotifyAll(); + } + + mozilla::UniquePtr<Event> Pop(bool mayWait) + { + mozilla::MonitorAutoLock lock(mMonitor); + + if (mayWait && mQueue.isEmpty()) { + lock.Wait(); + } + // Ownership of event object transfers to the return value. + return mozilla::UniquePtr<Event>(mQueue.popFirst()); + } + + } mEventQueue; + + mozilla::CondVar mSyncRunFinished; + bool mSyncRunQuit; + + bool mAllowCoalescingTouches; + + nsCOMPtr<nsIAndroidBrowserApp> mBrowserApp; + nsInterfaceHashtable<nsStringHashKey, nsIObserver> mObserversHash; +}; + +#endif // nsAppShell_h__ + diff --git a/widget/android/nsClipboard.cpp b/widget/android/nsClipboard.cpp new file mode 100644 index 000000000..5d70ae16b --- /dev/null +++ b/widget/android/nsClipboard.cpp @@ -0,0 +1,123 @@ +/* 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 "mozilla/dom/ContentChild.h" +#include "nsClipboard.h" +#include "nsISupportsPrimitives.h" +#include "AndroidBridge.h" +#include "nsCOMPtr.h" +#include "nsComponentManagerUtils.h" +#include "nsXULAppAPI.h" + +using namespace mozilla; +using mozilla::dom::ContentChild; + +NS_IMPL_ISUPPORTS(nsClipboard, nsIClipboard) + +/* The Android clipboard only supports text and doesn't support mime types + * so we assume all clipboard data is text/unicode for now. Documentation + * indicates that support for other data types is planned for future + * releases. + */ + +nsClipboard::nsClipboard() +{ +} + +NS_IMETHODIMP +nsClipboard::SetData(nsITransferable *aTransferable, + nsIClipboardOwner *anOwner, int32_t aWhichClipboard) +{ + if (aWhichClipboard != kGlobalClipboard) + return NS_ERROR_NOT_IMPLEMENTED; + + nsCOMPtr<nsISupports> tmp; + uint32_t len; + nsresult rv = aTransferable->GetTransferData(kUnicodeMime, getter_AddRefs(tmp), + &len); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr<nsISupportsString> supportsString = do_QueryInterface(tmp); + // No support for non-text data + NS_ENSURE_TRUE(supportsString, NS_ERROR_NOT_IMPLEMENTED); + nsAutoString buffer; + supportsString->GetData(buffer); + + java::Clipboard::SetText(buffer); + return NS_OK; +} + +NS_IMETHODIMP +nsClipboard::GetData(nsITransferable *aTransferable, int32_t aWhichClipboard) +{ + if (aWhichClipboard != kGlobalClipboard) + return NS_ERROR_NOT_IMPLEMENTED; + + nsAutoString buffer; + if (!AndroidBridge::Bridge()) + return NS_ERROR_NOT_IMPLEMENTED; + if (!AndroidBridge::Bridge()->GetClipboardText(buffer)) + return NS_ERROR_UNEXPECTED; + + nsresult rv; + nsCOMPtr<nsISupportsString> dataWrapper = + do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + rv = dataWrapper->SetData(buffer); + NS_ENSURE_SUCCESS(rv, rv); + + // If our data flavor has already been added, this will fail. But we don't care + aTransferable->AddDataFlavor(kUnicodeMime); + + nsCOMPtr<nsISupports> nsisupportsDataWrapper = + do_QueryInterface(dataWrapper); + rv = aTransferable->SetTransferData(kUnicodeMime, nsisupportsDataWrapper, + buffer.Length() * sizeof(char16_t)); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + +NS_IMETHODIMP +nsClipboard::EmptyClipboard(int32_t aWhichClipboard) +{ + if (aWhichClipboard != kGlobalClipboard) + return NS_ERROR_NOT_IMPLEMENTED; + java::Clipboard::ClearText(); + + return NS_OK; +} + +NS_IMETHODIMP +nsClipboard::HasDataMatchingFlavors(const char **aFlavorList, + uint32_t aLength, int32_t aWhichClipboard, + bool *aHasText) +{ + *aHasText = false; + if (aWhichClipboard != kGlobalClipboard) + return NS_ERROR_NOT_IMPLEMENTED; + + for (uint32_t k = 0; k < aLength; k++) { + if (strcmp(aFlavorList[k], kUnicodeMime) == 0) { + *aHasText = java::Clipboard::HasText(); + break; + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsClipboard::SupportsSelectionClipboard(bool *aIsSupported) +{ + *aIsSupported = false; + return NS_OK; +} + +NS_IMETHODIMP +nsClipboard::SupportsFindClipboard(bool* _retval) +{ + *_retval = false; + return NS_OK; +} diff --git a/widget/android/nsClipboard.h b/widget/android/nsClipboard.h new file mode 100644 index 000000000..657a8dea8 --- /dev/null +++ b/widget/android/nsClipboard.h @@ -0,0 +1,23 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * 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 NS_CLIPBOARD_H +#define NS_CLIPBOARD_H + +#include "nsIClipboard.h" + +class nsClipboard final : public nsIClipboard +{ +private: + ~nsClipboard() {} + +public: + NS_DECL_ISUPPORTS + NS_DECL_NSICLIPBOARD + + nsClipboard(); +}; + +#endif diff --git a/widget/android/nsDeviceContextAndroid.cpp b/widget/android/nsDeviceContextAndroid.cpp new file mode 100644 index 000000000..4c952957e --- /dev/null +++ b/widget/android/nsDeviceContextAndroid.cpp @@ -0,0 +1,84 @@ +/* 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 "nsDeviceContextAndroid.h" + +#include "mozilla/gfx/PrintTargetPDF.h" +#include "mozilla/RefPtr.h" +#include "nsString.h" +#include "nsIFile.h" +#include "nsIFileStreams.h" +#include "nsIPrintSettings.h" +#include "nsDirectoryServiceDefs.h" + +using namespace mozilla; +using namespace mozilla::gfx; + +NS_IMPL_ISUPPORTS(nsDeviceContextSpecAndroid, nsIDeviceContextSpec) + +already_AddRefed<PrintTarget> +nsDeviceContextSpecAndroid::MakePrintTarget() +{ + nsresult rv = + NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(mTempFile)); + NS_ENSURE_SUCCESS(rv, nullptr); + + nsAutoCString filename("tmp-printing.pdf"); + mTempFile->AppendNative(filename); + rv = mTempFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0660); + NS_ENSURE_SUCCESS(rv, nullptr); + + nsCOMPtr<nsIFileOutputStream> stream = do_CreateInstance("@mozilla.org/network/file-output-stream;1"); + rv = stream->Init(mTempFile, -1, -1, 0); + NS_ENSURE_SUCCESS(rv, nullptr); + + // XXX: what should we do here for size? screen size? + IntSize size(480, 800); + + return PrintTargetPDF::CreateOrNull(stream, size); +} + +NS_IMETHODIMP +nsDeviceContextSpecAndroid::Init(nsIWidget* aWidget, + nsIPrintSettings* aPS, + bool aIsPrintPreview) +{ + mPrintSettings = aPS; + return NS_OK; +} + +NS_IMETHODIMP +nsDeviceContextSpecAndroid::BeginDocument(const nsAString& aTitle, + const nsAString& aPrintToFileName, + int32_t aStartPage, + int32_t aEndPage) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsDeviceContextSpecAndroid::EndDocument() +{ + nsXPIDLString targetPath; + nsCOMPtr<nsIFile> destFile; + mPrintSettings->GetToFileName(getter_Copies(targetPath)); + + nsresult rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(targetPath), + false, getter_AddRefs(destFile)); + NS_ENSURE_SUCCESS(rv, rv); + + nsAutoString destLeafName; + rv = destFile->GetLeafName(destLeafName); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsIFile> destDir; + rv = destFile->GetParent(getter_AddRefs(destDir)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = mTempFile->MoveTo(destDir, destLeafName); + NS_ENSURE_SUCCESS(rv, rv); + + destFile->SetPermissions(0666); + return NS_OK; +} diff --git a/widget/android/nsDeviceContextAndroid.h b/widget/android/nsDeviceContextAndroid.h new file mode 100644 index 000000000..7abe38ca4 --- /dev/null +++ b/widget/android/nsDeviceContextAndroid.h @@ -0,0 +1,32 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "nsIDeviceContextSpec.h" +#include "nsCOMPtr.h" + +class nsDeviceContextSpecAndroid final : public nsIDeviceContextSpec +{ +private: + ~nsDeviceContextSpecAndroid() {} + +public: + NS_DECL_ISUPPORTS + + virtual already_AddRefed<PrintTarget> MakePrintTarget() final; + + NS_IMETHOD Init(nsIWidget* aWidget, + nsIPrintSettings* aPS, + bool aIsPrintPreview) override; + NS_IMETHOD BeginDocument(const nsAString& aTitle, + const nsAString& aPrintToFileName, + int32_t aStartPage, + int32_t aEndPage) override; + NS_IMETHOD EndDocument() override; + NS_IMETHOD BeginPage() override { return NS_OK; } + NS_IMETHOD EndPage() override { return NS_OK; } + +private: + nsCOMPtr<nsIPrintSettings> mPrintSettings; + nsCOMPtr<nsIFile> mTempFile; +}; diff --git a/widget/android/nsIAndroidBridge.idl b/widget/android/nsIAndroidBridge.idl new file mode 100644 index 000000000..91b1a3d52 --- /dev/null +++ b/widget/android/nsIAndroidBridge.idl @@ -0,0 +1,42 @@ +/* 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 "nsISupports.idl" + +interface mozIDOMWindowProxy; + +[scriptable, uuid(e8420a7b-659b-4325-968b-a114a6a067aa)] +interface nsIBrowserTab : nsISupports { + readonly attribute mozIDOMWindowProxy window; + readonly attribute float scale; +}; + +[scriptable, uuid(08426a73-e70b-4680-9282-630932e2b2bb)] +interface nsIUITelemetryObserver : nsISupports { + void startSession(in wstring name, + in long long timestamp); + void stopSession(in wstring name, + in wstring reason, + in long long timestamp); + void addEvent(in wstring action, + in wstring method, + in long long timestamp, + in wstring extras); +}; + +[scriptable, uuid(0370450f-2e9c-4d16-b333-8ca6ce31a5ff)] +interface nsIAndroidBrowserApp : nsISupports { + readonly attribute nsIBrowserTab selectedTab; + nsIBrowserTab getBrowserTab(in int32_t tabId); + nsIUITelemetryObserver getUITelemetryObserver(); +}; + +[scriptable, uuid(1beb70d3-70f3-4742-98cc-a3d301b26c0c)] +interface nsIAndroidBridge : nsISupports +{ + [implicit_jscontext] void handleGeckoMessage(in jsval message); + attribute nsIAndroidBrowserApp browserApp; + void contentDocumentChanged(in mozIDOMWindowProxy window); + boolean isContentDocumentDisplayed(in mozIDOMWindowProxy window); +}; diff --git a/widget/android/nsIdleServiceAndroid.cpp b/widget/android/nsIdleServiceAndroid.cpp new file mode 100644 index 000000000..1992d8043 --- /dev/null +++ b/widget/android/nsIdleServiceAndroid.cpp @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim:expandtab:shiftwidth=4:tabstop=4: + */ +/* 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 "nsIdleServiceAndroid.h" +#include "nsIServiceManager.h" + +NS_IMPL_ISUPPORTS_INHERITED0(nsIdleServiceAndroid, nsIdleService) + +bool +nsIdleServiceAndroid::PollIdleTime(uint32_t *aIdleTime) +{ + return false; +} + +bool +nsIdleServiceAndroid::UsePollMode() +{ + return false; +} diff --git a/widget/android/nsIdleServiceAndroid.h b/widget/android/nsIdleServiceAndroid.h new file mode 100644 index 000000000..28bca0553 --- /dev/null +++ b/widget/android/nsIdleServiceAndroid.h @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim:expandtab:shiftwidth=4:tabstop=4: + */ +/* 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 nsIdleServiceAndroid_h__ +#define nsIdleServiceAndroid_h__ + +#include "nsIdleService.h" + +class nsIdleServiceAndroid : public nsIdleService +{ +public: + NS_DECL_ISUPPORTS_INHERITED + + bool PollIdleTime(uint32_t* aIdleTime) override; + + static already_AddRefed<nsIdleServiceAndroid> GetInstance() + { + RefPtr<nsIdleService> idleService = nsIdleService::GetInstance(); + if (!idleService) { + idleService = new nsIdleServiceAndroid(); + } + + return idleService.forget().downcast<nsIdleServiceAndroid>(); + } + +protected: + nsIdleServiceAndroid() { } + virtual ~nsIdleServiceAndroid() { } + bool UsePollMode() override; +}; + +#endif // nsIdleServiceAndroid_h__ diff --git a/widget/android/nsLookAndFeel.cpp b/widget/android/nsLookAndFeel.cpp new file mode 100644 index 000000000..770b52a24 --- /dev/null +++ b/widget/android/nsLookAndFeel.cpp @@ -0,0 +1,500 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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 "mozilla/dom/ContentChild.h" +#include "nsStyleConsts.h" +#include "nsXULAppAPI.h" +#include "nsLookAndFeel.h" +#include "gfxFont.h" +#include "gfxFontConstants.h" +#include "mozilla/gfx/2D.h" + +using namespace mozilla; +using mozilla::dom::ContentChild; + +bool nsLookAndFeel::mInitializedSystemColors = false; +AndroidSystemColors nsLookAndFeel::mSystemColors; + +bool nsLookAndFeel::mInitializedShowPassword = false; +bool nsLookAndFeel::mShowPassword = true; + +static const char16_t UNICODE_BULLET = 0x2022; + +nsLookAndFeel::nsLookAndFeel() + : nsXPLookAndFeel() +{ +} + +nsLookAndFeel::~nsLookAndFeel() +{ +} + +#define BG_PRELIGHT_COLOR NS_RGB(0xee,0xee,0xee) +#define FG_PRELIGHT_COLOR NS_RGB(0x77,0x77,0x77) +#define BLACK_COLOR NS_RGB(0x00,0x00,0x00) +#define DARK_GRAY_COLOR NS_RGB(0x40,0x40,0x40) +#define GRAY_COLOR NS_RGB(0x80,0x80,0x80) +#define LIGHT_GRAY_COLOR NS_RGB(0xa0,0xa0,0xa0) +#define RED_COLOR NS_RGB(0xff,0x00,0x00) + +nsresult +nsLookAndFeel::GetSystemColors() +{ + if (mInitializedSystemColors) + return NS_OK; + + if (!AndroidBridge::Bridge()) + return NS_ERROR_FAILURE; + + AndroidBridge::Bridge()->GetSystemColors(&mSystemColors); + + mInitializedSystemColors = true; + + return NS_OK; +} + +nsresult +nsLookAndFeel::CallRemoteGetSystemColors() +{ + // An array has to be used to get data from remote process + InfallibleTArray<uint32_t> colors; + uint32_t colorsCount = sizeof(AndroidSystemColors) / sizeof(nscolor); + + if (!ContentChild::GetSingleton()->SendGetSystemColors(colorsCount, &colors)) + return NS_ERROR_FAILURE; + + NS_ASSERTION(colors.Length() == colorsCount, "System colors array is incomplete"); + if (colors.Length() == 0) + return NS_ERROR_FAILURE; + + if (colors.Length() < colorsCount) + colorsCount = colors.Length(); + + // Array elements correspond to the members of mSystemColors structure, + // so just copy the memory block + memcpy(&mSystemColors, colors.Elements(), sizeof(nscolor) * colorsCount); + + mInitializedSystemColors = true; + + return NS_OK; +} + +nsresult +nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor) +{ + nsresult rv = NS_OK; + + if (!mInitializedSystemColors) { + if (XRE_IsParentProcess()) + rv = GetSystemColors(); + else + rv = CallRemoteGetSystemColors(); + NS_ENSURE_SUCCESS(rv, rv); + } + + // XXX we'll want to use context.obtainStyledAttributes on the java side to + // get all of these; see TextView.java for a good exmaple. + + switch (aID) { + // These colors don't seem to be used for anything anymore in Mozilla + // (except here at least TextSelectBackground and TextSelectForeground) + // The CSS2 colors below are used. + case eColorID_WindowBackground: + aColor = NS_RGB(0xFF, 0xFF, 0xFF); + break; + case eColorID_WindowForeground: + aColor = mSystemColors.textColorPrimary; + break; + case eColorID_WidgetBackground: + aColor = mSystemColors.colorBackground; + break; + case eColorID_WidgetForeground: + aColor = mSystemColors.colorForeground; + break; + case eColorID_WidgetSelectBackground: + aColor = mSystemColors.textColorHighlight; + break; + case eColorID_WidgetSelectForeground: + aColor = mSystemColors.textColorPrimaryInverse; + break; + case eColorID_Widget3DHighlight: + aColor = LIGHT_GRAY_COLOR; + break; + case eColorID_Widget3DShadow: + aColor = DARK_GRAY_COLOR; + break; + case eColorID_TextBackground: + // not used? + aColor = mSystemColors.colorBackground; + break; + case eColorID_TextForeground: + // not used? + aColor = mSystemColors.textColorPrimary; + break; + case eColorID_TextSelectBackground: + case eColorID_IMESelectedRawTextBackground: + case eColorID_IMESelectedConvertedTextBackground: + // still used + aColor = mSystemColors.textColorHighlight; + break; + case eColorID_TextSelectForeground: + case eColorID_IMESelectedRawTextForeground: + case eColorID_IMESelectedConvertedTextForeground: + // still used + aColor = mSystemColors.textColorPrimaryInverse; + break; + case eColorID_IMERawInputBackground: + case eColorID_IMEConvertedTextBackground: + aColor = NS_TRANSPARENT; + break; + case eColorID_IMERawInputForeground: + case eColorID_IMEConvertedTextForeground: + aColor = NS_SAME_AS_FOREGROUND_COLOR; + break; + case eColorID_IMERawInputUnderline: + case eColorID_IMEConvertedTextUnderline: + aColor = NS_SAME_AS_FOREGROUND_COLOR; + break; + case eColorID_IMESelectedRawTextUnderline: + case eColorID_IMESelectedConvertedTextUnderline: + aColor = NS_TRANSPARENT; + break; + case eColorID_SpellCheckerUnderline: + aColor = RED_COLOR; + break; + + // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors + case eColorID_activeborder: + // active window border + aColor = mSystemColors.colorBackground; + break; + case eColorID_activecaption: + // active window caption background + aColor = mSystemColors.colorBackground; + break; + case eColorID_appworkspace: + // MDI background color + aColor = mSystemColors.colorBackground; + break; + case eColorID_background: + // desktop background + aColor = mSystemColors.colorBackground; + break; + case eColorID_captiontext: + // text in active window caption, size box, and scrollbar arrow box (!) + aColor = mSystemColors.colorForeground; + break; + case eColorID_graytext: + // disabled text in windows, menus, etc. + aColor = mSystemColors.textColorTertiary; + break; + case eColorID_highlight: + // background of selected item + aColor = mSystemColors.textColorHighlight; + break; + case eColorID_highlighttext: + // text of selected item + aColor = mSystemColors.textColorPrimaryInverse; + break; + case eColorID_inactiveborder: + // inactive window border + aColor = mSystemColors.colorBackground; + break; + case eColorID_inactivecaption: + // inactive window caption + aColor = mSystemColors.colorBackground; + break; + case eColorID_inactivecaptiontext: + // text in inactive window caption + aColor = mSystemColors.textColorTertiary; + break; + case eColorID_infobackground: + // tooltip background color + aColor = mSystemColors.colorBackground; + break; + case eColorID_infotext: + // tooltip text color + aColor = mSystemColors.colorForeground; + break; + case eColorID_menu: + // menu background + aColor = mSystemColors.colorBackground; + break; + case eColorID_menutext: + // menu text + aColor = mSystemColors.colorForeground; + break; + case eColorID_scrollbar: + // scrollbar gray area + aColor = mSystemColors.colorBackground; + break; + + case eColorID_threedface: + case eColorID_buttonface: + // 3-D face color + aColor = mSystemColors.colorBackground; + break; + + case eColorID_buttontext: + // text on push buttons + aColor = mSystemColors.colorForeground; + break; + + case eColorID_buttonhighlight: + // 3-D highlighted edge color + case eColorID_threedhighlight: + // 3-D highlighted outer edge color + aColor = LIGHT_GRAY_COLOR; + break; + + case eColorID_threedlightshadow: + // 3-D highlighted inner edge color + aColor = mSystemColors.colorBackground; + break; + + case eColorID_buttonshadow: + // 3-D shadow edge color + case eColorID_threedshadow: + // 3-D shadow inner edge color + aColor = GRAY_COLOR; + break; + + case eColorID_threeddarkshadow: + // 3-D shadow outer edge color + aColor = BLACK_COLOR; + break; + + case eColorID_window: + case eColorID_windowframe: + aColor = mSystemColors.colorBackground; + break; + + case eColorID_windowtext: + aColor = mSystemColors.textColorPrimary; + break; + + case eColorID__moz_eventreerow: + case eColorID__moz_field: + aColor = mSystemColors.colorBackground; + break; + case eColorID__moz_fieldtext: + aColor = mSystemColors.textColorPrimary; + break; + case eColorID__moz_dialog: + aColor = mSystemColors.colorBackground; + break; + case eColorID__moz_dialogtext: + aColor = mSystemColors.colorForeground; + break; + case eColorID__moz_dragtargetzone: + aColor = mSystemColors.textColorHighlight; + break; + case eColorID__moz_buttondefault: + // default button border color + aColor = BLACK_COLOR; + break; + case eColorID__moz_buttonhoverface: + aColor = BG_PRELIGHT_COLOR; + break; + case eColorID__moz_buttonhovertext: + aColor = FG_PRELIGHT_COLOR; + break; + case eColorID__moz_cellhighlight: + case eColorID__moz_html_cellhighlight: + aColor = mSystemColors.textColorHighlight; + break; + case eColorID__moz_cellhighlighttext: + case eColorID__moz_html_cellhighlighttext: + aColor = mSystemColors.textColorPrimaryInverse; + break; + case eColorID__moz_menuhover: + aColor = BG_PRELIGHT_COLOR; + break; + case eColorID__moz_menuhovertext: + aColor = FG_PRELIGHT_COLOR; + break; + case eColorID__moz_oddtreerow: + aColor = NS_TRANSPARENT; + break; + case eColorID__moz_nativehyperlinktext: + aColor = NS_SAME_AS_FOREGROUND_COLOR; + break; + case eColorID__moz_comboboxtext: + aColor = mSystemColors.colorForeground; + break; + case eColorID__moz_combobox: + aColor = mSystemColors.colorBackground; + break; + case eColorID__moz_menubartext: + aColor = mSystemColors.colorForeground; + break; + case eColorID__moz_menubarhovertext: + aColor = FG_PRELIGHT_COLOR; + break; + default: + /* default color is BLACK */ + aColor = 0; + rv = NS_ERROR_FAILURE; + break; + } + + return rv; +} + + +nsresult +nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult) +{ + nsresult rv = nsXPLookAndFeel::GetIntImpl(aID, aResult); + if (NS_SUCCEEDED(rv)) + return rv; + + rv = NS_OK; + + switch (aID) { + case eIntID_CaretBlinkTime: + aResult = 500; + break; + + case eIntID_CaretWidth: + aResult = 1; + break; + + case eIntID_ShowCaretDuringSelection: + aResult = 0; + break; + + case eIntID_SelectTextfieldsOnKeyFocus: + // Select textfield content when focused by kbd + // used by EventStateManager::sTextfieldSelectModel + aResult = 1; + break; + + case eIntID_SubmenuDelay: + aResult = 200; + break; + + case eIntID_TooltipDelay: + aResult = 500; + break; + + case eIntID_MenusCanOverlapOSBar: + // we want XUL popups to be able to overlap the task bar. + aResult = 1; + break; + + case eIntID_ScrollArrowStyle: + aResult = eScrollArrowStyle_Single; + break; + + case eIntID_ScrollSliderStyle: + aResult = eScrollThumbStyle_Proportional; + break; + + case eIntID_TouchEnabled: + aResult = 1; + break; + + case eIntID_ColorPickerAvailable: + aResult = 1; + break; + + case eIntID_WindowsDefaultTheme: + case eIntID_WindowsThemeIdentifier: + case eIntID_OperatingSystemVersionIdentifier: + aResult = 0; + rv = NS_ERROR_NOT_IMPLEMENTED; + break; + + case eIntID_SpellCheckerUnderlineStyle: + aResult = NS_STYLE_TEXT_DECORATION_STYLE_WAVY; + break; + + case eIntID_ScrollbarButtonAutoRepeatBehavior: + aResult = 0; + break; + + case eIntID_ContextMenuOffsetVertical: + case eIntID_ContextMenuOffsetHorizontal: + aResult = 2; + break; + + default: + aResult = 0; + rv = NS_ERROR_FAILURE; + } + + return rv; +} + +nsresult +nsLookAndFeel::GetFloatImpl(FloatID aID, float &aResult) +{ + nsresult rv = nsXPLookAndFeel::GetFloatImpl(aID, aResult); + if (NS_SUCCEEDED(rv)) + return rv; + rv = NS_OK; + + switch (aID) { + case eFloatID_IMEUnderlineRelativeSize: + aResult = 1.0f; + break; + + case eFloatID_SpellCheckerUnderlineRelativeSize: + aResult = 1.0f; + break; + + default: + aResult = -1.0; + rv = NS_ERROR_FAILURE; + break; + } + return rv; +} + +/*virtual*/ +bool +nsLookAndFeel::GetFontImpl(FontID aID, nsString& aFontName, + gfxFontStyle& aFontStyle, + float aDevPixPerCSSPixel) +{ + aFontName.AssignLiteral("\"Droid Sans\""); + aFontStyle.style = NS_FONT_STYLE_NORMAL; + aFontStyle.weight = NS_FONT_WEIGHT_NORMAL; + aFontStyle.stretch = NS_FONT_STRETCH_NORMAL; + aFontStyle.size = 9.0 * 96.0f / 72.0f * aDevPixPerCSSPixel; + aFontStyle.systemFont = true; + return true; +} + +/*virtual*/ +bool +nsLookAndFeel::GetEchoPasswordImpl() +{ + if (!mInitializedShowPassword) { + if (XRE_IsParentProcess()) { + mShowPassword = java::GeckoAppShell::GetShowPasswordSetting(); + } else { + ContentChild::GetSingleton()->SendGetShowPasswordSetting(&mShowPassword); + } + mInitializedShowPassword = true; + } + return mShowPassword; +} + +uint32_t +nsLookAndFeel::GetPasswordMaskDelayImpl() +{ + // This value is hard-coded in Android OS's PasswordTransformationMethod.java + return 1500; +} + +/* virtual */ +char16_t +nsLookAndFeel::GetPasswordCharacterImpl() +{ + // This value is hard-coded in Android OS's PasswordTransformationMethod.java + return UNICODE_BULLET; +} diff --git a/widget/android/nsLookAndFeel.h b/widget/android/nsLookAndFeel.h new file mode 100644 index 000000000..9b33279a8 --- /dev/null +++ b/widget/android/nsLookAndFeel.h @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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 __nsLookAndFeel +#define __nsLookAndFeel + +#include "nsXPLookAndFeel.h" +#include "AndroidBridge.h" + +class nsLookAndFeel: public nsXPLookAndFeel +{ +public: + nsLookAndFeel(); + virtual ~nsLookAndFeel(); + + virtual nsresult NativeGetColor(ColorID aID, nscolor &aResult); + virtual nsresult GetIntImpl(IntID aID, int32_t &aResult); + virtual nsresult GetFloatImpl(FloatID aID, float &aResult); + virtual bool GetFontImpl(FontID aID, nsString& aName, gfxFontStyle& aStyle, + float aDevPixPerCSSPixel); + virtual bool GetEchoPasswordImpl(); + virtual uint32_t GetPasswordMaskDelayImpl(); + virtual char16_t GetPasswordCharacterImpl(); + +protected: + static bool mInitializedSystemColors; + static mozilla::AndroidSystemColors mSystemColors; + static bool mInitializedShowPassword; + static bool mShowPassword; + + nsresult GetSystemColors(); + nsresult CallRemoteGetSystemColors(); +}; + +#endif diff --git a/widget/android/nsPrintOptionsAndroid.cpp b/widget/android/nsPrintOptionsAndroid.cpp new file mode 100644 index 000000000..03afba827 --- /dev/null +++ b/widget/android/nsPrintOptionsAndroid.cpp @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "nsPrintOptionsAndroid.h" + +#include "nsPrintSettingsImpl.h" + +class nsPrintSettingsAndroid : public nsPrintSettings { +public: + nsPrintSettingsAndroid() + { + // The aim here is to set up the objects enough that silent printing works + SetOutputFormat(nsIPrintSettings::kOutputFormatPDF); + SetPrinterName(u"PDF printer"); + + } +}; + +nsPrintOptionsAndroid::nsPrintOptionsAndroid() +{ +} + +nsPrintOptionsAndroid::~nsPrintOptionsAndroid() +{ +} + +nsresult +nsPrintOptionsAndroid::_CreatePrintSettings(nsIPrintSettings** _retval) +{ + nsPrintSettings * printSettings = new nsPrintSettingsAndroid(); + NS_ENSURE_TRUE(printSettings, NS_ERROR_OUT_OF_MEMORY); + NS_ADDREF(*_retval = printSettings); + (void)InitPrintSettingsFromPrefs(*_retval, false, + nsIPrintSettings::kInitSaveAll); + return NS_OK; +} diff --git a/widget/android/nsPrintOptionsAndroid.h b/widget/android/nsPrintOptionsAndroid.h new file mode 100644 index 000000000..27c4cce83 --- /dev/null +++ b/widget/android/nsPrintOptionsAndroid.h @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 nsPrintOptionsAndroid_h__ +#define nsPrintOptionsAndroid_h__ + +#include "nsPrintOptionsImpl.h" +#include "nsIPrintSettings.h" + +//***************************************************************************** +//*** nsPrintOptions +//***************************************************************************** +class nsPrintOptionsAndroid : public nsPrintOptions +{ +public: + nsPrintOptionsAndroid(); + virtual ~nsPrintOptionsAndroid(); + + nsresult _CreatePrintSettings(nsIPrintSettings** _retval) override; +}; + +#endif /* nsPrintOptionsAndroid_h__ */ diff --git a/widget/android/nsScreenManagerAndroid.cpp b/widget/android/nsScreenManagerAndroid.cpp new file mode 100644 index 000000000..4a79b9dab --- /dev/null +++ b/widget/android/nsScreenManagerAndroid.cpp @@ -0,0 +1,264 @@ +/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set sw=4 ts=4 expandtab: + * 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/. */ + +#define MOZ_FATAL_ASSERTIONS_FOR_THREAD_SAFETY + +#include "mozilla/SyncRunnable.h" +#include "nsScreenManagerAndroid.h" +#include "nsServiceManagerUtils.h" +#include "AndroidRect.h" +#include "FennecJNINatives.h" +#include "nsAppShell.h" +#include "nsThreadUtils.h" + +#include <android/log.h> +#include <mozilla/jni/Refs.h> + +#define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "nsScreenManagerAndroid", ## args) + +using namespace mozilla; +using namespace mozilla::java; + +static uint32_t sScreenId = 0; +const uint32_t PRIMARY_SCREEN_ID = 0; + +nsScreenAndroid::nsScreenAndroid(DisplayType aDisplayType, nsIntRect aRect) + : mId(sScreenId++) + , mDisplayType(aDisplayType) + , mRect(aRect) + , mDensity(0.0) +{ + // ensure that the ID of the primary screen would be PRIMARY_SCREEN_ID. + if (mDisplayType == DisplayType::DISPLAY_PRIMARY) { + mId = PRIMARY_SCREEN_ID; + } +} + +nsScreenAndroid::~nsScreenAndroid() +{ +} + +float +nsScreenAndroid::GetDensity() { + if (mDensity != 0.0) { + return mDensity; + } + if (mDisplayType == DisplayType::DISPLAY_PRIMARY) { + mDensity = mozilla::jni::IsAvailable() ? GeckoAppShell::GetDensity() + : 1.0; // xpcshell most likely + return mDensity; + } + return 1.0; +} + +NS_IMETHODIMP +nsScreenAndroid::GetId(uint32_t *outId) +{ + *outId = mId; + return NS_OK; +} + +NS_IMETHODIMP +nsScreenAndroid::GetRect(int32_t *outLeft, int32_t *outTop, int32_t *outWidth, int32_t *outHeight) +{ + if (mDisplayType != DisplayType::DISPLAY_PRIMARY) { + *outLeft = mRect.x; + *outTop = mRect.y; + *outWidth = mRect.width; + *outHeight = mRect.height; + + return NS_OK; + } + + if (!mozilla::jni::IsAvailable()) { + // xpcshell most likely + *outLeft = *outTop = *outWidth = *outHeight = 0; + return NS_ERROR_FAILURE; + } + + java::sdk::Rect::LocalRef rect = java::GeckoAppShell::GetScreenSize(); + rect->Left(outLeft); + rect->Top(outTop); + rect->Width(outWidth); + rect->Height(outHeight); + + return NS_OK; +} + + +NS_IMETHODIMP +nsScreenAndroid::GetAvailRect(int32_t *outLeft, int32_t *outTop, int32_t *outWidth, int32_t *outHeight) +{ + return GetRect(outLeft, outTop, outWidth, outHeight); +} + + + +NS_IMETHODIMP +nsScreenAndroid::GetPixelDepth(int32_t *aPixelDepth) +{ + if (!mozilla::jni::IsAvailable()) { + // xpcshell most likely + *aPixelDepth = 16; + return NS_ERROR_FAILURE; + } + + *aPixelDepth = java::GeckoAppShell::GetScreenDepth(); + return NS_OK; +} + + +NS_IMETHODIMP +nsScreenAndroid::GetColorDepth(int32_t *aColorDepth) +{ + return GetPixelDepth(aColorDepth); +} + + +void +nsScreenAndroid::ApplyMinimumBrightness(uint32_t aBrightness) +{ + if (mDisplayType == DisplayType::DISPLAY_PRIMARY && + mozilla::jni::IsAvailable()) { + java::GeckoAppShell::SetKeepScreenOn(aBrightness == BRIGHTNESS_FULL); + } +} + +class nsScreenManagerAndroid::ScreenManagerHelperSupport final + : public ScreenManagerHelper::Natives<ScreenManagerHelperSupport> +{ +public: + typedef ScreenManagerHelper::Natives<ScreenManagerHelperSupport> Base; + + static int32_t AddDisplay(int32_t aDisplayType, int32_t aWidth, int32_t aHeight, float aDensity) { + int32_t screenId = -1; // return value + nsCOMPtr<nsIThread> mainThread = do_GetMainThread(); + SyncRunnable::DispatchToThread(mainThread, NS_NewRunnableFunction( + [&aDisplayType, &aWidth, &aHeight, &aDensity, &screenId] { + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr<nsIScreenManager> screenMgr = + do_GetService("@mozilla.org/gfx/screenmanager;1"); + MOZ_ASSERT(screenMgr, "Failed to get nsIScreenManager"); + + RefPtr<nsScreenManagerAndroid> screenMgrAndroid = + (nsScreenManagerAndroid*) screenMgr.get(); + RefPtr<nsScreenAndroid> screen = + screenMgrAndroid->AddScreen(static_cast<DisplayType>(aDisplayType), + nsIntRect(0, 0, aWidth, aHeight)); + MOZ_ASSERT(screen); + screen->SetDensity(aDensity); + screenId = static_cast<int32_t>(screen->GetId()); + }).take()); + return screenId; + } + + static void RemoveDisplay(int32_t aScreenId) { + nsCOMPtr<nsIThread> mainThread = do_GetMainThread(); + SyncRunnable::DispatchToThread(mainThread, NS_NewRunnableFunction( + [&aScreenId] { + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr<nsIScreenManager> screenMgr = + do_GetService("@mozilla.org/gfx/screenmanager;1"); + MOZ_ASSERT(screenMgr, "Failed to get nsIScreenManager"); + + RefPtr<nsScreenManagerAndroid> screenMgrAndroid = + (nsScreenManagerAndroid*) screenMgr.get(); + screenMgrAndroid->RemoveScreen(aScreenId); + }).take()); + } +}; + +NS_IMPL_ISUPPORTS(nsScreenManagerAndroid, nsIScreenManager) + +nsScreenManagerAndroid::nsScreenManagerAndroid() +{ + if (mozilla::jni::IsAvailable()) { + ScreenManagerHelperSupport::Base::Init(); + } + nsCOMPtr<nsIScreen> screen = AddScreen(DisplayType::DISPLAY_PRIMARY); + MOZ_ASSERT(screen); +} + +nsScreenManagerAndroid::~nsScreenManagerAndroid() +{ +} + +NS_IMETHODIMP +nsScreenManagerAndroid::GetPrimaryScreen(nsIScreen **outScreen) +{ + ScreenForId(PRIMARY_SCREEN_ID, outScreen); + return NS_OK; +} + +NS_IMETHODIMP +nsScreenManagerAndroid::ScreenForId(uint32_t aId, + nsIScreen **outScreen) +{ + for (size_t i = 0; i < mScreens.Length(); ++i) { + if (aId == mScreens[i]->GetId()) { + nsCOMPtr<nsIScreen> screen = (nsIScreen*) mScreens[i]; + screen.forget(outScreen); + return NS_OK; + } + } + + *outScreen = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +nsScreenManagerAndroid::ScreenForRect(int32_t inLeft, + int32_t inTop, + int32_t inWidth, + int32_t inHeight, + nsIScreen **outScreen) +{ + // Not support to query non-primary screen with rect. + return GetPrimaryScreen(outScreen); +} + +NS_IMETHODIMP +nsScreenManagerAndroid::ScreenForNativeWidget(void *aWidget, nsIScreen **outScreen) +{ + // Not support to query non-primary screen with native widget. + return GetPrimaryScreen(outScreen); +} + +NS_IMETHODIMP +nsScreenManagerAndroid::GetNumberOfScreens(uint32_t *aNumberOfScreens) +{ + *aNumberOfScreens = mScreens.Length(); + return NS_OK; +} + +NS_IMETHODIMP +nsScreenManagerAndroid::GetSystemDefaultScale(float *aDefaultScale) +{ + *aDefaultScale = 1.0f; + return NS_OK; +} + +already_AddRefed<nsScreenAndroid> +nsScreenManagerAndroid::AddScreen(DisplayType aDisplayType, nsIntRect aRect) +{ + ALOG("nsScreenManagerAndroid: add %s screen", + (aDisplayType == DisplayType::DISPLAY_PRIMARY ? "PRIMARY" : + (aDisplayType == DisplayType::DISPLAY_EXTERNAL ? "EXTERNAL" : + "VIRTUAL"))); + RefPtr<nsScreenAndroid> screen = new nsScreenAndroid(aDisplayType, aRect); + mScreens.AppendElement(screen); + return screen.forget(); +} + +void +nsScreenManagerAndroid::RemoveScreen(uint32_t aScreenId) +{ + for (size_t i = 0; i < mScreens.Length(); i++) { + if (aScreenId == mScreens[i]->GetId()) { + mScreens.RemoveElementAt(i); + } + } +} diff --git a/widget/android/nsScreenManagerAndroid.h b/widget/android/nsScreenManagerAndroid.h new file mode 100644 index 000000000..cf8bfb245 --- /dev/null +++ b/widget/android/nsScreenManagerAndroid.h @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: ts=4 sw=4 expandtab: + * 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 nsScreenManagerAndroid_h___ +#define nsScreenManagerAndroid_h___ + +#include "nsCOMPtr.h" + +#include "nsBaseScreen.h" +#include "nsIScreenManager.h" +#include "nsRect.h" +#include "mozilla/WidgetUtils.h" + +class nsScreenAndroid final : public nsBaseScreen +{ +public: + nsScreenAndroid(DisplayType aDisplayType, nsIntRect aRect); + ~nsScreenAndroid(); + + NS_IMETHOD GetId(uint32_t* aId) override; + NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) override; + NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) override; + NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) override; + NS_IMETHOD GetColorDepth(int32_t* aColorDepth) override; + + uint32_t GetId() const { return mId; }; + DisplayType GetDisplayType() const { return mDisplayType; } + + void SetDensity(double aDensity) { mDensity = aDensity; } + float GetDensity(); + +protected: + virtual void ApplyMinimumBrightness(uint32_t aBrightness) override; + +private: + uint32_t mId; + DisplayType mDisplayType; + nsIntRect mRect; + float mDensity; +}; + +class nsScreenManagerAndroid final : public nsIScreenManager +{ +private: + ~nsScreenManagerAndroid(); + +public: + class ScreenManagerHelperSupport; + + nsScreenManagerAndroid(); + + NS_DECL_ISUPPORTS + NS_DECL_NSISCREENMANAGER + + already_AddRefed<nsScreenAndroid> AddScreen(DisplayType aDisplayType, + nsIntRect aRect = nsIntRect()); + void RemoveScreen(uint32_t aScreenId); + +protected: + nsTArray<RefPtr<nsScreenAndroid>> mScreens; +}; + +#endif /* nsScreenManagerAndroid_h___ */ diff --git a/widget/android/nsWidgetFactory.cpp b/widget/android/nsWidgetFactory.cpp new file mode 100644 index 000000000..bd930e4a4 --- /dev/null +++ b/widget/android/nsWidgetFactory.cpp @@ -0,0 +1,132 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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 "mozilla/ModuleUtils.h" +#include "mozilla/WidgetUtils.h" + +#include "nsCOMPtr.h" +#include "nsWidgetsCID.h" +#include "nsAppShell.h" +#include "AndroidBridge.h" + +#include "nsWindow.h" +#include "nsLookAndFeel.h" +#include "nsAppShellSingleton.h" +#include "nsScreenManagerAndroid.h" + +#include "nsIdleServiceAndroid.h" +#include "nsClipboard.h" +#include "nsClipboardHelper.h" +#include "nsTransferable.h" +#include "nsPrintOptionsAndroid.h" +#include "nsPrintSession.h" +#include "nsDeviceContextAndroid.h" +#include "nsHTMLFormatConverter.h" +#include "nsXULAppAPI.h" +#include "nsAndroidProtocolHandler.h" + +#include "nsToolkitCompsCID.h" +#include "AndroidAlerts.h" + +NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerAndroid) +NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIdleServiceAndroid, nsIdleServiceAndroid::GetInstance) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper) +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintOptionsAndroid, Init) +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSession, Init) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceContextSpecAndroid) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsAndroidBridge) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsAndroidProtocolHandler) + +#include "GfxInfo.h" +namespace mozilla { +namespace widget { +// This constructor should really be shared with all platforms. +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(GfxInfo, Init) +NS_GENERIC_FACTORY_CONSTRUCTOR(AndroidAlerts) +} +} + +NS_DEFINE_NAMED_CID(NS_APPSHELL_CID); +NS_DEFINE_NAMED_CID(NS_WINDOW_CID); +NS_DEFINE_NAMED_CID(NS_CHILD_CID); +NS_DEFINE_NAMED_CID(NS_SCREENMANAGER_CID); +NS_DEFINE_NAMED_CID(NS_IDLE_SERVICE_CID); +NS_DEFINE_NAMED_CID(NS_TRANSFERABLE_CID); +NS_DEFINE_NAMED_CID(NS_CLIPBOARD_CID); +NS_DEFINE_NAMED_CID(NS_CLIPBOARDHELPER_CID); +NS_DEFINE_NAMED_CID(NS_PRINTSETTINGSSERVICE_CID); +NS_DEFINE_NAMED_CID(NS_PRINTSESSION_CID); +NS_DEFINE_NAMED_CID(NS_DEVICE_CONTEXT_SPEC_CID); +NS_DEFINE_NAMED_CID(NS_HTMLFORMATCONVERTER_CID); +NS_DEFINE_NAMED_CID(NS_GFXINFO_CID); +NS_DEFINE_NAMED_CID(NS_ANDROIDBRIDGE_CID); +NS_DEFINE_NAMED_CID(NS_ANDROIDPROTOCOLHANDLER_CID); +NS_DEFINE_NAMED_CID(NS_SYSTEMALERTSSERVICE_CID); + +static const mozilla::Module::CIDEntry kWidgetCIDs[] = { + { &kNS_WINDOW_CID, false, nullptr, nsWindowConstructor }, + { &kNS_CHILD_CID, false, nullptr, nsWindowConstructor }, + { &kNS_APPSHELL_CID, false, nullptr, nsAppShellConstructor }, + { &kNS_SCREENMANAGER_CID, false, nullptr, nsScreenManagerAndroidConstructor }, + { &kNS_IDLE_SERVICE_CID, false, nullptr, nsIdleServiceAndroidConstructor }, + { &kNS_TRANSFERABLE_CID, false, nullptr, nsTransferableConstructor }, + { &kNS_CLIPBOARD_CID, false, nullptr, nsClipboardConstructor }, + { &kNS_CLIPBOARDHELPER_CID, false, nullptr, nsClipboardHelperConstructor }, + { &kNS_PRINTSETTINGSSERVICE_CID, false, nullptr, nsPrintOptionsAndroidConstructor }, + { &kNS_PRINTSESSION_CID, false, nullptr, nsPrintSessionConstructor }, + { &kNS_DEVICE_CONTEXT_SPEC_CID, false, nullptr, nsDeviceContextSpecAndroidConstructor }, + { &kNS_HTMLFORMATCONVERTER_CID, false, nullptr, nsHTMLFormatConverterConstructor }, + { &kNS_GFXINFO_CID, false, nullptr, mozilla::widget::GfxInfoConstructor }, + { &kNS_ANDROIDBRIDGE_CID, false, nullptr, nsAndroidBridgeConstructor }, + { &kNS_ANDROIDPROTOCOLHANDLER_CID, false, nullptr, nsAndroidProtocolHandlerConstructor }, + { &kNS_SYSTEMALERTSSERVICE_CID, false, nullptr, mozilla::widget::AndroidAlertsConstructor }, + { nullptr } +}; + +static const mozilla::Module::ContractIDEntry kWidgetContracts[] = { + { "@mozilla.org/widgets/window/android;1", &kNS_WINDOW_CID }, + { "@mozilla.org/widgets/child_window/android;1", &kNS_CHILD_CID }, + { "@mozilla.org/widget/appshell/android;1", &kNS_APPSHELL_CID }, + { "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID }, + { "@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID }, + { "@mozilla.org/widget/transferable;1", &kNS_TRANSFERABLE_CID }, + { "@mozilla.org/widget/clipboard;1", &kNS_CLIPBOARD_CID }, + { "@mozilla.org/widget/clipboardhelper;1", &kNS_CLIPBOARDHELPER_CID }, + { "@mozilla.org/gfx/printsettings-service;1", &kNS_PRINTSETTINGSSERVICE_CID }, + { "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID }, + { "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID }, + { "@mozilla.org/widget/htmlformatconverter;1", &kNS_HTMLFORMATCONVERTER_CID }, + { "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID }, + { "@mozilla.org/android/bridge;1", &kNS_ANDROIDBRIDGE_CID }, + { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "android", &kNS_ANDROIDPROTOCOLHANDLER_CID }, + { NS_SYSTEMALERTSERVICE_CONTRACTID, &kNS_SYSTEMALERTSSERVICE_CID }, + { nullptr } +}; + +static void +nsWidgetAndroidModuleDtor() +{ + // Shutdown all XP level widget classes. + mozilla::widget::WidgetUtils::Shutdown(); + + nsLookAndFeel::Shutdown(); + nsAppShellShutdown(); +} + +static const mozilla::Module kWidgetModule = { + mozilla::Module::kVersion, + kWidgetCIDs, + kWidgetContracts, + nullptr, + nullptr, + nsAppShellInit, + nsWidgetAndroidModuleDtor +}; + +NSMODULE_DEFN(nsWidgetAndroidModule) = &kWidgetModule; diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp new file mode 100644 index 000000000..9423a4a26 --- /dev/null +++ b/widget/android/nsWindow.cpp @@ -0,0 +1,3638 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- + * vim: set sw=4 ts=4 expandtab: + * 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 <android/log.h> +#include <android/native_window.h> +#include <android/native_window_jni.h> +#include <math.h> +#include <unistd.h> + +#include "mozilla/IMEStateManager.h" +#include "mozilla/MiscEvents.h" +#include "mozilla/MouseEvents.h" +#include "mozilla/TextComposition.h" +#include "mozilla/TextEvents.h" +#include "mozilla/TouchEvents.h" +#include "mozilla/TypeTraits.h" +#include "mozilla/WeakPtr.h" + +#include "mozilla/dom/ContentParent.h" +#include "mozilla/dom/ContentChild.h" +#include "mozilla/Unused.h" +#include "mozilla/Preferences.h" +#include "mozilla/layers/RenderTrace.h" +#include <algorithm> + +using mozilla::dom::ContentParent; +using mozilla::dom::ContentChild; +using mozilla::Unused; + +#include "nsWindow.h" + +#include "nsIBaseWindow.h" +#include "nsIDOMChromeWindow.h" +#include "nsIObserverService.h" +#include "nsISelection.h" +#include "nsISupportsPrimitives.h" +#include "nsIWidgetListener.h" +#include "nsIWindowWatcher.h" +#include "nsIXULWindow.h" + +#include "nsAppShell.h" +#include "nsFocusManager.h" +#include "nsIdleService.h" +#include "nsLayoutUtils.h" +#include "nsViewManager.h" + +#include "WidgetUtils.h" + +#include "nsIDOMSimpleGestureEvent.h" + +#include "nsGkAtoms.h" +#include "nsWidgetsCID.h" +#include "nsGfxCIID.h" + +#include "gfxContext.h" + +#include "Layers.h" +#include "mozilla/layers/LayerManagerComposite.h" +#include "mozilla/layers/AsyncCompositionManager.h" +#include "mozilla/layers/APZEventState.h" +#include "mozilla/layers/APZThreadUtils.h" +#include "mozilla/layers/IAPZCTreeManager.h" +#include "GLContext.h" +#include "GLContextProvider.h" +#include "ScopedGLHelpers.h" +#include "mozilla/layers/CompositorOGL.h" +#include "AndroidContentController.h" + +#include "nsTArray.h" + +#include "AndroidBridge.h" +#include "AndroidBridgeUtilities.h" +#include "android_npapi.h" +#include "FennecJNINatives.h" +#include "GeneratedJNINatives.h" +#include "KeyEvent.h" +#include "MotionEvent.h" + +#include "imgIEncoder.h" + +#include "nsString.h" +#include "GeckoProfiler.h" // For PROFILER_LABEL +#include "nsIXULRuntime.h" +#include "nsPrintfCString.h" + +using namespace mozilla; +using namespace mozilla::dom; +using namespace mozilla::layers; +using namespace mozilla::java; +using namespace mozilla::widget; + +NS_IMPL_ISUPPORTS_INHERITED0(nsWindow, nsBaseWidget) + +#include "mozilla/layers/CompositorBridgeChild.h" +#include "mozilla/layers/CompositorBridgeParent.h" +#include "mozilla/layers/CompositorSession.h" +#include "mozilla/layers/LayerTransactionParent.h" +#include "mozilla/Services.h" +#include "nsThreadUtils.h" + +// All the toplevel windows that have been created; these are in +// stacking order, so the window at gTopLevelWindows[0] is the topmost +// one. +static nsTArray<nsWindow*> gTopLevelWindows; + +static bool sFailedToCreateGLContext = false; + +// Multitouch swipe thresholds in inches +static const double SWIPE_MAX_PINCH_DELTA_INCHES = 0.4; +static const double SWIPE_MIN_DISTANCE_INCHES = 0.6; + +// Sync with GeckoEditableView class +static const int IME_MONITOR_CURSOR_ONE_SHOT = 1; +static const int IME_MONITOR_CURSOR_START_MONITOR = 2; +static const int IME_MONITOR_CURSOR_END_MONITOR = 3; + +static Modifiers GetModifiers(int32_t metaState); + +template<typename Lambda, bool IsStatic, typename InstanceType, class Impl> +class nsWindow::WindowEvent : public nsAppShell::LambdaEvent<Lambda> +{ + typedef nsAppShell::Event Event; + typedef nsAppShell::LambdaEvent<Lambda> Base; + + bool IsStaleCall() + { + if (IsStatic) { + // Static calls are never stale. + return false; + } + + JNIEnv* const env = mozilla::jni::GetEnvForThread(); + + const auto natives = reinterpret_cast<mozilla::WeakPtr<Impl>*>( + jni::GetNativeHandle(env, mInstance.Get())); + MOZ_CATCH_JNI_EXCEPTION(env); + + // The call is stale if the nsWindow has been destroyed on the + // Gecko side, but the Java object is still attached to it through + // a weak pointer. Stale calls should be discarded. Note that it's + // an error if natives is nullptr here; we return false but the + // native call will throw an error. + return natives && !natives->get(); + } + + const InstanceType mInstance; + const Event::Type mEventType; + +public: + WindowEvent(Lambda&& aLambda, + InstanceType&& aInstance, + Event::Type aEventType = Event::Type::kGeneralActivity) + : Base(mozilla::Move(aLambda)) + , mInstance(mozilla::Move(aInstance)) + , mEventType(aEventType) + {} + + WindowEvent(Lambda&& aLambda, + Event::Type aEventType = Event::Type::kGeneralActivity) + : Base(mozilla::Move(aLambda)) + , mInstance(Base::lambda.GetThisArg()) + , mEventType(aEventType) + {} + + void Run() override + { + if (!IsStaleCall()) { + return Base::Run(); + } + } + + Event::Type ActivityType() const override + { + return mEventType; + } +}; + +template<class Impl> +template<class Instance, typename... Args> void +nsWindow::NativePtr<Impl>::Attach(Instance aInstance, nsWindow* aWindow, + Args&&... aArgs) +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!mPtr && !mImpl); + + auto impl = mozilla::MakeUnique<Impl>( + this, aWindow, mozilla::Forward<Args>(aArgs)...); + mImpl = impl.get(); + + Impl::AttachNative(aInstance, mozilla::Move(impl)); +} + +template<class Impl> void +nsWindow::NativePtr<Impl>::Detach() +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(mPtr && mImpl); + + mImpl->OnDetach(); + { + Locked implLock(*this); + mImpl = nullptr; + } + + typename WindowPtr<Impl>::Locked lock(*mPtr); + mPtr->mWindow = nullptr; + mPtr->mPtr = nullptr; + mPtr = nullptr; +} + +template<class Impl> +class nsWindow::NativePtr<Impl>::Locked final : private MutexAutoLock +{ + Impl* const mImpl; + +public: + Locked(NativePtr<Impl>& aPtr) + : MutexAutoLock(aPtr.mImplLock) + , mImpl(aPtr.mImpl) + {} + + operator Impl*() const { return mImpl; } + Impl* operator->() const { return mImpl; } +}; + +template<class Impl> +class nsWindow::WindowPtr final +{ + friend NativePtr<Impl>; + + NativePtr<Impl>* mPtr; + nsWindow* mWindow; + Mutex mWindowLock; + +public: + class Locked final : private MutexAutoLock + { + nsWindow* const mWindow; + + public: + Locked(WindowPtr<Impl>& aPtr) + : MutexAutoLock(aPtr.mWindowLock) + , mWindow(aPtr.mWindow) + {} + + operator nsWindow*() const { return mWindow; } + nsWindow* operator->() const { return mWindow; } + }; + + WindowPtr(NativePtr<Impl>* aPtr, nsWindow* aWindow) + : mPtr(aPtr) + , mWindow(aWindow) + , mWindowLock(NativePtr<Impl>::sName) + { + MOZ_ASSERT(NS_IsMainThread()); + mPtr->mPtr = this; + } + + ~WindowPtr() + { + MOZ_ASSERT(NS_IsMainThread()); + if (!mPtr) { + return; + } + mPtr->mPtr = nullptr; + mPtr->mImpl = nullptr; + } + + operator nsWindow*() const + { + MOZ_ASSERT(NS_IsMainThread()); + return mWindow; + } + + nsWindow* operator->() const { return operator nsWindow*(); } +}; + + +class nsWindow::GeckoViewSupport final + : public GeckoView::Window::Natives<GeckoViewSupport> + , public GeckoEditable::Natives<GeckoViewSupport> + , public SupportsWeakPtr<GeckoViewSupport> +{ + nsWindow& window; + +public: + typedef GeckoView::Window::Natives<GeckoViewSupport> Base; + typedef GeckoEditable::Natives<GeckoViewSupport> EditableBase; + + MOZ_DECLARE_WEAKREFERENCE_TYPENAME(GeckoViewSupport); + + template<typename Functor> + static void OnNativeCall(Functor&& aCall) + { + if (aCall.IsTarget(&Open) && NS_IsMainThread()) { + // Gecko state probably just switched to PROFILE_READY, and the + // event loop is not running yet. Skip the event loop here so we + // can get a head start on opening our window. + return aCall(); + } + + const nsAppShell::Event::Type eventType = + aCall.IsTarget(&GeckoViewSupport::OnKeyEvent) || + aCall.IsTarget(&GeckoViewSupport::OnImeReplaceText) || + aCall.IsTarget(&GeckoViewSupport::OnImeUpdateComposition) ? + nsAppShell::Event::Type::kUIActivity : + nsAppShell::Event::Type::kGeneralActivity; + + nsAppShell::PostEvent(mozilla::MakeUnique<WindowEvent<Functor>>( + mozilla::Move(aCall), eventType)); + } + + GeckoViewSupport(nsWindow* aWindow, + const GeckoView::Window::LocalRef& aInstance, + GeckoView::Param aView) + : window(*aWindow) + , mEditable(GeckoEditable::New(aView)) + , mIMERanges(new TextRangeArray()) + , mIMEMaskEventsCount(1) // Mask IME events since there's no focus yet + , mIMEUpdatingContext(false) + , mIMESelectionChanged(false) + , mIMETextChangedDuringFlush(false) + , mIMEMonitorCursor(false) + { + Base::AttachNative(aInstance, this); + EditableBase::AttachNative(mEditable, this); + } + + ~GeckoViewSupport(); + + using Base::DisposeNative; + using EditableBase::DisposeNative; + + /** + * GeckoView methods + */ +private: + nsCOMPtr<nsPIDOMWindowOuter> mDOMWindow; + +public: + // Create and attach a window. + static void Open(const jni::Class::LocalRef& aCls, + GeckoView::Window::Param aWindow, + GeckoView::Param aView, jni::Object::Param aCompositor, + jni::String::Param aChromeURI, + int32_t screenId); + + // Close and destroy the nsWindow. + void Close(); + + // Reattach this nsWindow to a new GeckoView. + void Reattach(const GeckoView::Window::LocalRef& inst, + GeckoView::Param aView, jni::Object::Param aCompositor); + + void LoadUri(jni::String::Param aUri, int32_t aFlags); + + /** + * GeckoEditable methods + */ +private: + /* + Rules for managing IME between Gecko and Java: + + * Gecko controls the text content, and Java shadows the Gecko text + through text updates + * Gecko and Java maintain separate selections, and synchronize when + needed through selection updates and set-selection events + * Java controls the composition, and Gecko shadows the Java + composition through update composition events + */ + + struct IMETextChange final { + int32_t mStart, mOldEnd, mNewEnd; + + IMETextChange() : + mStart(-1), mOldEnd(-1), mNewEnd(-1) {} + + IMETextChange(const IMENotification& aIMENotification) + : mStart(aIMENotification.mTextChangeData.mStartOffset) + , mOldEnd(aIMENotification.mTextChangeData.mRemovedEndOffset) + , mNewEnd(aIMENotification.mTextChangeData.mAddedEndOffset) + { + MOZ_ASSERT(aIMENotification.mMessage == NOTIFY_IME_OF_TEXT_CHANGE, + "IMETextChange initialized with wrong notification"); + MOZ_ASSERT(aIMENotification.mTextChangeData.IsValid(), + "The text change notification isn't initialized"); + MOZ_ASSERT(aIMENotification.mTextChangeData.IsInInt32Range(), + "The text change notification is out of range"); + } + + bool IsEmpty() const { return mStart < 0; } + }; + + // GeckoEditable instance used by this nsWindow; + java::GeckoEditable::GlobalRef mEditable; + AutoTArray<mozilla::UniquePtr<mozilla::WidgetEvent>, 8> mIMEKeyEvents; + AutoTArray<IMETextChange, 4> mIMETextChanges; + InputContext mInputContext; + RefPtr<mozilla::TextRangeArray> mIMERanges; + int32_t mIMEMaskEventsCount; // Mask events when > 0. + bool mIMEUpdatingContext; + bool mIMESelectionChanged; + bool mIMETextChangedDuringFlush; + bool mIMEMonitorCursor; + + void SendIMEDummyKeyEvents(); + void AddIMETextChange(const IMETextChange& aChange); + + enum FlushChangesFlag { + // Not retrying. + FLUSH_FLAG_NONE, + // Retrying due to IME text changes during flush. + FLUSH_FLAG_RETRY, + // Retrying due to IME sync exceptions during flush. + FLUSH_FLAG_RECOVER + }; + void PostFlushIMEChanges(); + void FlushIMEChanges(FlushChangesFlag aFlags = FLUSH_FLAG_NONE); + void FlushIMEText(FlushChangesFlag aFlags = FLUSH_FLAG_NONE); + void AsyncNotifyIME(int32_t aNotification); + void UpdateCompositionRects(); + +public: + bool NotifyIME(const IMENotification& aIMENotification); + void SetInputContext(const InputContext& aContext, + const InputContextAction& aAction); + InputContext GetInputContext(); + + // RAII helper class that automatically sends an event reply through + // OnImeSynchronize, as required by events like OnImeReplaceText. + class AutoIMESynchronize { + GeckoViewSupport* const mGVS; + public: + AutoIMESynchronize(GeckoViewSupport* gvs) : mGVS(gvs) {} + ~AutoIMESynchronize() { mGVS->OnImeSynchronize(); } + }; + + // Handle an Android KeyEvent. + void OnKeyEvent(int32_t aAction, int32_t aKeyCode, int32_t aScanCode, + int32_t aMetaState, int64_t aTime, int32_t aUnicodeChar, + int32_t aBaseUnicodeChar, int32_t aDomPrintableKeyValue, + int32_t aRepeatCount, int32_t aFlags, + bool aIsSynthesizedImeKey, jni::Object::Param originalEvent); + + // Synchronize Gecko thread with the InputConnection thread. + void OnImeSynchronize(); + + // Replace a range of text with new text. + void OnImeReplaceText(int32_t aStart, int32_t aEnd, + jni::String::Param aText); + + // Add styling for a range within the active composition. + void OnImeAddCompositionRange(int32_t aStart, int32_t aEnd, + int32_t aRangeType, int32_t aRangeStyle, int32_t aRangeLineStyle, + bool aRangeBoldLine, int32_t aRangeForeColor, + int32_t aRangeBackColor, int32_t aRangeLineColor); + + // Update styling for the active composition using previous-added ranges. + void OnImeUpdateComposition(int32_t aStart, int32_t aEnd); + + // Set cursor mode whether IME requests + void OnImeRequestCursorUpdates(int aRequestMode); +}; + +/** + * NativePanZoomController handles its native calls on the UI thread, so make + * it separate from GeckoViewSupport. + */ +class nsWindow::NPZCSupport final + : public NativePanZoomController::Natives<NPZCSupport> +{ + using LockedWindowPtr = WindowPtr<NPZCSupport>::Locked; + + WindowPtr<NPZCSupport> mWindow; + NativePanZoomController::GlobalRef mNPZC; + int mPreviousButtons; + +public: + typedef NativePanZoomController::Natives<NPZCSupport> Base; + + NPZCSupport(NativePtr<NPZCSupport>* aPtr, nsWindow* aWindow, + const NativePanZoomController::LocalRef& aNPZC) + : mWindow(aPtr, aWindow) + , mNPZC(aNPZC) + , mPreviousButtons(0) + {} + + ~NPZCSupport() + {} + + using Base::AttachNative; + using Base::DisposeNative; + + void OnDetach() + { + // There are several considerations when shutting down NPZC. 1) The + // Gecko thread may destroy NPZC at any time when nsWindow closes. 2) + // There may be pending events on the Gecko thread when NPZC is + // destroyed. 3) mWindow may not be available when the pending event + // runs. 4) The UI thread may destroy NPZC at any time when GeckoView + // is destroyed. 5) The UI thread may destroy NPZC at the same time as + // Gecko thread trying to destroy NPZC. 6) There may be pending calls + // on the UI thread when NPZC is destroyed. 7) mWindow may have been + // cleared on the Gecko thread when the pending call happens on the UI + // thread. + // + // 1) happens through OnDetach, which first notifies the UI + // thread through Destroy; Destroy then calls DisposeNative, which + // finally disposes the native instance back on the Gecko thread. Using + // Destroy to indirectly call DisposeNative here also solves 5), by + // making everything go through the UI thread, avoiding contention. + // + // 2) and 3) are solved by clearing mWindow, which signals to the + // pending event that we had shut down. In that case the event bails + // and does not touch mWindow. + // + // 4) happens through DisposeNative directly. OnDetach is not + // called. + // + // 6) is solved by keeping a destroyed flag in the Java NPZC instance, + // and only make a pending call if the destroyed flag is not set. + // + // 7) is solved by taking a lock whenever mWindow is modified on the + // Gecko thread or accessed on the UI thread. That way, we don't + // release mWindow until the UI thread is done using it, thus avoiding + // the race condition. + + typedef NativePanZoomController::GlobalRef NPZCRef; + auto callDestroy = [] (const NPZCRef& npzc) { + npzc->Destroy(); + }; + + NativePanZoomController::GlobalRef npzc = mNPZC; + AndroidBridge::Bridge()->PostTaskToUiThread(NewRunnableFunction( + static_cast<void(*)(const NPZCRef&)>(callDestroy), + mozilla::Move(npzc)), 0); + } + +public: + void AdjustScrollForSurfaceShift(float aX, float aY) + { + MOZ_ASSERT(AndroidBridge::IsJavaUiThread()); + + RefPtr<IAPZCTreeManager> controller; + + if (LockedWindowPtr window{mWindow}) { + controller = window->mAPZC; + } + + if (controller) { + controller->AdjustScrollForSurfaceShift( + ScreenPoint(aX, aY)); + } + } + + void SetIsLongpressEnabled(bool aIsLongpressEnabled) + { + MOZ_ASSERT(AndroidBridge::IsJavaUiThread()); + + RefPtr<IAPZCTreeManager> controller; + + if (LockedWindowPtr window{mWindow}) { + controller = window->mAPZC; + } + + if (controller) { + controller->SetLongTapEnabled(aIsLongpressEnabled); + } + } + + bool HandleScrollEvent(int64_t aTime, int32_t aMetaState, + float aX, float aY, + float aHScroll, float aVScroll) + { + MOZ_ASSERT(AndroidBridge::IsJavaUiThread()); + + RefPtr<IAPZCTreeManager> controller; + + if (LockedWindowPtr window{mWindow}) { + controller = window->mAPZC; + } + + if (!controller) { + return false; + } + + ScreenPoint origin = ScreenPoint(aX, aY); + + ScrollWheelInput input(aTime, TimeStamp::Now(), GetModifiers(aMetaState), + ScrollWheelInput::SCROLLMODE_SMOOTH, + ScrollWheelInput::SCROLLDELTA_PIXEL, + origin, + aHScroll, aVScroll, + false); + + ScrollableLayerGuid guid; + uint64_t blockId; + nsEventStatus status = controller->ReceiveInputEvent(input, &guid, &blockId); + + if (status == nsEventStatus_eConsumeNoDefault) { + return true; + } + + NativePanZoomController::GlobalRef npzc = mNPZC; + nsAppShell::PostEvent([npzc, input, guid, blockId, status] { + MOZ_ASSERT(NS_IsMainThread()); + + JNIEnv* const env = jni::GetGeckoThreadEnv(); + NPZCSupport* npzcSupport = GetNative( + NativePanZoomController::LocalRef(env, npzc)); + + if (!npzcSupport || !npzcSupport->mWindow) { + // We already shut down. + env->ExceptionClear(); + return; + } + + nsWindow* const window = npzcSupport->mWindow; + window->UserActivity(); + WidgetWheelEvent wheelEvent = input.ToWidgetWheelEvent(window); + window->ProcessUntransformedAPZEvent(&wheelEvent, guid, + blockId, status); + }); + + return true; + } + +private: + static MouseInput::ButtonType GetButtonType(int button) + { + MouseInput::ButtonType result = MouseInput::NONE; + + switch (button) { + case java::sdk::MotionEvent::BUTTON_PRIMARY: + result = MouseInput::LEFT_BUTTON; + break; + case java::sdk::MotionEvent::BUTTON_SECONDARY: + result = MouseInput::RIGHT_BUTTON; + break; + case java::sdk::MotionEvent::BUTTON_TERTIARY: + result = MouseInput::MIDDLE_BUTTON; + break; + default: + break; + } + + return result; + } + + static int16_t ConvertButtons(int buttons) { + int16_t result = 0; + + if (buttons & java::sdk::MotionEvent::BUTTON_PRIMARY) { + result |= WidgetMouseEventBase::eLeftButtonFlag; + } + if (buttons & java::sdk::MotionEvent::BUTTON_SECONDARY) { + result |= WidgetMouseEventBase::eRightButtonFlag; + } + if (buttons & java::sdk::MotionEvent::BUTTON_TERTIARY) { + result |= WidgetMouseEventBase::eMiddleButtonFlag; + } + if (buttons & java::sdk::MotionEvent::BUTTON_BACK) { + result |= WidgetMouseEventBase::e4thButtonFlag; + } + if (buttons & java::sdk::MotionEvent::BUTTON_FORWARD) { + result |= WidgetMouseEventBase::e5thButtonFlag; + } + + return result; + } + +public: + bool HandleMouseEvent(int32_t aAction, int64_t aTime, int32_t aMetaState, + float aX, float aY, int buttons) + { + MOZ_ASSERT(AndroidBridge::IsJavaUiThread()); + + RefPtr<IAPZCTreeManager> controller; + + if (LockedWindowPtr window{mWindow}) { + controller = window->mAPZC; + } + + if (!controller) { + return false; + } + + MouseInput::MouseType mouseType = MouseInput::MOUSE_NONE; + MouseInput::ButtonType buttonType = MouseInput::NONE; + switch (aAction) { + case AndroidMotionEvent::ACTION_DOWN: + mouseType = MouseInput::MOUSE_DOWN; + buttonType = GetButtonType(buttons ^ mPreviousButtons); + mPreviousButtons = buttons; + break; + case AndroidMotionEvent::ACTION_UP: + mouseType = MouseInput::MOUSE_UP; + buttonType = GetButtonType(buttons ^ mPreviousButtons); + mPreviousButtons = buttons; + break; + case AndroidMotionEvent::ACTION_MOVE: + mouseType = MouseInput::MOUSE_MOVE; + break; + case AndroidMotionEvent::ACTION_HOVER_MOVE: + mouseType = MouseInput::MOUSE_MOVE; + break; + case AndroidMotionEvent::ACTION_HOVER_ENTER: + mouseType = MouseInput::MOUSE_WIDGET_ENTER; + break; + case AndroidMotionEvent::ACTION_HOVER_EXIT: + mouseType = MouseInput::MOUSE_WIDGET_EXIT; + break; + default: + break; + } + + if (mouseType == MouseInput::MOUSE_NONE) { + return false; + } + + ScreenPoint origin = ScreenPoint(aX, aY); + + MouseInput input(mouseType, buttonType, nsIDOMMouseEvent::MOZ_SOURCE_MOUSE, ConvertButtons(buttons), origin, aTime, TimeStamp(), GetModifiers(aMetaState)); + + ScrollableLayerGuid guid; + uint64_t blockId; + nsEventStatus status = controller->ReceiveInputEvent(input, &guid, &blockId); + + if (status == nsEventStatus_eConsumeNoDefault) { + return true; + } + + NativePanZoomController::GlobalRef npzc = mNPZC; + nsAppShell::PostEvent([npzc, input, guid, blockId, status] { + MOZ_ASSERT(NS_IsMainThread()); + + JNIEnv* const env = jni::GetGeckoThreadEnv(); + NPZCSupport* npzcSupport = GetNative( + NativePanZoomController::LocalRef(env, npzc)); + + if (!npzcSupport || !npzcSupport->mWindow) { + // We already shut down. + env->ExceptionClear(); + return; + } + + nsWindow* const window = npzcSupport->mWindow; + window->UserActivity(); + WidgetMouseEvent mouseEvent = input.ToWidgetMouseEvent(window); + window->ProcessUntransformedAPZEvent(&mouseEvent, guid, + blockId, status); + }); + + return true; + } + + bool HandleMotionEvent(const NativePanZoomController::LocalRef& aInstance, + int32_t aAction, int32_t aActionIndex, + int64_t aTime, int32_t aMetaState, + jni::IntArray::Param aPointerId, + jni::FloatArray::Param aX, + jni::FloatArray::Param aY, + jni::FloatArray::Param aOrientation, + jni::FloatArray::Param aPressure, + jni::FloatArray::Param aToolMajor, + jni::FloatArray::Param aToolMinor) + { + MOZ_ASSERT(AndroidBridge::IsJavaUiThread()); + + RefPtr<IAPZCTreeManager> controller; + + if (LockedWindowPtr window{mWindow}) { + controller = window->mAPZC; + } + + if (!controller) { + return false; + } + + nsTArray<int32_t> pointerId(aPointerId->GetElements()); + MultiTouchInput::MultiTouchType type; + size_t startIndex = 0; + size_t endIndex = pointerId.Length(); + + switch (aAction) { + case sdk::MotionEvent::ACTION_DOWN: + case sdk::MotionEvent::ACTION_POINTER_DOWN: + type = MultiTouchInput::MULTITOUCH_START; + break; + case sdk::MotionEvent::ACTION_MOVE: + type = MultiTouchInput::MULTITOUCH_MOVE; + break; + case sdk::MotionEvent::ACTION_UP: + case sdk::MotionEvent::ACTION_POINTER_UP: + // for pointer-up events we only want the data from + // the one pointer that went up + type = MultiTouchInput::MULTITOUCH_END; + startIndex = aActionIndex; + endIndex = aActionIndex + 1; + break; + case sdk::MotionEvent::ACTION_OUTSIDE: + case sdk::MotionEvent::ACTION_CANCEL: + type = MultiTouchInput::MULTITOUCH_CANCEL; + break; + default: + return false; + } + + MultiTouchInput input(type, aTime, TimeStamp(), 0); + input.modifiers = GetModifiers(aMetaState); + input.mTouches.SetCapacity(endIndex - startIndex); + + nsTArray<float> x(aX->GetElements()); + nsTArray<float> y(aY->GetElements()); + nsTArray<float> orientation(aOrientation->GetElements()); + nsTArray<float> pressure(aPressure->GetElements()); + nsTArray<float> toolMajor(aToolMajor->GetElements()); + nsTArray<float> toolMinor(aToolMinor->GetElements()); + + MOZ_ASSERT(pointerId.Length() == x.Length()); + MOZ_ASSERT(pointerId.Length() == y.Length()); + MOZ_ASSERT(pointerId.Length() == orientation.Length()); + MOZ_ASSERT(pointerId.Length() == pressure.Length()); + MOZ_ASSERT(pointerId.Length() == toolMajor.Length()); + MOZ_ASSERT(pointerId.Length() == toolMinor.Length()); + + for (size_t i = startIndex; i < endIndex; i++) { + + float orien = orientation[i] * 180.0f / M_PI; + // w3c touchevents spec does not allow orientations == 90 + // this shifts it to -90, which will be shifted to zero below + if (orien >= 90.0) { + orien -= 180.0f; + } + + nsIntPoint point = nsIntPoint(int32_t(floorf(x[i])), + int32_t(floorf(y[i]))); + + // w3c touchevent radii are given with an orientation between 0 and + // 90. The radii are found by removing the orientation and + // measuring the x and y radii of the resulting ellipse. For + // Android orientations >= 0 and < 90, use the y radius as the + // major radius, and x as the minor radius. However, for an + // orientation < 0, we have to shift the orientation by adding 90, + // and reverse which radius is major and minor. + gfx::Size radius; + if (orien < 0.0f) { + orien += 90.0f; + radius = gfx::Size(int32_t(toolMajor[i] / 2.0f), + int32_t(toolMinor[i] / 2.0f)); + } else { + radius = gfx::Size(int32_t(toolMinor[i] / 2.0f), + int32_t(toolMajor[i] / 2.0f)); + } + + input.mTouches.AppendElement(SingleTouchData( + pointerId[i], ScreenIntPoint::FromUnknownPoint(point), + ScreenSize::FromUnknownSize(radius), orien, pressure[i])); + } + + ScrollableLayerGuid guid; + uint64_t blockId; + nsEventStatus status = + controller->ReceiveInputEvent(input, &guid, &blockId); + + if (status == nsEventStatus_eConsumeNoDefault) { + return true; + } + + // Dispatch APZ input event on Gecko thread. + NativePanZoomController::GlobalRef npzc = mNPZC; + nsAppShell::PostEvent([npzc, input, guid, blockId, status] { + MOZ_ASSERT(NS_IsMainThread()); + + JNIEnv* const env = jni::GetGeckoThreadEnv(); + NPZCSupport* npzcSupport = GetNative( + NativePanZoomController::LocalRef(env, npzc)); + + if (!npzcSupport || !npzcSupport->mWindow) { + // We already shut down. + env->ExceptionClear(); + return; + } + + nsWindow* const window = npzcSupport->mWindow; + window->UserActivity(); + WidgetTouchEvent touchEvent = input.ToWidgetTouchEvent(window); + window->ProcessUntransformedAPZEvent(&touchEvent, guid, + blockId, status); + window->DispatchHitTest(touchEvent); + }); + return true; + } + + void HandleMotionEventVelocity(int64_t aTime, float aSpeedY) + { + MOZ_ASSERT(AndroidBridge::IsJavaUiThread()); + + RefPtr<IAPZCTreeManager> controller; + + if (LockedWindowPtr window{mWindow}) { + controller = window->mAPZC; + } + + if (controller) { + controller->ProcessTouchVelocity((uint32_t)aTime, aSpeedY); + } + } + + void UpdateOverscrollVelocity(const float x, const float y) + { + mNPZC->UpdateOverscrollVelocity(x, y); + } + + void UpdateOverscrollOffset(const float x, const float y) + { + mNPZC->UpdateOverscrollOffset(x, y); + } + + void SetScrollingRootContent(const bool isRootContent) + { + mNPZC->SetScrollingRootContent(isRootContent); + } + + void SetSelectionDragState(const bool aState) + { + mNPZC->OnSelectionDragState(aState); + } +}; + +template<> const char +nsWindow::NativePtr<nsWindow::NPZCSupport>::sName[] = "NPZCSupport"; + +/** + * Compositor has some unique requirements for its native calls, so make it + * separate from GeckoViewSupport. + */ +class nsWindow::LayerViewSupport final + : public LayerView::Compositor::Natives<LayerViewSupport> +{ + using LockedWindowPtr = WindowPtr<LayerViewSupport>::Locked; + + WindowPtr<LayerViewSupport> mWindow; + LayerView::Compositor::GlobalRef mCompositor; + GeckoLayerClient::GlobalRef mLayerClient; + Atomic<bool, ReleaseAcquire> mCompositorPaused; + jni::Object::GlobalRef mSurface; + + // In order to use Event::HasSameTypeAs in PostTo(), we cannot make + // LayerViewEvent a template because each template instantiation is + // a different type. So implement LayerViewEvent as a ProxyEvent. + class LayerViewEvent final : public nsAppShell::ProxyEvent + { + using Event = nsAppShell::Event; + + public: + static UniquePtr<Event> MakeEvent(UniquePtr<Event>&& event) + { + return MakeUnique<LayerViewEvent>(mozilla::Move(event)); + } + + LayerViewEvent(UniquePtr<Event>&& event) + : nsAppShell::ProxyEvent(mozilla::Move(event)) + {} + + void PostTo(LinkedList<Event>& queue) override + { + // Give priority to compositor events, but keep in order with + // existing compositor events. + nsAppShell::Event* event = queue.getFirst(); + while (event && event->HasSameTypeAs(this)) { + event = event->getNext(); + } + if (event) { + event->setPrevious(this); + } else { + queue.insertBack(this); + } + } + }; + +public: + typedef LayerView::Compositor::Natives<LayerViewSupport> Base; + + template<class Functor> + static void OnNativeCall(Functor&& aCall) + { + if (aCall.IsTarget(&LayerViewSupport::CreateCompositor)) { + // This call is blocking. + nsAppShell::SyncRunEvent(nsAppShell::LambdaEvent<Functor>( + mozilla::Move(aCall)), &LayerViewEvent::MakeEvent); + return; + } + } + + static LayerViewSupport* + FromNative(const LayerView::Compositor::LocalRef& instance) + { + return GetNative(instance); + } + + LayerViewSupport(NativePtr<LayerViewSupport>* aPtr, nsWindow* aWindow, + const LayerView::Compositor::LocalRef& aInstance) + : mWindow(aPtr, aWindow) + , mCompositor(aInstance) + , mCompositorPaused(true) + {} + + ~LayerViewSupport() + {} + + using Base::AttachNative; + using Base::DisposeNative; + + void OnDetach() + { + mCompositor->Destroy(); + } + + const GeckoLayerClient::Ref& GetLayerClient() const + { + return mLayerClient; + } + + bool CompositorPaused() const + { + return mCompositorPaused; + } + + jni::Object::Param GetSurface() + { + return mSurface; + } + +private: + void OnResumedCompositor() + { + MOZ_ASSERT(NS_IsMainThread()); + + // When we receive this, the compositor has already been told to + // resume. (It turns out that waiting till we reach here to tell + // the compositor to resume takes too long, resulting in a black + // flash.) This means it's now safe for layer updates to occur. + // Since we might have prevented one or more draw events from + // occurring while the compositor was paused, we need to schedule + // a draw event now. + if (!mCompositorPaused) { + mWindow->RedrawAll(); + } + } + + /** + * Compositor methods + */ +public: + void AttachToJava(jni::Object::Param aClient, jni::Object::Param aNPZC) + { + MOZ_ASSERT(NS_IsMainThread()); + if (!mWindow) { + return; // Already shut down. + } + + const auto& layerClient = GeckoLayerClient::Ref::From(aClient); + + // If resetting is true, Android destroyed our GeckoApp activity and we + // had to recreate it, but all the Gecko-side things were not + // destroyed. We therefore need to link up the new java objects to + // Gecko, and that's what we do here. + const bool resetting = !!mLayerClient; + mLayerClient = layerClient; + + MOZ_ASSERT(aNPZC); + auto npzc = NativePanZoomController::LocalRef( + jni::GetGeckoThreadEnv(), + NativePanZoomController::Ref::From(aNPZC)); + mWindow->mNPZCSupport.Attach(npzc, mWindow, npzc); + + layerClient->OnGeckoReady(); + + if (resetting) { + // Since we are re-linking the new java objects to Gecko, we need + // to get the viewport from the compositor (since the Java copy was + // thrown away) and we do that by setting the first-paint flag. + if (RefPtr<CompositorBridgeParent> bridge = mWindow->GetCompositorBridgeParent()) { + bridge->ForceIsFirstPaint(); + } + } + } + + void OnSizeChanged(int32_t aWindowWidth, int32_t aWindowHeight, + int32_t aScreenWidth, int32_t aScreenHeight) + { + MOZ_ASSERT(NS_IsMainThread()); + if (!mWindow) { + return; // Already shut down. + } + + if (aWindowWidth != mWindow->mBounds.width || + aWindowHeight != mWindow->mBounds.height) { + + mWindow->Resize(aWindowWidth, aWindowHeight, /* repaint */ false); + } + } + + void CreateCompositor(int32_t aWidth, int32_t aHeight, + jni::Object::Param aSurface) + { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(mWindow); + + mSurface = aSurface; + mWindow->CreateLayerManager(aWidth, aHeight); + + mCompositorPaused = false; + OnResumedCompositor(); + } + + void SyncPauseCompositor() + { + MOZ_ASSERT(AndroidBridge::IsJavaUiThread()); + + RefPtr<CompositorBridgeParent> bridge; + + if (LockedWindowPtr window{mWindow}) { + bridge = window->GetCompositorBridgeParent(); + } + + if (bridge) { + mCompositorPaused = true; + bridge->SchedulePauseOnCompositorThread(); + } + } + + void SyncResumeCompositor() + { + MOZ_ASSERT(AndroidBridge::IsJavaUiThread()); + + RefPtr<CompositorBridgeParent> bridge; + + if (LockedWindowPtr window{mWindow}) { + bridge = window->GetCompositorBridgeParent(); + } + + if (bridge && bridge->ScheduleResumeOnCompositorThread()) { + mCompositorPaused = false; + } + } + + void SyncResumeResizeCompositor(const LayerView::Compositor::LocalRef& aObj, + int32_t aWidth, int32_t aHeight, + jni::Object::Param aSurface) + { + MOZ_ASSERT(AndroidBridge::IsJavaUiThread()); + + RefPtr<CompositorBridgeParent> bridge; + + if (LockedWindowPtr window{mWindow}) { + bridge = window->GetCompositorBridgeParent(); + } + + mSurface = aSurface; + + if (!bridge || !bridge->ScheduleResumeOnCompositorThread(aWidth, + aHeight)) { + return; + } + + mCompositorPaused = false; + + class OnResumedEvent : public nsAppShell::Event + { + LayerView::Compositor::GlobalRef mCompositor; + + public: + OnResumedEvent(LayerView::Compositor::GlobalRef&& aCompositor) + : mCompositor(mozilla::Move(aCompositor)) + {} + + void Run() override + { + MOZ_ASSERT(NS_IsMainThread()); + + JNIEnv* const env = jni::GetGeckoThreadEnv(); + LayerViewSupport* const lvs = GetNative( + LayerView::Compositor::LocalRef(env, mCompositor)); + MOZ_CATCH_JNI_EXCEPTION(env); + + lvs->OnResumedCompositor(); + } + }; + + nsAppShell::PostEvent(MakeUnique<LayerViewEvent>( + MakeUnique<OnResumedEvent>(aObj))); + } + + void SyncInvalidateAndScheduleComposite() + { + RefPtr<CompositorBridgeParent> bridge; + + if (LockedWindowPtr window{mWindow}) { + bridge = window->GetCompositorBridgeParent(); + } + + if (bridge) { + bridge->InvalidateOnCompositorThread(); + bridge->ScheduleRenderOnCompositorThread(); + } + } +}; + +template<> const char +nsWindow::NativePtr<nsWindow::LayerViewSupport>::sName[] = "LayerViewSupport"; + +/* PresentationMediaPlayerManager native calls access inner nsWindow functionality so PMPMSupport is a child class of nsWindow */ +class nsWindow::PMPMSupport final + : public PresentationMediaPlayerManager::Natives<PMPMSupport> +{ + PMPMSupport() = delete; + + static LayerViewSupport* GetLayerViewSupport(jni::Object::Param aView) + { + const auto& layerView = LayerView::Ref::From(aView); + + LayerView::Compositor::LocalRef compositor = layerView->GetCompositor(); + if (!layerView->CompositorCreated() || !compositor) { + return nullptr; + } + + LayerViewSupport* const lvs = LayerViewSupport::FromNative(compositor); + if (!lvs) { + // There is a pending exception whenever FromNative returns nullptr. + compositor.Env()->ExceptionClear(); + } + return lvs; + } + +public: + static ANativeWindow* sWindow; + static EGLSurface sSurface; + + static void InvalidateAndScheduleComposite(jni::Object::Param aView) + { + LayerViewSupport* const lvs = GetLayerViewSupport(aView); + if (lvs) { + lvs->SyncInvalidateAndScheduleComposite(); + } + } + + static void AddPresentationSurface(const jni::Class::LocalRef& aCls, + jni::Object::Param aView, + jni::Object::Param aSurface) + { + RemovePresentationSurface(); + + LayerViewSupport* const lvs = GetLayerViewSupport(aView); + if (!lvs) { + return; + } + + ANativeWindow* const window = ANativeWindow_fromSurface( + aCls.Env(), aSurface.Get()); + if (!window) { + return; + } + + sWindow = window; + + const bool wasAlreadyPaused = lvs->CompositorPaused(); + if (!wasAlreadyPaused) { + lvs->SyncPauseCompositor(); + } + + if (sSurface) { + // Destroy the EGL surface! The compositor is paused so it should + // be okay to destroy the surface here. + mozilla::gl::GLContextProvider::DestroyEGLSurface(sSurface); + sSurface = nullptr; + } + + if (!wasAlreadyPaused) { + lvs->SyncResumeCompositor(); + } + + lvs->SyncInvalidateAndScheduleComposite(); + } + + static void RemovePresentationSurface() + { + if (sWindow) { + ANativeWindow_release(sWindow); + sWindow = nullptr; + } + } +}; + +ANativeWindow* nsWindow::PMPMSupport::sWindow; +EGLSurface nsWindow::PMPMSupport::sSurface; + + +nsWindow::GeckoViewSupport::~GeckoViewSupport() +{ + // Disassociate our GeckoEditable instance with our native object. + // OnDestroy will call disposeNative after any pending native calls have + // been made. + MOZ_ASSERT(mEditable); + mEditable->OnViewChange(nullptr); + + if (window.mNPZCSupport) { + window.mNPZCSupport.Detach(); + } + + if (window.mLayerViewSupport) { + window.mLayerViewSupport.Detach(); + } +} + +/* static */ void +nsWindow::GeckoViewSupport::Open(const jni::Class::LocalRef& aCls, + GeckoView::Window::Param aWindow, + GeckoView::Param aView, + jni::Object::Param aCompositor, + jni::String::Param aChromeURI, + int32_t aScreenId) +{ + MOZ_ASSERT(NS_IsMainThread()); + + PROFILER_LABEL("nsWindow", "GeckoViewSupport::Open", + js::ProfileEntry::Category::OTHER); + + nsCOMPtr<nsIWindowWatcher> ww = do_GetService(NS_WINDOWWATCHER_CONTRACTID); + MOZ_RELEASE_ASSERT(ww); + + nsAdoptingCString url; + if (aChromeURI) { + url = aChromeURI->ToCString(); + } else { + url = Preferences::GetCString("toolkit.defaultChromeURI"); + if (!url) { + url = NS_LITERAL_CSTRING("chrome://browser/content/browser.xul"); + } + } + + nsCOMPtr<mozIDOMWindowProxy> domWindow; + ww->OpenWindow(nullptr, url, nullptr, "chrome,dialog=0,resizable,scrollbars=yes", + nullptr, getter_AddRefs(domWindow)); + MOZ_RELEASE_ASSERT(domWindow); + + nsCOMPtr<nsPIDOMWindowOuter> pdomWindow = + nsPIDOMWindowOuter::From(domWindow); + nsCOMPtr<nsIWidget> widget = WidgetUtils::DOMWindowToWidget(pdomWindow); + MOZ_ASSERT(widget); + + const auto window = static_cast<nsWindow*>(widget.get()); + window->SetScreenId(aScreenId); + + // Attach a new GeckoView support object to the new window. + window->mGeckoViewSupport = mozilla::MakeUnique<GeckoViewSupport>( + window, GeckoView::Window::LocalRef(aCls.Env(), aWindow), aView); + + window->mGeckoViewSupport->mDOMWindow = pdomWindow; + + // Attach the Compositor to the new window. + auto compositor = LayerView::Compositor::LocalRef( + aCls.Env(), LayerView::Compositor::Ref::From(aCompositor)); + window->mLayerViewSupport.Attach(compositor, window, compositor); + + if (window->mWidgetListener) { + nsCOMPtr<nsIXULWindow> xulWindow( + window->mWidgetListener->GetXULWindow()); + if (xulWindow) { + // Our window is not intrinsically sized, so tell nsXULWindow to + // not set a size for us. + xulWindow->SetIntrinsicallySized(false); + } + } +} + +void +nsWindow::GeckoViewSupport::Close() +{ + if (!mDOMWindow) { + return; + } + + mDOMWindow->ForceClose(); + mDOMWindow = nullptr; +} + +void +nsWindow::GeckoViewSupport::Reattach(const GeckoView::Window::LocalRef& inst, + GeckoView::Param aView, + jni::Object::Param aCompositor) +{ + // Associate our previous GeckoEditable with the new GeckoView. + mEditable->OnViewChange(aView); + + // mNPZCSupport might have already been detached through the Java side calling + // NativePanZoomController.destroy(). + if (window.mNPZCSupport) { + window.mNPZCSupport.Detach(); + } + + MOZ_ASSERT(window.mLayerViewSupport); + window.mLayerViewSupport.Detach(); + + auto compositor = LayerView::Compositor::LocalRef( + inst.Env(), LayerView::Compositor::Ref::From(aCompositor)); + window.mLayerViewSupport.Attach(compositor, &window, compositor); + compositor->Reattach(); +} + +void +nsWindow::GeckoViewSupport::LoadUri(jni::String::Param aUri, int32_t aFlags) +{ + if (!mDOMWindow) { + return; + } + + nsCOMPtr<nsIURI> uri = nsAppShell::ResolveURI(aUri->ToCString()); + if (NS_WARN_IF(!uri)) { + return; + } + + nsCOMPtr<nsIDOMChromeWindow> chromeWin = do_QueryInterface(mDOMWindow); + nsCOMPtr<nsIBrowserDOMWindow> browserWin; + + if (NS_WARN_IF(!chromeWin) || NS_WARN_IF(NS_FAILED( + chromeWin->GetBrowserDOMWindow(getter_AddRefs(browserWin))))) { + return; + } + + const int flags = aFlags == GeckoView::LOAD_NEW_TAB ? + nsIBrowserDOMWindow::OPEN_NEWTAB : + aFlags == GeckoView::LOAD_SWITCH_TAB ? + nsIBrowserDOMWindow::OPEN_SWITCHTAB : + nsIBrowserDOMWindow::OPEN_CURRENTWINDOW; + nsCOMPtr<mozIDOMWindowProxy> newWin; + + if (NS_FAILED(browserWin->OpenURI( + uri, nullptr, flags, nsIBrowserDOMWindow::OPEN_EXTERNAL, + getter_AddRefs(newWin)))) { + NS_WARNING("Failed to open URI"); + } +} + +void +nsWindow::InitNatives() +{ + nsWindow::GeckoViewSupport::Base::Init(); + nsWindow::GeckoViewSupport::EditableBase::Init(); + nsWindow::LayerViewSupport::Init(); + nsWindow::NPZCSupport::Init(); + if (jni::IsFennec()) { + nsWindow::PMPMSupport::Init(); + } +} + +nsWindow* +nsWindow::TopWindow() +{ + if (!gTopLevelWindows.IsEmpty()) + return gTopLevelWindows[0]; + return nullptr; +} + +void +nsWindow::LogWindow(nsWindow *win, int index, int indent) +{ +#if defined(DEBUG) || defined(FORCE_ALOG) + char spaces[] = " "; + spaces[indent < 20 ? indent : 20] = 0; + ALOG("%s [% 2d] 0x%08x [parent 0x%08x] [% 3d,% 3dx% 3d,% 3d] vis %d type %d", + spaces, index, (intptr_t)win, (intptr_t)win->mParent, + win->mBounds.x, win->mBounds.y, + win->mBounds.width, win->mBounds.height, + win->mIsVisible, win->mWindowType); +#endif +} + +void +nsWindow::DumpWindows() +{ + DumpWindows(gTopLevelWindows); +} + +void +nsWindow::DumpWindows(const nsTArray<nsWindow*>& wins, int indent) +{ + for (uint32_t i = 0; i < wins.Length(); ++i) { + nsWindow *w = wins[i]; + LogWindow(w, i, indent); + DumpWindows(w->mChildren, indent+1); + } +} + +nsWindow::nsWindow() : + mScreenId(0), // Use 0 (primary screen) as the default value. + mIsVisible(false), + mParent(nullptr), + mAwaitingFullScreen(false), + mIsFullScreen(false) +{ +} + +nsWindow::~nsWindow() +{ + gTopLevelWindows.RemoveElement(this); + ALOG("nsWindow %p destructor", (void*)this); +} + +bool +nsWindow::IsTopLevel() +{ + return mWindowType == eWindowType_toplevel || + mWindowType == eWindowType_dialog || + mWindowType == eWindowType_invisible; +} + +nsresult +nsWindow::Create(nsIWidget* aParent, + nsNativeWidget aNativeParent, + const LayoutDeviceIntRect& aRect, + nsWidgetInitData* aInitData) +{ + ALOG("nsWindow[%p]::Create %p [%d %d %d %d]", (void*)this, (void*)aParent, + aRect.x, aRect.y, aRect.width, aRect.height); + + nsWindow *parent = (nsWindow*) aParent; + if (aNativeParent) { + if (parent) { + ALOG("Ignoring native parent on Android window [%p], " + "since parent was specified (%p %p)", (void*)this, + (void*)aNativeParent, (void*)aParent); + } else { + parent = (nsWindow*) aNativeParent; + } + } + + mBounds = aRect; + + BaseCreate(nullptr, aInitData); + + NS_ASSERTION(IsTopLevel() || parent, + "non-top-level window doesn't have a parent!"); + + if (IsTopLevel()) { + gTopLevelWindows.AppendElement(this); + + } else if (parent) { + parent->mChildren.AppendElement(this); + mParent = parent; + } + +#ifdef DEBUG_ANDROID_WIDGET + DumpWindows(); +#endif + + return NS_OK; +} + +void +nsWindow::Destroy() +{ + nsBaseWidget::mOnDestroyCalled = true; + + if (mGeckoViewSupport) { + // Disassociate our native object with GeckoView. + mGeckoViewSupport = nullptr; + } + + // Stuff below may release the last ref to this + nsCOMPtr<nsIWidget> kungFuDeathGrip(this); + + while (mChildren.Length()) { + // why do we still have children? + ALOG("### Warning: Destroying window %p and reparenting child %p to null!", (void*)this, (void*)mChildren[0]); + mChildren[0]->SetParent(nullptr); + } + + nsBaseWidget::Destroy(); + + if (IsTopLevel()) + gTopLevelWindows.RemoveElement(this); + + SetParent(nullptr); + + nsBaseWidget::OnDestroy(); + +#ifdef DEBUG_ANDROID_WIDGET + DumpWindows(); +#endif +} + +NS_IMETHODIMP +nsWindow::ConfigureChildren(const nsTArray<nsIWidget::Configuration>& config) +{ + for (uint32_t i = 0; i < config.Length(); ++i) { + nsWindow *childWin = (nsWindow*) config[i].mChild.get(); + childWin->Resize(config[i].mBounds.x, + config[i].mBounds.y, + config[i].mBounds.width, + config[i].mBounds.height, + false); + } + + return NS_OK; +} + +void +nsWindow::RedrawAll() +{ + if (mAttachedWidgetListener) { + mAttachedWidgetListener->RequestRepaint(); + } else if (mWidgetListener) { + mWidgetListener->RequestRepaint(); + } +} + +NS_IMETHODIMP +nsWindow::SetParent(nsIWidget *aNewParent) +{ + if ((nsIWidget*)mParent == aNewParent) + return NS_OK; + + // If we had a parent before, remove ourselves from its list of + // children. + if (mParent) + mParent->mChildren.RemoveElement(this); + + mParent = (nsWindow*)aNewParent; + + if (mParent) + mParent->mChildren.AppendElement(this); + + // if we are now in the toplevel window's hierarchy, schedule a redraw + if (FindTopLevel() == nsWindow::TopWindow()) + RedrawAll(); + + return NS_OK; +} + +nsIWidget* +nsWindow::GetParent() +{ + return mParent; +} + +float +nsWindow::GetDPI() +{ + if (AndroidBridge::Bridge()) + return AndroidBridge::Bridge()->GetDPI(); + return 160.0f; +} + +double +nsWindow::GetDefaultScaleInternal() +{ + + nsCOMPtr<nsIScreen> screen = GetWidgetScreen(); + MOZ_ASSERT(screen); + RefPtr<nsScreenAndroid> screenAndroid = (nsScreenAndroid*) screen.get(); + return screenAndroid->GetDensity(); +} + +NS_IMETHODIMP +nsWindow::Show(bool aState) +{ + ALOG("nsWindow[%p]::Show %d", (void*)this, aState); + + if (mWindowType == eWindowType_invisible) { + ALOG("trying to show invisible window! ignoring.."); + return NS_ERROR_FAILURE; + } + + if (aState == mIsVisible) + return NS_OK; + + mIsVisible = aState; + + if (IsTopLevel()) { + // XXX should we bring this to the front when it's shown, + // if it's a toplevel widget? + + // XXX we should synthesize a eMouseExitFromWidget (for old top + // window)/eMouseEnterIntoWidget (for new top window) since we need + // to pretend that the top window always has focus. Not sure + // if Show() is the right place to do this, though. + + if (aState) { + // It just became visible, so bring it to the front. + BringToFront(); + + } else if (nsWindow::TopWindow() == this) { + // find the next visible window to show + unsigned int i; + for (i = 1; i < gTopLevelWindows.Length(); i++) { + nsWindow *win = gTopLevelWindows[i]; + if (!win->mIsVisible) + continue; + + win->BringToFront(); + break; + } + } + } else if (FindTopLevel() == nsWindow::TopWindow()) { + RedrawAll(); + } + +#ifdef DEBUG_ANDROID_WIDGET + DumpWindows(); +#endif + + return NS_OK; +} + +bool +nsWindow::IsVisible() const +{ + return mIsVisible; +} + +void +nsWindow::ConstrainPosition(bool aAllowSlop, + int32_t *aX, + int32_t *aY) +{ + ALOG("nsWindow[%p]::ConstrainPosition %d [%d %d]", (void*)this, aAllowSlop, *aX, *aY); + + // constrain toplevel windows; children we don't care about + if (IsTopLevel()) { + *aX = 0; + *aY = 0; + } +} + +NS_IMETHODIMP +nsWindow::Move(double aX, + double aY) +{ + if (IsTopLevel()) + return NS_OK; + + return Resize(aX, + aY, + mBounds.width, + mBounds.height, + true); +} + +NS_IMETHODIMP +nsWindow::Resize(double aWidth, + double aHeight, + bool aRepaint) +{ + return Resize(mBounds.x, + mBounds.y, + aWidth, + aHeight, + aRepaint); +} + +NS_IMETHODIMP +nsWindow::Resize(double aX, + double aY, + double aWidth, + double aHeight, + bool aRepaint) +{ + ALOG("nsWindow[%p]::Resize [%f %f %f %f] (repaint %d)", (void*)this, aX, aY, aWidth, aHeight, aRepaint); + + bool needSizeDispatch = aWidth != mBounds.width || aHeight != mBounds.height; + + mBounds.x = NSToIntRound(aX); + mBounds.y = NSToIntRound(aY); + mBounds.width = NSToIntRound(aWidth); + mBounds.height = NSToIntRound(aHeight); + + if (needSizeDispatch) { + OnSizeChanged(gfx::IntSize::Truncate(aWidth, aHeight)); + } + + // Should we skip honoring aRepaint here? + if (aRepaint && FindTopLevel() == nsWindow::TopWindow()) + RedrawAll(); + + nsIWidgetListener* listener = GetWidgetListener(); + if (mAwaitingFullScreen && listener) { + listener->FullscreenChanged(mIsFullScreen); + mAwaitingFullScreen = false; + } + + return NS_OK; +} + +void +nsWindow::SetZIndex(int32_t aZIndex) +{ + ALOG("nsWindow[%p]::SetZIndex %d ignored", (void*)this, aZIndex); +} + +void +nsWindow::SetSizeMode(nsSizeMode aMode) +{ + switch (aMode) { + case nsSizeMode_Minimized: + GeckoAppShell::MoveTaskToBack(); + break; + case nsSizeMode_Fullscreen: + MakeFullScreen(true); + break; + default: + break; + } +} + +NS_IMETHODIMP +nsWindow::Enable(bool aState) +{ + ALOG("nsWindow[%p]::Enable %d ignored", (void*)this, aState); + return NS_OK; +} + +bool +nsWindow::IsEnabled() const +{ + return true; +} + +NS_IMETHODIMP +nsWindow::Invalidate(const LayoutDeviceIntRect& aRect) +{ + return NS_OK; +} + +nsWindow* +nsWindow::FindTopLevel() +{ + nsWindow *toplevel = this; + while (toplevel) { + if (toplevel->IsTopLevel()) + return toplevel; + + toplevel = toplevel->mParent; + } + + ALOG("nsWindow::FindTopLevel(): couldn't find a toplevel or dialog window in this [%p] widget's hierarchy!", (void*)this); + return this; +} + +NS_IMETHODIMP +nsWindow::SetFocus(bool aRaise) +{ + nsWindow *top = FindTopLevel(); + top->BringToFront(); + + return NS_OK; +} + +void +nsWindow::BringToFront() +{ + // If the window to be raised is the same as the currently raised one, + // do nothing. We need to check the focus manager as well, as the first + // window that is created will be first in the window list but won't yet + // be focused. + nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID); + nsCOMPtr<mozIDOMWindowProxy> existingTopWindow; + fm->GetActiveWindow(getter_AddRefs(existingTopWindow)); + if (existingTopWindow && FindTopLevel() == nsWindow::TopWindow()) + return; + + if (!IsTopLevel()) { + FindTopLevel()->BringToFront(); + return; + } + + RefPtr<nsWindow> kungFuDeathGrip(this); + + nsWindow *oldTop = nullptr; + if (!gTopLevelWindows.IsEmpty()) { + oldTop = gTopLevelWindows[0]; + } + + gTopLevelWindows.RemoveElement(this); + gTopLevelWindows.InsertElementAt(0, this); + + if (oldTop) { + nsIWidgetListener* listener = oldTop->GetWidgetListener(); + if (listener) { + listener->WindowDeactivated(); + } + } + + if (mWidgetListener) { + mWidgetListener->WindowActivated(); + } + + RedrawAll(); +} + +LayoutDeviceIntRect +nsWindow::GetScreenBounds() +{ + return LayoutDeviceIntRect(WidgetToScreenOffset(), mBounds.Size()); +} + +LayoutDeviceIntPoint +nsWindow::WidgetToScreenOffset() +{ + LayoutDeviceIntPoint p(0, 0); + nsWindow *w = this; + + while (w && !w->IsTopLevel()) { + p.x += w->mBounds.x; + p.y += w->mBounds.y; + + w = w->mParent; + } + + return p; +} + +NS_IMETHODIMP +nsWindow::DispatchEvent(WidgetGUIEvent* aEvent, + nsEventStatus& aStatus) +{ + aStatus = DispatchEvent(aEvent); + return NS_OK; +} + +nsEventStatus +nsWindow::DispatchEvent(WidgetGUIEvent* aEvent) +{ + if (mAttachedWidgetListener) { + return mAttachedWidgetListener->HandleEvent(aEvent, mUseAttachedEvents); + } else if (mWidgetListener) { + return mWidgetListener->HandleEvent(aEvent, mUseAttachedEvents); + } + return nsEventStatus_eIgnore; +} + +nsresult +nsWindow::MakeFullScreen(bool aFullScreen, nsIScreen*) +{ + mIsFullScreen = aFullScreen; + mAwaitingFullScreen = true; + GeckoAppShell::SetFullScreen(aFullScreen); + return NS_OK; +} + +mozilla::layers::LayerManager* +nsWindow::GetLayerManager(PLayerTransactionChild*, LayersBackend, LayerManagerPersistence) +{ + if (mLayerManager) { + return mLayerManager; + } + return nullptr; +} + +void +nsWindow::CreateLayerManager(int aCompositorWidth, int aCompositorHeight) +{ + if (mLayerManager) { + return; + } + + nsWindow *topLevelWindow = FindTopLevel(); + if (!topLevelWindow || topLevelWindow->mWindowType == eWindowType_invisible) { + // don't create a layer manager for an invisible top-level window + return; + } + + // Ensure that gfxPlatform is initialized first. + gfxPlatform::GetPlatform(); + + if (ShouldUseOffMainThreadCompositing()) { + CreateCompositor(aCompositorWidth, aCompositorHeight); + if (mLayerManager) { + return; + } + + // If we get here, then off main thread compositing failed to initialize. + sFailedToCreateGLContext = true; + } + + if (!ComputeShouldAccelerate() || sFailedToCreateGLContext) { + printf_stderr(" -- creating basic, not accelerated\n"); + mLayerManager = CreateBasicLayerManager(); + } +} + +void +nsWindow::OnSizeChanged(const gfx::IntSize& aSize) +{ + ALOG("nsWindow: %p OnSizeChanged [%d %d]", (void*)this, aSize.width, aSize.height); + + mBounds.width = aSize.width; + mBounds.height = aSize.height; + + if (mWidgetListener) { + mWidgetListener->WindowResized(this, aSize.width, aSize.height); + } + + if (mAttachedWidgetListener) { + mAttachedWidgetListener->WindowResized(this, aSize.width, aSize.height); + } +} + +void +nsWindow::InitEvent(WidgetGUIEvent& event, LayoutDeviceIntPoint* aPoint) +{ + if (aPoint) { + event.mRefPoint = *aPoint; + } else { + event.mRefPoint = LayoutDeviceIntPoint(0, 0); + } + + event.mTime = PR_Now() / 1000; +} + +void +nsWindow::UpdateOverscrollVelocity(const float aX, const float aY) +{ + if (NativePtr<NPZCSupport>::Locked npzcs{mNPZCSupport}) { + npzcs->UpdateOverscrollVelocity(aX, aY); + } +} + +void +nsWindow::UpdateOverscrollOffset(const float aX, const float aY) +{ + if (NativePtr<NPZCSupport>::Locked npzcs{mNPZCSupport}) { + npzcs->UpdateOverscrollOffset(aX, aY); + } +} + +void +nsWindow::SetScrollingRootContent(const bool isRootContent) +{ + // On Android, the Controller thread and UI thread are the same. + MOZ_ASSERT(APZThreadUtils::IsControllerThread(), "nsWindow::SetScrollingRootContent must be called from the controller thread"); + + if (NativePtr<NPZCSupport>::Locked npzcs{mNPZCSupport}) { + npzcs->SetScrollingRootContent(isRootContent); + } +} + +void +nsWindow::SetSelectionDragState(bool aState) +{ + if (NativePtr<NPZCSupport>::Locked npzcs{mNPZCSupport}) { + npzcs->SetSelectionDragState(aState); + } +} + +void * +nsWindow::GetNativeData(uint32_t aDataType) +{ + switch (aDataType) { + // used by GLContextProviderEGL, nullptr is EGL_DEFAULT_DISPLAY + case NS_NATIVE_DISPLAY: + return nullptr; + + case NS_NATIVE_WIDGET: + return (void *) this; + + case NS_RAW_NATIVE_IME_CONTEXT: { + void* pseudoIMEContext = GetPseudoIMEContext(); + if (pseudoIMEContext) { + return pseudoIMEContext; + } + // We assume that there is only one context per process on Android + return NS_ONLY_ONE_NATIVE_IME_CONTEXT; + } + + case NS_JAVA_SURFACE: + if (NativePtr<LayerViewSupport>::Locked lvs{mLayerViewSupport}) { + return lvs->GetSurface().Get(); + } + return nullptr; + + case NS_PRESENTATION_WINDOW: + return PMPMSupport::sWindow; + + case NS_PRESENTATION_SURFACE: + return PMPMSupport::sSurface; + } + + return nullptr; +} + +void +nsWindow::SetNativeData(uint32_t aDataType, uintptr_t aVal) +{ + switch (aDataType) { + case NS_PRESENTATION_SURFACE: + PMPMSupport::sSurface = reinterpret_cast<EGLSurface>(aVal); + break; + } +} + +void +nsWindow::DispatchHitTest(const WidgetTouchEvent& aEvent) +{ + if (aEvent.mMessage == eTouchStart && aEvent.mTouches.Length() == 1) { + // Since touch events don't get retargeted by PositionedEventTargeting.cpp + // code on Fennec, we dispatch a dummy mouse event that *does* get + // retargeted. The Fennec browser.js code can use this to activate the + // highlight element in case the this touchstart is the start of a tap. + WidgetMouseEvent hittest(true, eMouseHitTest, this, + WidgetMouseEvent::eReal); + hittest.mRefPoint = aEvent.mTouches[0]->mRefPoint; + hittest.mIgnoreRootScrollFrame = true; + hittest.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH; + nsEventStatus status; + DispatchEvent(&hittest, status); + + if (mAPZEventState && hittest.hitCluster) { + mAPZEventState->ProcessClusterHit(); + } + } +} + +static unsigned int ConvertAndroidKeyCodeToDOMKeyCode(int androidKeyCode) +{ + // Special-case alphanumeric keycodes because they are most common. + if (androidKeyCode >= AKEYCODE_A && + androidKeyCode <= AKEYCODE_Z) { + return androidKeyCode - AKEYCODE_A + NS_VK_A; + } + + if (androidKeyCode >= AKEYCODE_0 && + androidKeyCode <= AKEYCODE_9) { + return androidKeyCode - AKEYCODE_0 + NS_VK_0; + } + + switch (androidKeyCode) { + // KEYCODE_UNKNOWN (0) ... KEYCODE_HOME (3) + case AKEYCODE_BACK: return NS_VK_ESCAPE; + // KEYCODE_CALL (5) ... KEYCODE_POUND (18) + case AKEYCODE_DPAD_UP: return NS_VK_UP; + case AKEYCODE_DPAD_DOWN: return NS_VK_DOWN; + case AKEYCODE_DPAD_LEFT: return NS_VK_LEFT; + case AKEYCODE_DPAD_RIGHT: return NS_VK_RIGHT; + case AKEYCODE_DPAD_CENTER: return NS_VK_RETURN; + case AKEYCODE_VOLUME_UP: return NS_VK_VOLUME_UP; + case AKEYCODE_VOLUME_DOWN: return NS_VK_VOLUME_DOWN; + // KEYCODE_VOLUME_POWER (26) ... KEYCODE_Z (54) + case AKEYCODE_COMMA: return NS_VK_COMMA; + case AKEYCODE_PERIOD: return NS_VK_PERIOD; + case AKEYCODE_ALT_LEFT: return NS_VK_ALT; + case AKEYCODE_ALT_RIGHT: return NS_VK_ALT; + case AKEYCODE_SHIFT_LEFT: return NS_VK_SHIFT; + case AKEYCODE_SHIFT_RIGHT: return NS_VK_SHIFT; + case AKEYCODE_TAB: return NS_VK_TAB; + case AKEYCODE_SPACE: return NS_VK_SPACE; + // KEYCODE_SYM (63) ... KEYCODE_ENVELOPE (65) + case AKEYCODE_ENTER: return NS_VK_RETURN; + case AKEYCODE_DEL: return NS_VK_BACK; // Backspace + case AKEYCODE_GRAVE: return NS_VK_BACK_QUOTE; + // KEYCODE_MINUS (69) + case AKEYCODE_EQUALS: return NS_VK_EQUALS; + case AKEYCODE_LEFT_BRACKET: return NS_VK_OPEN_BRACKET; + case AKEYCODE_RIGHT_BRACKET: return NS_VK_CLOSE_BRACKET; + case AKEYCODE_BACKSLASH: return NS_VK_BACK_SLASH; + case AKEYCODE_SEMICOLON: return NS_VK_SEMICOLON; + // KEYCODE_APOSTROPHE (75) + case AKEYCODE_SLASH: return NS_VK_SLASH; + // KEYCODE_AT (77) ... KEYCODE_MEDIA_FAST_FORWARD (90) + case AKEYCODE_MUTE: return NS_VK_VOLUME_MUTE; + case AKEYCODE_PAGE_UP: return NS_VK_PAGE_UP; + case AKEYCODE_PAGE_DOWN: return NS_VK_PAGE_DOWN; + // KEYCODE_PICTSYMBOLS (94) ... KEYCODE_BUTTON_MODE (110) + case AKEYCODE_ESCAPE: return NS_VK_ESCAPE; + case AKEYCODE_FORWARD_DEL: return NS_VK_DELETE; + case AKEYCODE_CTRL_LEFT: return NS_VK_CONTROL; + case AKEYCODE_CTRL_RIGHT: return NS_VK_CONTROL; + case AKEYCODE_CAPS_LOCK: return NS_VK_CAPS_LOCK; + case AKEYCODE_SCROLL_LOCK: return NS_VK_SCROLL_LOCK; + // KEYCODE_META_LEFT (117) ... KEYCODE_FUNCTION (119) + case AKEYCODE_SYSRQ: return NS_VK_PRINTSCREEN; + case AKEYCODE_BREAK: return NS_VK_PAUSE; + case AKEYCODE_MOVE_HOME: return NS_VK_HOME; + case AKEYCODE_MOVE_END: return NS_VK_END; + case AKEYCODE_INSERT: return NS_VK_INSERT; + // KEYCODE_FORWARD (125) ... KEYCODE_MEDIA_RECORD (130) + case AKEYCODE_F1: return NS_VK_F1; + case AKEYCODE_F2: return NS_VK_F2; + case AKEYCODE_F3: return NS_VK_F3; + case AKEYCODE_F4: return NS_VK_F4; + case AKEYCODE_F5: return NS_VK_F5; + case AKEYCODE_F6: return NS_VK_F6; + case AKEYCODE_F7: return NS_VK_F7; + case AKEYCODE_F8: return NS_VK_F8; + case AKEYCODE_F9: return NS_VK_F9; + case AKEYCODE_F10: return NS_VK_F10; + case AKEYCODE_F11: return NS_VK_F11; + case AKEYCODE_F12: return NS_VK_F12; + case AKEYCODE_NUM_LOCK: return NS_VK_NUM_LOCK; + case AKEYCODE_NUMPAD_0: return NS_VK_NUMPAD0; + case AKEYCODE_NUMPAD_1: return NS_VK_NUMPAD1; + case AKEYCODE_NUMPAD_2: return NS_VK_NUMPAD2; + case AKEYCODE_NUMPAD_3: return NS_VK_NUMPAD3; + case AKEYCODE_NUMPAD_4: return NS_VK_NUMPAD4; + case AKEYCODE_NUMPAD_5: return NS_VK_NUMPAD5; + case AKEYCODE_NUMPAD_6: return NS_VK_NUMPAD6; + case AKEYCODE_NUMPAD_7: return NS_VK_NUMPAD7; + case AKEYCODE_NUMPAD_8: return NS_VK_NUMPAD8; + case AKEYCODE_NUMPAD_9: return NS_VK_NUMPAD9; + case AKEYCODE_NUMPAD_DIVIDE: return NS_VK_DIVIDE; + case AKEYCODE_NUMPAD_MULTIPLY: return NS_VK_MULTIPLY; + case AKEYCODE_NUMPAD_SUBTRACT: return NS_VK_SUBTRACT; + case AKEYCODE_NUMPAD_ADD: return NS_VK_ADD; + case AKEYCODE_NUMPAD_DOT: return NS_VK_DECIMAL; + case AKEYCODE_NUMPAD_COMMA: return NS_VK_SEPARATOR; + case AKEYCODE_NUMPAD_ENTER: return NS_VK_RETURN; + case AKEYCODE_NUMPAD_EQUALS: return NS_VK_EQUALS; + // KEYCODE_NUMPAD_LEFT_PAREN (162) ... KEYCODE_CALCULATOR (210) + + // Needs to confirm the behavior. If the key switches the open state + // of Japanese IME (or switches input character between Hiragana and + // Roman numeric characters), then, it might be better to use + // NS_VK_KANJI which is used for Alt+Zenkaku/Hankaku key on Windows. + case AKEYCODE_ZENKAKU_HANKAKU: return 0; + case AKEYCODE_EISU: return NS_VK_EISU; + case AKEYCODE_MUHENKAN: return NS_VK_NONCONVERT; + case AKEYCODE_HENKAN: return NS_VK_CONVERT; + case AKEYCODE_KATAKANA_HIRAGANA: return 0; + case AKEYCODE_YEN: return NS_VK_BACK_SLASH; // Same as other platforms. + case AKEYCODE_RO: return NS_VK_BACK_SLASH; // Same as other platforms. + case AKEYCODE_KANA: return NS_VK_KANA; + case AKEYCODE_ASSIST: return NS_VK_HELP; + + // the A key is the action key for gamepad devices. + case AKEYCODE_BUTTON_A: return NS_VK_RETURN; + + default: + ALOG("ConvertAndroidKeyCodeToDOMKeyCode: " + "No DOM keycode for Android keycode %d", androidKeyCode); + return 0; + } +} + +static KeyNameIndex +ConvertAndroidKeyCodeToKeyNameIndex(int keyCode, int action, + int domPrintableKeyValue) +{ + // Special-case alphanumeric keycodes because they are most common. + if (keyCode >= AKEYCODE_A && keyCode <= AKEYCODE_Z) { + return KEY_NAME_INDEX_USE_STRING; + } + + if (keyCode >= AKEYCODE_0 && keyCode <= AKEYCODE_9) { + return KEY_NAME_INDEX_USE_STRING; + } + + switch (keyCode) { + +#define NS_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX(aNativeKey, aKeyNameIndex) \ + case aNativeKey: return aKeyNameIndex; + +#include "NativeKeyToDOMKeyName.h" + +#undef NS_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX + + // KEYCODE_0 (7) ... KEYCODE_9 (16) + case AKEYCODE_STAR: // '*' key + case AKEYCODE_POUND: // '#' key + + // KEYCODE_A (29) ... KEYCODE_Z (54) + + case AKEYCODE_COMMA: // ',' key + case AKEYCODE_PERIOD: // '.' key + case AKEYCODE_SPACE: + case AKEYCODE_GRAVE: // '`' key + case AKEYCODE_MINUS: // '-' key + case AKEYCODE_EQUALS: // '=' key + case AKEYCODE_LEFT_BRACKET: // '[' key + case AKEYCODE_RIGHT_BRACKET: // ']' key + case AKEYCODE_BACKSLASH: // '\' key + case AKEYCODE_SEMICOLON: // ';' key + case AKEYCODE_APOSTROPHE: // ''' key + case AKEYCODE_SLASH: // '/' key + case AKEYCODE_AT: // '@' key + case AKEYCODE_PLUS: // '+' key + + case AKEYCODE_NUMPAD_0: + case AKEYCODE_NUMPAD_1: + case AKEYCODE_NUMPAD_2: + case AKEYCODE_NUMPAD_3: + case AKEYCODE_NUMPAD_4: + case AKEYCODE_NUMPAD_5: + case AKEYCODE_NUMPAD_6: + case AKEYCODE_NUMPAD_7: + case AKEYCODE_NUMPAD_8: + case AKEYCODE_NUMPAD_9: + case AKEYCODE_NUMPAD_DIVIDE: + case AKEYCODE_NUMPAD_MULTIPLY: + case AKEYCODE_NUMPAD_SUBTRACT: + case AKEYCODE_NUMPAD_ADD: + case AKEYCODE_NUMPAD_DOT: + case AKEYCODE_NUMPAD_COMMA: + case AKEYCODE_NUMPAD_EQUALS: + case AKEYCODE_NUMPAD_LEFT_PAREN: + case AKEYCODE_NUMPAD_RIGHT_PAREN: + + case AKEYCODE_YEN: // yen sign key + case AKEYCODE_RO: // Japanese Ro key + return KEY_NAME_INDEX_USE_STRING; + + case AKEYCODE_ENDCALL: + case AKEYCODE_NUM: // XXX Not sure + case AKEYCODE_HEADSETHOOK: + case AKEYCODE_NOTIFICATION: // XXX Not sure + case AKEYCODE_PICTSYMBOLS: + + case AKEYCODE_BUTTON_A: + case AKEYCODE_BUTTON_B: + case AKEYCODE_BUTTON_C: + case AKEYCODE_BUTTON_X: + case AKEYCODE_BUTTON_Y: + case AKEYCODE_BUTTON_Z: + case AKEYCODE_BUTTON_L1: + case AKEYCODE_BUTTON_R1: + case AKEYCODE_BUTTON_L2: + case AKEYCODE_BUTTON_R2: + case AKEYCODE_BUTTON_THUMBL: + case AKEYCODE_BUTTON_THUMBR: + case AKEYCODE_BUTTON_START: + case AKEYCODE_BUTTON_SELECT: + case AKEYCODE_BUTTON_MODE: + + case AKEYCODE_MUTE: // mutes the microphone + case AKEYCODE_MEDIA_CLOSE: + + case AKEYCODE_DVR: + + case AKEYCODE_BUTTON_1: + case AKEYCODE_BUTTON_2: + case AKEYCODE_BUTTON_3: + case AKEYCODE_BUTTON_4: + case AKEYCODE_BUTTON_5: + case AKEYCODE_BUTTON_6: + case AKEYCODE_BUTTON_7: + case AKEYCODE_BUTTON_8: + case AKEYCODE_BUTTON_9: + case AKEYCODE_BUTTON_10: + case AKEYCODE_BUTTON_11: + case AKEYCODE_BUTTON_12: + case AKEYCODE_BUTTON_13: + case AKEYCODE_BUTTON_14: + case AKEYCODE_BUTTON_15: + case AKEYCODE_BUTTON_16: + + case AKEYCODE_MANNER_MODE: + case AKEYCODE_3D_MODE: + case AKEYCODE_CONTACTS: + return KEY_NAME_INDEX_Unidentified; + + case AKEYCODE_UNKNOWN: + MOZ_ASSERT( + action != AKEY_EVENT_ACTION_MULTIPLE, + "Don't call this when action is AKEY_EVENT_ACTION_MULTIPLE!"); + // It's actually an unknown key if the action isn't ACTION_MULTIPLE. + // However, it might cause text input. So, let's check the value. + return domPrintableKeyValue ? + KEY_NAME_INDEX_USE_STRING : KEY_NAME_INDEX_Unidentified; + + default: + ALOG("ConvertAndroidKeyCodeToKeyNameIndex: " + "No DOM key name index for Android keycode %d", keyCode); + return KEY_NAME_INDEX_Unidentified; + } +} + +static CodeNameIndex +ConvertAndroidScanCodeToCodeNameIndex(int scanCode) +{ + switch (scanCode) { + +#define NS_NATIVE_KEY_TO_DOM_CODE_NAME_INDEX(aNativeKey, aCodeNameIndex) \ + case aNativeKey: return aCodeNameIndex; + +#include "NativeKeyToDOMCodeName.h" + +#undef NS_NATIVE_KEY_TO_DOM_CODE_NAME_INDEX + + default: + return CODE_NAME_INDEX_UNKNOWN; + } +} + +static bool +IsModifierKey(int32_t keyCode) +{ + using mozilla::java::sdk::KeyEvent; + return keyCode == KeyEvent::KEYCODE_ALT_LEFT || + keyCode == KeyEvent::KEYCODE_ALT_RIGHT || + keyCode == KeyEvent::KEYCODE_SHIFT_LEFT || + keyCode == KeyEvent::KEYCODE_SHIFT_RIGHT || + keyCode == KeyEvent::KEYCODE_CTRL_LEFT || + keyCode == KeyEvent::KEYCODE_CTRL_RIGHT || + keyCode == KeyEvent::KEYCODE_META_LEFT || + keyCode == KeyEvent::KEYCODE_META_RIGHT; +} + +static Modifiers +GetModifiers(int32_t metaState) +{ + using mozilla::java::sdk::KeyEvent; + return (metaState & KeyEvent::META_ALT_MASK ? MODIFIER_ALT : 0) + | (metaState & KeyEvent::META_SHIFT_MASK ? MODIFIER_SHIFT : 0) + | (metaState & KeyEvent::META_CTRL_MASK ? MODIFIER_CONTROL : 0) + | (metaState & KeyEvent::META_META_MASK ? MODIFIER_META : 0) + | (metaState & KeyEvent::META_FUNCTION_ON ? MODIFIER_FN : 0) + | (metaState & KeyEvent::META_CAPS_LOCK_ON ? MODIFIER_CAPSLOCK : 0) + | (metaState & KeyEvent::META_NUM_LOCK_ON ? MODIFIER_NUMLOCK : 0) + | (metaState & KeyEvent::META_SCROLL_LOCK_ON ? MODIFIER_SCROLLLOCK : 0); +} + +static void +InitKeyEvent(WidgetKeyboardEvent& event, + int32_t action, int32_t keyCode, int32_t scanCode, + int32_t metaState, int64_t time, int32_t unicodeChar, + int32_t baseUnicodeChar, int32_t domPrintableKeyValue, + int32_t repeatCount, int32_t flags) +{ + const uint32_t domKeyCode = ConvertAndroidKeyCodeToDOMKeyCode(keyCode); + const int32_t charCode = unicodeChar ? unicodeChar : baseUnicodeChar; + + event.mModifiers = GetModifiers(metaState); + + if (event.mMessage == eKeyPress) { + // Android gives us \n, so filter out some control characters. + event.mIsChar = (charCode >= ' '); + event.mCharCode = event.mIsChar ? charCode : 0; + event.mKeyCode = event.mIsChar ? 0 : domKeyCode; + event.mPluginEvent.Clear(); + + // For keypress, if the unicode char already has modifiers applied, we + // don't specify extra modifiers. If UnicodeChar() != BaseUnicodeChar() + // it means UnicodeChar() already has modifiers applied. + // Note that on Android 4.x, Alt modifier isn't set when the key input + // causes text input even while right Alt key is pressed. However, + // this is necessary for Android 2.3 compatibility. + if (unicodeChar && unicodeChar != baseUnicodeChar) { + event.mModifiers &= ~(MODIFIER_ALT | MODIFIER_CONTROL + | MODIFIER_META); + } + + } else { + event.mIsChar = false; + event.mCharCode = 0; + event.mKeyCode = domKeyCode; + + ANPEvent pluginEvent; + pluginEvent.inSize = sizeof(pluginEvent); + pluginEvent.eventType = kKey_ANPEventType; + pluginEvent.data.key.action = event.mMessage == eKeyDown + ? kDown_ANPKeyAction : kUp_ANPKeyAction; + pluginEvent.data.key.nativeCode = keyCode; + pluginEvent.data.key.virtualCode = domKeyCode; + pluginEvent.data.key.unichar = charCode; + pluginEvent.data.key.modifiers = + (metaState & sdk::KeyEvent::META_SHIFT_MASK + ? kShift_ANPKeyModifier : 0) | + (metaState & sdk::KeyEvent::META_ALT_MASK + ? kAlt_ANPKeyModifier : 0); + pluginEvent.data.key.repeatCount = repeatCount; + event.mPluginEvent.Copy(pluginEvent); + } + + event.mIsRepeat = + (event.mMessage == eKeyDown || event.mMessage == eKeyPress) && + ((flags & sdk::KeyEvent::FLAG_LONG_PRESS) || repeatCount); + + event.mKeyNameIndex = ConvertAndroidKeyCodeToKeyNameIndex( + keyCode, action, domPrintableKeyValue); + event.mCodeNameIndex = ConvertAndroidScanCodeToCodeNameIndex(scanCode); + + if (event.mKeyNameIndex == KEY_NAME_INDEX_USE_STRING && + domPrintableKeyValue) { + event.mKeyValue = char16_t(domPrintableKeyValue); + } + + event.mLocation = + WidgetKeyboardEvent::ComputeLocationFromCodeValue(event.mCodeNameIndex); + event.mTime = time; +} + +void +nsWindow::GeckoViewSupport::OnKeyEvent(int32_t aAction, int32_t aKeyCode, + int32_t aScanCode, int32_t aMetaState, int64_t aTime, + int32_t aUnicodeChar, int32_t aBaseUnicodeChar, + int32_t aDomPrintableKeyValue, int32_t aRepeatCount, int32_t aFlags, + bool aIsSynthesizedImeKey, jni::Object::Param originalEvent) +{ + RefPtr<nsWindow> kungFuDeathGrip(&window); + if (!aIsSynthesizedImeKey) { + window.UserActivity(); + window.RemoveIMEComposition(); + } + + EventMessage msg; + if (aAction == sdk::KeyEvent::ACTION_DOWN) { + msg = eKeyDown; + } else if (aAction == sdk::KeyEvent::ACTION_UP) { + msg = eKeyUp; + } else if (aAction == sdk::KeyEvent::ACTION_MULTIPLE) { + // Keys with multiple action are handled in Java, + // and we should never see one here + MOZ_CRASH("Cannot handle key with multiple action"); + } else { + ALOG("Unknown key action event!"); + return; + } + + nsEventStatus status = nsEventStatus_eIgnore; + WidgetKeyboardEvent event(true, msg, &window); + window.InitEvent(event, nullptr); + InitKeyEvent(event, aAction, aKeyCode, aScanCode, aMetaState, aTime, + aUnicodeChar, aBaseUnicodeChar, aDomPrintableKeyValue, + aRepeatCount, aFlags); + + if (aIsSynthesizedImeKey) { + // Keys synthesized by Java IME code are saved in the mIMEKeyEvents + // array until the next IME_REPLACE_TEXT event, at which point + // these keys are dispatched in sequence. + mIMEKeyEvents.AppendElement( + mozilla::UniquePtr<WidgetEvent>(event.Duplicate())); + + } else { + window.DispatchEvent(&event, status); + + if (window.Destroyed() || status == nsEventStatus_eConsumeNoDefault) { + // Skip default processing. + return; + } + + mEditable->OnDefaultKeyEvent(originalEvent); + } + + if (msg != eKeyDown || IsModifierKey(aKeyCode)) { + // Skip sending key press event. + return; + } + + WidgetKeyboardEvent pressEvent(true, eKeyPress, &window); + window.InitEvent(pressEvent, nullptr); + InitKeyEvent(pressEvent, aAction, aKeyCode, aScanCode, aMetaState, aTime, + aUnicodeChar, aBaseUnicodeChar, aDomPrintableKeyValue, + aRepeatCount, aFlags); + + if (aIsSynthesizedImeKey) { + mIMEKeyEvents.AppendElement( + mozilla::UniquePtr<WidgetEvent>(pressEvent.Duplicate())); + } else { + window.DispatchEvent(&pressEvent, status); + } +} + +#ifdef DEBUG_ANDROID_IME +#define ALOGIME(args...) ALOG(args) +#else +#define ALOGIME(args...) ((void)0) +#endif + +static nscolor +ConvertAndroidColor(uint32_t aArgb) +{ + return NS_RGBA((aArgb & 0x00ff0000) >> 16, + (aArgb & 0x0000ff00) >> 8, + (aArgb & 0x000000ff), + (aArgb & 0xff000000) >> 24); +} + +/* + * Get the current composition object, if any. + */ +RefPtr<mozilla::TextComposition> +nsWindow::GetIMEComposition() +{ + MOZ_ASSERT(this == FindTopLevel()); + return mozilla::IMEStateManager::GetTextCompositionFor(this); +} + +/* + Remove the composition but leave the text content as-is +*/ +void +nsWindow::RemoveIMEComposition(RemoveIMECompositionFlag aFlag) +{ + // Remove composition on Gecko side + const RefPtr<mozilla::TextComposition> composition(GetIMEComposition()); + if (!composition) { + return; + } + + RefPtr<nsWindow> kungFuDeathGrip(this); + + WidgetCompositionEvent compositionCommitEvent( + true, eCompositionCommit, this); + if (aFlag == COMMIT_IME_COMPOSITION) { + compositionCommitEvent.mMessage = eCompositionCommitAsIs; + } + InitEvent(compositionCommitEvent, nullptr); + DispatchEvent(&compositionCommitEvent); +} + +/* + * Send dummy key events for pages that are unaware of input events, + * to provide web compatibility for pages that depend on key events. + * Our dummy key events have 0 as the keycode. + */ +void +nsWindow::GeckoViewSupport::SendIMEDummyKeyEvents() +{ + WidgetKeyboardEvent downEvent(true, eKeyDown, &window); + window.InitEvent(downEvent, nullptr); + MOZ_ASSERT(downEvent.mKeyCode == 0); + window.DispatchEvent(&downEvent); + + WidgetKeyboardEvent upEvent(true, eKeyUp, &window); + window.InitEvent(upEvent, nullptr); + MOZ_ASSERT(upEvent.mKeyCode == 0); + window.DispatchEvent(&upEvent); +} + +void +nsWindow::GeckoViewSupport::AddIMETextChange(const IMETextChange& aChange) +{ + mIMETextChanges.AppendElement(aChange); + + // We may not be in the middle of flushing, + // in which case this flag is meaningless. + mIMETextChangedDuringFlush = true; + + // Now that we added a new range we need to go back and + // update all the ranges before that. + // Ranges that have offsets which follow this new range + // need to be updated to reflect new offsets + const int32_t delta = aChange.mNewEnd - aChange.mOldEnd; + for (int32_t i = mIMETextChanges.Length() - 2; i >= 0; i--) { + IMETextChange& previousChange = mIMETextChanges[i]; + if (previousChange.mStart > aChange.mOldEnd) { + previousChange.mStart += delta; + previousChange.mOldEnd += delta; + previousChange.mNewEnd += delta; + } + } + + // Now go through all ranges to merge any ranges that are connected + // srcIndex is the index of the range to merge from + // dstIndex is the index of the range to potentially merge into + int32_t srcIndex = mIMETextChanges.Length() - 1; + int32_t dstIndex = srcIndex; + + while (--dstIndex >= 0) { + IMETextChange& src = mIMETextChanges[srcIndex]; + IMETextChange& dst = mIMETextChanges[dstIndex]; + // When merging a more recent change into an older + // change, we need to compare recent change's (start, oldEnd) + // range to the older change's (start, newEnd) + if (src.mOldEnd < dst.mStart || dst.mNewEnd < src.mStart) { + // No overlap between ranges + continue; + } + // When merging two ranges, there are generally four posibilities: + // [----(----]----), (----[----]----), + // [----(----)----], (----[----)----] + // where [----] is the first range and (----) is the second range + // As seen above, the start of the merged range is always the lesser + // of the two start offsets. OldEnd and NewEnd then need to be + // adjusted separately depending on the case. In any case, the change + // in text length of the merged range should be the sum of text length + // changes of the two original ranges, i.e., + // newNewEnd - newOldEnd == newEnd1 - oldEnd1 + newEnd2 - oldEnd2 + dst.mStart = std::min(dst.mStart, src.mStart); + if (src.mOldEnd < dst.mNewEnd) { + // New range overlaps or is within previous range; merge + dst.mNewEnd += src.mNewEnd - src.mOldEnd; + } else { // src.mOldEnd >= dst.mNewEnd + // New range overlaps previous range; merge + dst.mOldEnd += src.mOldEnd - dst.mNewEnd; + dst.mNewEnd = src.mNewEnd; + } + // src merged to dst; delete src. + mIMETextChanges.RemoveElementAt(srcIndex); + // Any ranges that we skip over between src and dst are not mergeable + // so we can safely continue the merge starting at dst + srcIndex = dstIndex; + } +} + +void +nsWindow::GeckoViewSupport::PostFlushIMEChanges() +{ + if (!mIMETextChanges.IsEmpty() || mIMESelectionChanged) { + // Already posted + return; + } + + // Keep a strong reference to the window to keep 'this' alive. + RefPtr<nsWindow> window(&this->window); + + nsAppShell::PostEvent([this, window] { + if (!window->Destroyed()) { + FlushIMEChanges(); + } + }); +} + +void +nsWindow::GeckoViewSupport::FlushIMEChanges(FlushChangesFlag aFlags) +{ + // Only send change notifications if we are *not* masking events, + // i.e. if we have a focused editor, + NS_ENSURE_TRUE_VOID(!mIMEMaskEventsCount); + + nsCOMPtr<nsISelection> imeSelection; + nsCOMPtr<nsIContent> imeRoot; + + // If we are receiving notifications, we must have selection/root content. + MOZ_ALWAYS_SUCCEEDS(IMEStateManager::GetFocusSelectionAndRoot( + getter_AddRefs(imeSelection), getter_AddRefs(imeRoot))); + + // Make sure we still have a valid selection/root. We can potentially get + // a stale selection/root if the editor becomes hidden, for example. + NS_ENSURE_TRUE_VOID(imeRoot->IsInComposedDoc()); + + RefPtr<nsWindow> kungFuDeathGrip(&window); + window.UserActivity(); + + struct TextRecord { + nsString text; + int32_t start; + int32_t oldEnd; + int32_t newEnd; + }; + AutoTArray<TextRecord, 4> textTransaction; + if (mIMETextChanges.Length() > textTransaction.Capacity()) { + textTransaction.SetCapacity(mIMETextChanges.Length()); + } + + mIMETextChangedDuringFlush = false; + + auto shouldAbort = [=] () -> bool { + if (!mIMETextChangedDuringFlush) { + return false; + } + // A query event could have triggered more text changes to come in, as + // indicated by our flag. If that happens, try flushing IME changes + // again. + if (aFlags == FLUSH_FLAG_NONE) { + FlushIMEChanges(FLUSH_FLAG_RETRY); + } else { + // Don't retry if already retrying, to avoid infinite loops. + __android_log_print(ANDROID_LOG_WARN, "GeckoViewSupport", + "Already retrying IME flush"); + } + return true; + }; + + for (const IMETextChange &change : mIMETextChanges) { + if (change.mStart == change.mOldEnd && + change.mStart == change.mNewEnd) { + continue; + } + + WidgetQueryContentEvent event(true, eQueryTextContent, &window); + + if (change.mNewEnd != change.mStart) { + window.InitEvent(event, nullptr); + event.InitForQueryTextContent(change.mStart, + change.mNewEnd - change.mStart); + window.DispatchEvent(&event); + NS_ENSURE_TRUE_VOID(event.mSucceeded); + NS_ENSURE_TRUE_VOID(event.mReply.mContentsRoot == imeRoot.get()); + } + + if (shouldAbort()) { + return; + } + + textTransaction.AppendElement( + TextRecord{event.mReply.mString, change.mStart, + change.mOldEnd, change.mNewEnd}); + } + + int32_t selStart = -1; + int32_t selEnd = -1; + + if (mIMESelectionChanged) { + WidgetQueryContentEvent event(true, eQuerySelectedText, &window); + window.InitEvent(event, nullptr); + window.DispatchEvent(&event); + + NS_ENSURE_TRUE_VOID(event.mSucceeded); + NS_ENSURE_TRUE_VOID(event.mReply.mContentsRoot == imeRoot.get()); + + if (shouldAbort()) { + return; + } + + selStart = int32_t(event.GetSelectionStart()); + selEnd = int32_t(event.GetSelectionEnd()); + } + + JNIEnv* const env = jni::GetGeckoThreadEnv(); + auto flushOnException = [=] () -> bool { + if (!env->ExceptionCheck()) { + return false; + } + if (aFlags != FLUSH_FLAG_RECOVER) { + // First time seeing an exception; try flushing text. + env->ExceptionClear(); + __android_log_print(ANDROID_LOG_WARN, "GeckoViewSupport", + "Recovering from IME exception"); + FlushIMEText(FLUSH_FLAG_RECOVER); + } else { + // Give up because we've already tried. + MOZ_CATCH_JNI_EXCEPTION(env); + } + return true; + }; + + // Commit the text change and selection change transaction. + mIMETextChanges.Clear(); + + for (const TextRecord& record : textTransaction) { + mEditable->OnTextChange(record.text, record.start, + record.oldEnd, record.newEnd); + if (flushOnException()) { + return; + } + } + + if (mIMESelectionChanged) { + mIMESelectionChanged = false; + mEditable->OnSelectionChange(selStart, selEnd); + flushOnException(); + } +} + +void +nsWindow::GeckoViewSupport::FlushIMEText(FlushChangesFlag aFlags) +{ + // Notify Java of the newly focused content + mIMETextChanges.Clear(); + mIMESelectionChanged = true; + + // Use 'INT32_MAX / 2' here because subsequent text changes might combine + // with this text change, and overflow might occur if we just use + // INT32_MAX. + IMENotification notification(NOTIFY_IME_OF_TEXT_CHANGE); + notification.mTextChangeData.mStartOffset = 0; + notification.mTextChangeData.mRemovedEndOffset = INT32_MAX / 2; + notification.mTextChangeData.mAddedEndOffset = INT32_MAX / 2; + NotifyIME(notification); + + FlushIMEChanges(aFlags); +} + +static jni::ObjectArray::LocalRef +ConvertRectArrayToJavaRectFArray(JNIEnv* aJNIEnv, const nsTArray<LayoutDeviceIntRect>& aRects, const LayoutDeviceIntPoint& aOffset, const CSSToLayoutDeviceScale aScale) +{ + size_t length = aRects.Length(); + jobjectArray rects = aJNIEnv->NewObjectArray(length, sdk::RectF::Context().ClassRef(), nullptr); + auto rectsRef = jni::ObjectArray::LocalRef::Adopt(aJNIEnv, rects); + for (size_t i = 0; i < length; i++) { + sdk::RectF::LocalRef rect(aJNIEnv); + LayoutDeviceIntRect tmp = aRects[i] + aOffset; + sdk::RectF::New(tmp.x / aScale.scale, tmp.y / aScale.scale, + (tmp.x + tmp.width) / aScale.scale, + (tmp.y + tmp.height) / aScale.scale, + &rect); + rectsRef->SetElement(i, rect); + } + return rectsRef; +} + +void +nsWindow::GeckoViewSupport::UpdateCompositionRects() +{ + const auto composition(window.GetIMEComposition()); + if (NS_WARN_IF(!composition)) { + return; + } + + uint32_t offset = composition->NativeOffsetOfStartComposition(); + WidgetQueryContentEvent textRects(true, eQueryTextRectArray, &window); + textRects.InitForQueryTextRectArray(offset, composition->String().Length()); + window.DispatchEvent(&textRects); + + auto rects = + ConvertRectArrayToJavaRectFArray(jni::GetGeckoThreadEnv(), + textRects.mReply.mRectArray, + window.WidgetToScreenOffset(), + window.GetDefaultScale()); + + mEditable->UpdateCompositionRects(rects); +} + +void +nsWindow::GeckoViewSupport::AsyncNotifyIME(int32_t aNotification) +{ + // Keep a strong reference to the window to keep 'this' alive. + RefPtr<nsWindow> window(&this->window); + + nsAppShell::PostEvent([this, window, aNotification] { + if (mIMEMaskEventsCount) { + return; + } + + mEditable->NotifyIME(aNotification); + }); +} + +bool +nsWindow::GeckoViewSupport::NotifyIME(const IMENotification& aIMENotification) +{ + MOZ_ASSERT(mEditable); + + switch (aIMENotification.mMessage) { + case REQUEST_TO_COMMIT_COMPOSITION: { + ALOGIME("IME: REQUEST_TO_COMMIT_COMPOSITION"); + + window.RemoveIMEComposition(); + + AsyncNotifyIME(GeckoEditableListener:: + NOTIFY_IME_TO_COMMIT_COMPOSITION); + return true; + } + + case REQUEST_TO_CANCEL_COMPOSITION: { + ALOGIME("IME: REQUEST_TO_CANCEL_COMPOSITION"); + + window.RemoveIMEComposition(CANCEL_IME_COMPOSITION); + + AsyncNotifyIME(GeckoEditableListener:: + NOTIFY_IME_TO_CANCEL_COMPOSITION); + return true; + } + + case NOTIFY_IME_OF_FOCUS: { + ALOGIME("IME: NOTIFY_IME_OF_FOCUS"); + // Keep a strong reference to the window to keep 'this' alive. + RefPtr<nsWindow> window(&this->window); + + // Post an event because we have to flush the text before sending a + // focus event, and we may not be able to flush text during the + // NotifyIME call. + nsAppShell::PostEvent([this, window] { + --mIMEMaskEventsCount; + if (mIMEMaskEventsCount || window->Destroyed()) { + return; + } + + FlushIMEText(); + + // IME will call requestCursorUpdates after getting context. + // So reset cursor update mode before getting context. + mIMEMonitorCursor = false; + + MOZ_ASSERT(mEditable); + mEditable->NotifyIME(GeckoEditableListener::NOTIFY_IME_OF_FOCUS); + }); + return true; + } + + case NOTIFY_IME_OF_BLUR: { + ALOGIME("IME: NOTIFY_IME_OF_BLUR"); + + if (!mIMEMaskEventsCount) { + mEditable->NotifyIME(GeckoEditableListener::NOTIFY_IME_OF_BLUR); + } + + // Mask events because we lost focus. Unmask on the next focus. + mIMEMaskEventsCount++; + return true; + } + + case NOTIFY_IME_OF_SELECTION_CHANGE: { + ALOGIME("IME: NOTIFY_IME_OF_SELECTION_CHANGE"); + + PostFlushIMEChanges(); + mIMESelectionChanged = true; + return true; + } + + case NOTIFY_IME_OF_TEXT_CHANGE: { + ALOGIME("IME: NotifyIMEOfTextChange: s=%d, oe=%d, ne=%d", + aIMENotification.mTextChangeData.mStartOffset, + aIMENotification.mTextChangeData.mRemovedEndOffset, + aIMENotification.mTextChangeData.mAddedEndOffset); + + /* Make sure Java's selection is up-to-date */ + PostFlushIMEChanges(); + mIMESelectionChanged = true; + AddIMETextChange(IMETextChange(aIMENotification)); + return true; + } + + case NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED: { + ALOGIME("IME: NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED"); + + // Hardware keyboard support requires each string rect. + if (AndroidBridge::Bridge() && AndroidBridge::Bridge()->GetAPIVersion() >= 21 && mIMEMonitorCursor) { + UpdateCompositionRects(); + } + return true; + } + + default: + return false; + } +} + +void +nsWindow::GeckoViewSupport::SetInputContext(const InputContext& aContext, + const InputContextAction& aAction) +{ + MOZ_ASSERT(mEditable); + + ALOGIME("IME: SetInputContext: s=0x%X, 0x%X, action=0x%X, 0x%X", + aContext.mIMEState.mEnabled, aContext.mIMEState.mOpen, + aAction.mCause, aAction.mFocusChange); + + // Ensure that opening the virtual keyboard is allowed for this specific + // InputContext depending on the content.ime.strict.policy pref + if (aContext.mIMEState.mEnabled != IMEState::DISABLED && + aContext.mIMEState.mEnabled != IMEState::PLUGIN && + Preferences::GetBool("content.ime.strict_policy", false) && + !aAction.ContentGotFocusByTrustedCause() && + !aAction.UserMightRequestOpenVKB()) { + return; + } + + IMEState::Enabled enabled = aContext.mIMEState.mEnabled; + + // Only show the virtual keyboard for plugins if mOpen is set appropriately. + // This avoids showing it whenever a plugin is focused. Bug 747492 + if (aContext.mIMEState.mEnabled == IMEState::PLUGIN && + aContext.mIMEState.mOpen != IMEState::OPEN) { + enabled = IMEState::DISABLED; + } + + mInputContext = aContext; + mInputContext.mIMEState.mEnabled = enabled; + + if (enabled == IMEState::ENABLED && aAction.UserMightRequestOpenVKB()) { + // Don't reset keyboard when we should simply open the vkb + mEditable->NotifyIME(GeckoEditableListener::NOTIFY_IME_OPEN_VKB); + return; + } + + if (mIMEUpdatingContext) { + return; + } + + // Keep a strong reference to the window to keep 'this' alive. + RefPtr<nsWindow> window(&this->window); + mIMEUpdatingContext = true; + + nsAppShell::PostEvent([this, window] { + mIMEUpdatingContext = false; + if (window->Destroyed()) { + return; + } + MOZ_ASSERT(mEditable); + mEditable->NotifyIMEContext(mInputContext.mIMEState.mEnabled, + mInputContext.mHTMLInputType, + mInputContext.mHTMLInputInputmode, + mInputContext.mActionHint); + }); +} + +InputContext +nsWindow::GeckoViewSupport::GetInputContext() +{ + InputContext context = mInputContext; + context.mIMEState.mOpen = IMEState::OPEN_STATE_NOT_SUPPORTED; + return context; +} + +void +nsWindow::GeckoViewSupport::OnImeSynchronize() +{ + if (!mIMEMaskEventsCount) { + FlushIMEChanges(); + } + mEditable->NotifyIME(GeckoEditableListener::NOTIFY_IME_REPLY_EVENT); +} + +void +nsWindow::GeckoViewSupport::OnImeReplaceText(int32_t aStart, int32_t aEnd, + jni::String::Param aText) +{ + AutoIMESynchronize as(this); + + if (mIMEMaskEventsCount > 0) { + // Not focused; still reply to events, but don't do anything else. + return; + } + + /* + Replace text in Gecko thread from aStart to aEnd with the string text. + */ + RefPtr<nsWindow> kungFuDeathGrip(&window); + nsString string(aText->ToString()); + + const auto composition(window.GetIMEComposition()); + MOZ_ASSERT(!composition || !composition->IsEditorHandlingEvent()); + + const bool composing = !mIMERanges->IsEmpty(); + + if (!mIMEKeyEvents.IsEmpty() || !composition || + uint32_t(aStart) != composition->NativeOffsetOfStartComposition() || + uint32_t(aEnd) != composition->NativeOffsetOfStartComposition() + + composition->String().Length()) + { + // Only start a new composition if we have key events, + // if we don't have an existing composition, or + // the replaced text does not match our composition. + window.RemoveIMEComposition(); + + { + // Use text selection to set target postion(s) for + // insert, or replace, of text. + WidgetSelectionEvent event(true, eSetSelection, &window); + window.InitEvent(event, nullptr); + event.mOffset = uint32_t(aStart); + event.mLength = uint32_t(aEnd - aStart); + event.mExpandToClusterBoundary = false; + event.mReason = nsISelectionListener::IME_REASON; + window.DispatchEvent(&event); + } + + if (!mIMEKeyEvents.IsEmpty()) { + nsEventStatus status; + for (uint32_t i = 0; i < mIMEKeyEvents.Length(); i++) { + const auto event = static_cast<WidgetGUIEvent*>( + mIMEKeyEvents[i].get()); + if (event->mMessage == eKeyPress && + status == nsEventStatus_eConsumeNoDefault) { + MOZ_ASSERT(i > 0 && + mIMEKeyEvents[i - 1]->mMessage == eKeyDown); + // The previous key down event resulted in eConsumeNoDefault + // so we should not dispatch the current key press event. + continue; + } + // widget for duplicated events is initially nullptr. + event->mWidget = &window; + window.DispatchEvent(event, status); + } + mIMEKeyEvents.Clear(); + return; + } + + if (aStart != aEnd) { + // Perform a deletion first. + WidgetContentCommandEvent event( + true, eContentCommandDelete, &window); + window.InitEvent(event, nullptr); + window.DispatchEvent(&event); + } + + // Start a composition if we're not just performing a deletion. + if (composing || !string.IsEmpty()) { + WidgetCompositionEvent event(true, eCompositionStart, &window); + window.InitEvent(event, nullptr); + window.DispatchEvent(&event); + } + + } else if (composition->String().Equals(string)) { + /* If the new text is the same as the existing composition text, + * the NS_COMPOSITION_CHANGE event does not generate a text + * change notification. However, the Java side still expects + * one, so we manually generate a notification. */ + IMETextChange dummyChange; + dummyChange.mStart = aStart; + dummyChange.mOldEnd = dummyChange.mNewEnd = aEnd; + AddIMETextChange(dummyChange); + } + + // Check composition again because previous events may have destroyed our + // composition; in which case we should just skip the next event. + if (window.GetIMEComposition()) { + WidgetCompositionEvent event(true, eCompositionChange, &window); + window.InitEvent(event, nullptr); + event.mData = string; + + if (composing) { + event.mRanges = new TextRangeArray(); + mIMERanges.swap(event.mRanges); + } else { + event.mMessage = eCompositionCommit; + } + + window.DispatchEvent(&event); + + } else if (composing) { + // Ensure IME ranges are empty. + mIMERanges->Clear(); + } + + if (mInputContext.mMayBeIMEUnaware) { + SendIMEDummyKeyEvents(); + } +} + +void +nsWindow::GeckoViewSupport::OnImeAddCompositionRange( + int32_t aStart, int32_t aEnd, int32_t aRangeType, int32_t aRangeStyle, + int32_t aRangeLineStyle, bool aRangeBoldLine, int32_t aRangeForeColor, + int32_t aRangeBackColor, int32_t aRangeLineColor) +{ + if (mIMEMaskEventsCount > 0) { + // Not focused. + return; + } + + TextRange range; + range.mStartOffset = aStart; + range.mEndOffset = aEnd; + range.mRangeType = ToTextRangeType(aRangeType); + range.mRangeStyle.mDefinedStyles = aRangeStyle; + range.mRangeStyle.mLineStyle = aRangeLineStyle; + range.mRangeStyle.mIsBoldLine = aRangeBoldLine; + range.mRangeStyle.mForegroundColor = + ConvertAndroidColor(uint32_t(aRangeForeColor)); + range.mRangeStyle.mBackgroundColor = + ConvertAndroidColor(uint32_t(aRangeBackColor)); + range.mRangeStyle.mUnderlineColor = + ConvertAndroidColor(uint32_t(aRangeLineColor)); + mIMERanges->AppendElement(range); +} + +void +nsWindow::GeckoViewSupport::OnImeUpdateComposition(int32_t aStart, int32_t aEnd) +{ + if (mIMEMaskEventsCount > 0) { + // Not focused. + return; + } + + RefPtr<nsWindow> kungFuDeathGrip(&window); + + // A composition with no ranges means we want to set the selection. + if (mIMERanges->IsEmpty()) { + MOZ_ASSERT(aStart >= 0 && aEnd >= 0); + window.RemoveIMEComposition(); + + WidgetSelectionEvent selEvent(true, eSetSelection, &window); + window.InitEvent(selEvent, nullptr); + + selEvent.mOffset = std::min(aStart, aEnd); + selEvent.mLength = std::max(aStart, aEnd) - selEvent.mOffset; + selEvent.mReversed = aStart > aEnd; + selEvent.mExpandToClusterBoundary = false; + + window.DispatchEvent(&selEvent); + return; + } + + /* + Update the composition from aStart to aEnd using + information from added ranges. This is only used for + visual indication and does not affect the text content. + Only the offsets are specified and not the text content + to eliminate the possibility of this event altering the + text content unintentionally. + */ + const auto composition(window.GetIMEComposition()); + MOZ_ASSERT(!composition || !composition->IsEditorHandlingEvent()); + + WidgetCompositionEvent event(true, eCompositionChange, &window); + window.InitEvent(event, nullptr); + + event.mRanges = new TextRangeArray(); + mIMERanges.swap(event.mRanges); + + if (!composition || + uint32_t(aStart) != composition->NativeOffsetOfStartComposition() || + uint32_t(aEnd) != composition->NativeOffsetOfStartComposition() + + composition->String().Length()) + { + // Only start new composition if we don't have an existing one, + // or if the existing composition doesn't match the new one. + window.RemoveIMEComposition(); + + { + WidgetSelectionEvent event(true, eSetSelection, &window); + window.InitEvent(event, nullptr); + event.mOffset = uint32_t(aStart); + event.mLength = uint32_t(aEnd - aStart); + event.mExpandToClusterBoundary = false; + event.mReason = nsISelectionListener::IME_REASON; + window.DispatchEvent(&event); + } + + { + WidgetQueryContentEvent queryEvent(true, eQuerySelectedText, + &window); + window.InitEvent(queryEvent, nullptr); + window.DispatchEvent(&queryEvent); + MOZ_ASSERT(queryEvent.mSucceeded); + event.mData = queryEvent.mReply.mString; + } + + { + WidgetCompositionEvent event(true, eCompositionStart, &window); + window.InitEvent(event, nullptr); + window.DispatchEvent(&event); + } + + } else { + // If the new composition matches the existing composition, + // reuse the old composition. + event.mData = composition->String(); + } + +#ifdef DEBUG_ANDROID_IME + const NS_ConvertUTF16toUTF8 data(event.mData); + const char* text = data.get(); + ALOGIME("IME: IME_SET_TEXT: text=\"%s\", length=%u, range=%u", + text, event.mData.Length(), event.mRanges->Length()); +#endif // DEBUG_ANDROID_IME + + // Previous events may have destroyed our composition; bail in that case. + if (window.GetIMEComposition()) { + window.DispatchEvent(&event); + } +} + +void +nsWindow::GeckoViewSupport::OnImeRequestCursorUpdates(int aRequestMode) +{ + if (aRequestMode == IME_MONITOR_CURSOR_ONE_SHOT) { + UpdateCompositionRects(); + return; + } + + mIMEMonitorCursor = (aRequestMode == IME_MONITOR_CURSOR_START_MONITOR); +} + +void +nsWindow::UserActivity() +{ + if (!mIdleService) { + mIdleService = do_GetService("@mozilla.org/widget/idleservice;1"); + } + + if (mIdleService) { + mIdleService->ResetIdleTimeOut(0); + } +} + +nsresult +nsWindow::NotifyIMEInternal(const IMENotification& aIMENotification) +{ + MOZ_ASSERT(this == FindTopLevel()); + + if (!mGeckoViewSupport) { + // Non-GeckoView windows don't support IME operations. + return NS_ERROR_NOT_AVAILABLE; + } + + if (mGeckoViewSupport->NotifyIME(aIMENotification)) { + return NS_OK; + } + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP_(void) +nsWindow::SetInputContext(const InputContext& aContext, + const InputContextAction& aAction) +{ + nsWindow* top = FindTopLevel(); + MOZ_ASSERT(top); + + if (!top->mGeckoViewSupport) { + // Non-GeckoView windows don't support IME operations. + return; + } + + // We are using an IME event later to notify Java, and the IME event + // will be processed by the top window. Therefore, to ensure the + // IME event uses the correct mInputContext, we need to let the top + // window process SetInputContext + top->mGeckoViewSupport->SetInputContext(aContext, aAction); +} + +NS_IMETHODIMP_(InputContext) +nsWindow::GetInputContext() +{ + nsWindow* top = FindTopLevel(); + MOZ_ASSERT(top); + + if (!top->mGeckoViewSupport) { + // Non-GeckoView windows don't support IME operations. + return InputContext(); + } + + // We let the top window process SetInputContext, + // so we should let it process GetInputContext as well. + return top->mGeckoViewSupport->GetInputContext(); +} + +nsIMEUpdatePreference +nsWindow::GetIMEUpdatePreference() +{ + // While a plugin has focus, nsWindow for Android doesn't need any + // notifications. + if (GetInputContext().mIMEState.mEnabled == IMEState::PLUGIN) { + return nsIMEUpdatePreference(); + } + return nsIMEUpdatePreference(nsIMEUpdatePreference::NOTIFY_TEXT_CHANGE); +} + +nsresult +nsWindow::SynthesizeNativeTouchPoint(uint32_t aPointerId, + TouchPointerState aPointerState, + LayoutDeviceIntPoint aPoint, + double aPointerPressure, + uint32_t aPointerOrientation, + nsIObserver* aObserver) +{ + mozilla::widget::AutoObserverNotifier notifier(aObserver, "touchpoint"); + + int eventType; + switch (aPointerState) { + case TOUCH_CONTACT: + // This could be a ACTION_DOWN or ACTION_MOVE depending on the + // existing state; it is mapped to the right thing in Java. + eventType = sdk::MotionEvent::ACTION_POINTER_DOWN; + break; + case TOUCH_REMOVE: + // This could be turned into a ACTION_UP in Java + eventType = sdk::MotionEvent::ACTION_POINTER_UP; + break; + case TOUCH_CANCEL: + eventType = sdk::MotionEvent::ACTION_CANCEL; + break; + case TOUCH_HOVER: // not supported for now + default: + return NS_ERROR_UNEXPECTED; + } + + MOZ_ASSERT(mLayerViewSupport); + GeckoLayerClient::LocalRef client = mLayerViewSupport->GetLayerClient(); + client->SynthesizeNativeTouchPoint(aPointerId, eventType, + aPoint.x, aPoint.y, aPointerPressure, aPointerOrientation); + + return NS_OK; +} + +nsresult +nsWindow::SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint, + uint32_t aNativeMessage, + uint32_t aModifierFlags, + nsIObserver* aObserver) +{ + mozilla::widget::AutoObserverNotifier notifier(aObserver, "mouseevent"); + + MOZ_ASSERT(mLayerViewSupport); + GeckoLayerClient::LocalRef client = mLayerViewSupport->GetLayerClient(); + client->SynthesizeNativeMouseEvent(aNativeMessage, aPoint.x, aPoint.y); + + return NS_OK; +} + +nsresult +nsWindow::SynthesizeNativeMouseMove(LayoutDeviceIntPoint aPoint, + nsIObserver* aObserver) +{ + mozilla::widget::AutoObserverNotifier notifier(aObserver, "mouseevent"); + + MOZ_ASSERT(mLayerViewSupport); + GeckoLayerClient::LocalRef client = mLayerViewSupport->GetLayerClient(); + client->SynthesizeNativeMouseEvent(sdk::MotionEvent::ACTION_HOVER_MOVE, aPoint.x, aPoint.y); + + return NS_OK; +} + +bool +nsWindow::PreRender(WidgetRenderingContext* aContext) +{ + if (Destroyed()) { + return true; + } + + layers::Compositor* compositor = aContext->mCompositor; + + GeckoLayerClient::LocalRef client; + + if (NativePtr<LayerViewSupport>::Locked lvs{mLayerViewSupport}) { + client = lvs->GetLayerClient(); + } + + if (compositor && client) { + // Android Color is ARGB which is apparently unusual. + compositor->SetDefaultClearColor(gfx::Color::UnusualFromARGB((uint32_t)client->ClearColor())); + } + + return true; +} +void +nsWindow::DrawWindowUnderlay(WidgetRenderingContext* aContext, + LayoutDeviceIntRect aRect) +{ + if (Destroyed()) { + return; + } + + GeckoLayerClient::LocalRef client; + + if (NativePtr<LayerViewSupport>::Locked lvs{mLayerViewSupport}) { + client = lvs->GetLayerClient(); + } + + if (!client) { + return; + } + + LayerRenderer::Frame::LocalRef frame = client->CreateFrame(); + mLayerRendererFrame = frame; + if (NS_WARN_IF(!mLayerRendererFrame)) { + return; + } + + if (!WidgetPaintsBackground()) { + return; + } + + frame->BeginDrawing(); +} + +void +nsWindow::DrawWindowOverlay(WidgetRenderingContext* aContext, + LayoutDeviceIntRect aRect) +{ + PROFILER_LABEL("nsWindow", "DrawWindowOverlay", + js::ProfileEntry::Category::GRAPHICS); + + if (Destroyed() || NS_WARN_IF(!mLayerRendererFrame)) { + return; + } + + mLayerRendererFrame->EndDrawing(); + mLayerRendererFrame = nullptr; +} + +bool +nsWindow::WidgetPaintsBackground() +{ + static bool sWidgetPaintsBackground = true; + static bool sWidgetPaintsBackgroundPrefCached = false; + + if (!sWidgetPaintsBackgroundPrefCached) { + sWidgetPaintsBackgroundPrefCached = true; + mozilla::Preferences::AddBoolVarCache(&sWidgetPaintsBackground, + "android.widget_paints_background", + true); + } + + return sWidgetPaintsBackground; +} + +bool +nsWindow::NeedsPaint() +{ + if (!mLayerViewSupport || mLayerViewSupport->CompositorPaused() || + // FindTopLevel() != nsWindow::TopWindow() || + !GetLayerManager(nullptr)) { + return false; + } + return nsIWidget::NeedsPaint(); +} + +void +nsWindow::ConfigureAPZControllerThread() +{ + APZThreadUtils::SetControllerThread(nullptr); +} + +already_AddRefed<GeckoContentController> +nsWindow::CreateRootContentController() +{ + RefPtr<GeckoContentController> controller = new AndroidContentController(this, mAPZEventState, mAPZC); + return controller.forget(); +} + +uint32_t +nsWindow::GetMaxTouchPoints() const +{ + return GeckoAppShell::GetMaxTouchPoints(); +} + +void +nsWindow::UpdateZoomConstraints(const uint32_t& aPresShellId, + const FrameMetrics::ViewID& aViewId, + const mozilla::Maybe<ZoomConstraints>& aConstraints) +{ + nsBaseWidget::UpdateZoomConstraints(aPresShellId, aViewId, aConstraints); +} + +CompositorBridgeParent* +nsWindow::GetCompositorBridgeParent() const +{ + return mCompositorSession ? mCompositorSession->GetInProcessBridge() : nullptr; +} + +already_AddRefed<nsIScreen> +nsWindow::GetWidgetScreen() +{ + nsCOMPtr<nsIScreenManager> screenMgr = + do_GetService("@mozilla.org/gfx/screenmanager;1"); + MOZ_ASSERT(screenMgr, "Failed to get nsIScreenManager"); + + nsCOMPtr<nsIScreen> screen; + screenMgr->ScreenForId(mScreenId, getter_AddRefs(screen)); + + return screen.forget(); +} + +jni::DependentRef<java::GeckoLayerClient> +nsWindow::GetLayerClient() +{ + if (NativePtr<LayerViewSupport>::Locked lvs{mLayerViewSupport}) { + return lvs->GetLayerClient().Get(); + } + return nullptr; +} diff --git a/widget/android/nsWindow.h b/widget/android/nsWindow.h new file mode 100644 index 000000000..f3d7566f7 --- /dev/null +++ b/widget/android/nsWindow.h @@ -0,0 +1,289 @@ +/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * vim: set sw=4 ts=4 expandtab: + * 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 NSWINDOW_H_ +#define NSWINDOW_H_ + +#include "nsBaseWidget.h" +#include "gfxPoint.h" +#include "nsIIdleServiceInternal.h" +#include "nsTArray.h" +#include "AndroidJavaWrappers.h" +#include "GeneratedJNIWrappers.h" +#include "mozilla/EventForwards.h" +#include "mozilla/Mutex.h" +#include "mozilla/StaticPtr.h" +#include "mozilla/TextRange.h" +#include "mozilla/UniquePtr.h" + +struct ANPEvent; + +namespace mozilla { + class TextComposition; + class WidgetTouchEvent; + + namespace layers { + class CompositorBridgeParent; + class CompositorBridgeChild; + class LayerManager; + class APZCTreeManager; + } +} + +class nsWindow : public nsBaseWidget +{ +private: + virtual ~nsWindow(); + +public: + using nsBaseWidget::GetLayerManager; + + nsWindow(); + + NS_DECL_ISUPPORTS_INHERITED + + static void InitNatives(); + void SetScreenId(uint32_t aScreenId) { mScreenId = aScreenId; } + +private: + uint32_t mScreenId; + + // An Event subclass that guards against stale events. + template<typename Lambda, + bool IsStatic = Lambda::isStatic, + typename InstanceType = typename Lambda::ThisArgType, + class Impl = typename Lambda::TargetClass> + class WindowEvent; + + // Smart pointer for holding a pointer back to the nsWindow inside a native + // object class. The nsWindow pointer is automatically cleared when the + // nsWindow is destroyed, and a WindowPtr<Impl>::Locked class is provided + // for thread-safe access to the nsWindow pointer off of the Gecko thread. + template<class Impl> class WindowPtr; + + // Smart pointer for holding a pointer to a native object class. The + // pointer is automatically cleared when the object is destroyed. + template<class Impl> + class NativePtr final + { + friend WindowPtr<Impl>; + + static const char sName[]; + + WindowPtr<Impl>* mPtr; + Impl* mImpl; + mozilla::Mutex mImplLock; + + public: + class Locked; + + NativePtr() : mPtr(nullptr), mImpl(nullptr), mImplLock(sName) {} + ~NativePtr() { MOZ_ASSERT(!mPtr); } + + operator Impl*() const + { + MOZ_ASSERT(NS_IsMainThread()); + return mImpl; + } + + Impl* operator->() const { return operator Impl*(); } + + template<class Instance, typename... Args> + void Attach(Instance aInstance, nsWindow* aWindow, Args&&... aArgs); + void Detach(); + }; + + class LayerViewSupport; + // Object that implements native LayerView calls. + // Owned by the Java LayerView instance. + NativePtr<LayerViewSupport> mLayerViewSupport; + + class NPZCSupport; + // Object that implements native NativePanZoomController calls. + // Owned by the Java NativePanZoomController instance. + NativePtr<NPZCSupport> mNPZCSupport; + + class GeckoViewSupport; + // Object that implements native GeckoView calls and associated states. + // nullptr for nsWindows that were not opened from GeckoView. + // Because other objects get destroyed in the mGeckOViewSupport destructor, + // keep it last in the list, so its destructor is called first. + mozilla::UniquePtr<GeckoViewSupport> mGeckoViewSupport; + + // Class that implements native PresentationMediaPlayerManager calls. + class PMPMSupport; + +public: + static nsWindow* TopWindow(); + + void OnSizeChanged(const mozilla::gfx::IntSize& aSize); + + void InitEvent(mozilla::WidgetGUIEvent& event, + LayoutDeviceIntPoint* aPoint = 0); + + void UpdateOverscrollVelocity(const float aX, const float aY); + void UpdateOverscrollOffset(const float aX, const float aY); + void SetScrollingRootContent(const bool isRootContent); + + // + // nsIWidget + // + + using nsBaseWidget::Create; // for Create signature not overridden here + virtual MOZ_MUST_USE nsresult Create(nsIWidget* aParent, + nsNativeWidget aNativeParent, + const LayoutDeviceIntRect& aRect, + nsWidgetInitData* aInitData) override; + virtual void Destroy() override; + NS_IMETHOD ConfigureChildren(const nsTArray<nsIWidget::Configuration>&) override; + NS_IMETHOD SetParent(nsIWidget* aNewParent) override; + virtual nsIWidget *GetParent(void) override; + virtual float GetDPI() override; + virtual double GetDefaultScaleInternal() override; + NS_IMETHOD Show(bool aState) override; + virtual bool IsVisible() const override; + virtual void ConstrainPosition(bool aAllowSlop, + int32_t *aX, + int32_t *aY) override; + NS_IMETHOD Move(double aX, + double aY) override; + NS_IMETHOD Resize(double aWidth, + double aHeight, + bool aRepaint) override; + NS_IMETHOD Resize(double aX, + double aY, + double aWidth, + double aHeight, + bool aRepaint) override; + void SetZIndex(int32_t aZIndex) override; + virtual void SetSizeMode(nsSizeMode aMode) override; + NS_IMETHOD Enable(bool aState) override; + virtual bool IsEnabled() const override; + NS_IMETHOD Invalidate(const LayoutDeviceIntRect& aRect) override; + NS_IMETHOD SetFocus(bool aRaise = false) override; + virtual LayoutDeviceIntRect GetScreenBounds() override; + virtual LayoutDeviceIntPoint WidgetToScreenOffset() override; + NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, + nsEventStatus& aStatus) override; + nsEventStatus DispatchEvent(mozilla::WidgetGUIEvent* aEvent); + virtual already_AddRefed<nsIScreen> GetWidgetScreen() override; + virtual nsresult MakeFullScreen(bool aFullScreen, + nsIScreen* aTargetScreen = nullptr) + override; + + NS_IMETHOD SetCursor(nsCursor aCursor) override { return NS_ERROR_NOT_IMPLEMENTED; } + NS_IMETHOD SetCursor(imgIContainer* aCursor, + uint32_t aHotspotX, + uint32_t aHotspotY) override { return NS_ERROR_NOT_IMPLEMENTED; } + NS_IMETHOD SetHasTransparentBackground(bool aTransparent) { return NS_OK; } + NS_IMETHOD GetHasTransparentBackground(bool& aTransparent) { aTransparent = false; return NS_OK; } + NS_IMETHOD HideWindowChrome(bool aShouldHide) override { return NS_ERROR_NOT_IMPLEMENTED; } + void* GetNativeData(uint32_t aDataType) override; + void SetNativeData(uint32_t aDataType, uintptr_t aVal) override; + NS_IMETHOD SetTitle(const nsAString& aTitle) override { return NS_OK; } + NS_IMETHOD SetIcon(const nsAString& aIconSpec) override { return NS_OK; } + NS_IMETHOD GetAttention(int32_t aCycleCount) override { return NS_ERROR_NOT_IMPLEMENTED; } + NS_IMETHOD BeginResizeDrag(mozilla::WidgetGUIEvent* aEvent, + int32_t aHorizontal, + int32_t aVertical) override + { + return NS_ERROR_NOT_IMPLEMENTED; + } + + NS_IMETHOD_(void) SetInputContext(const InputContext& aContext, + const InputContextAction& aAction) override; + NS_IMETHOD_(InputContext) GetInputContext() override; + virtual nsIMEUpdatePreference GetIMEUpdatePreference() override; + + void SetSelectionDragState(bool aState); + LayerManager* GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr, + LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE, + LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT) override; + + virtual bool NeedsPaint() override; + virtual bool PreRender(mozilla::widget::WidgetRenderingContext* aContext) override; + virtual void DrawWindowUnderlay(mozilla::widget::WidgetRenderingContext* aContext, + LayoutDeviceIntRect aRect) override; + virtual void DrawWindowOverlay(mozilla::widget::WidgetRenderingContext* aContext, + LayoutDeviceIntRect aRect) override; + + virtual bool WidgetPaintsBackground() override; + + virtual uint32_t GetMaxTouchPoints() const override; + + void UpdateZoomConstraints(const uint32_t& aPresShellId, + const FrameMetrics::ViewID& aViewId, + const mozilla::Maybe<ZoomConstraints>& aConstraints) override; + + nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId, + TouchPointerState aPointerState, + LayoutDeviceIntPoint aPoint, + double aPointerPressure, + uint32_t aPointerOrientation, + nsIObserver* aObserver) override; + nsresult SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint, + uint32_t aNativeMessage, + uint32_t aModifierFlags, + nsIObserver* aObserver) override; + nsresult SynthesizeNativeMouseMove(LayoutDeviceIntPoint aPoint, + nsIObserver* aObserver) override; + + CompositorBridgeParent* GetCompositorBridgeParent() const; + + mozilla::jni::DependentRef<mozilla::java::GeckoLayerClient> GetLayerClient(); + +protected: + void BringToFront(); + nsWindow *FindTopLevel(); + bool IsTopLevel(); + + RefPtr<mozilla::TextComposition> GetIMEComposition(); + enum RemoveIMECompositionFlag { + CANCEL_IME_COMPOSITION, + COMMIT_IME_COMPOSITION + }; + void RemoveIMEComposition(RemoveIMECompositionFlag aFlag = COMMIT_IME_COMPOSITION); + + void ConfigureAPZControllerThread() override; + void DispatchHitTest(const mozilla::WidgetTouchEvent& aEvent); + + already_AddRefed<GeckoContentController> CreateRootContentController() override; + + // Call this function when the users activity is the direct cause of an + // event (like a keypress or mouse click). + void UserActivity(); + + bool mIsVisible; + nsTArray<nsWindow*> mChildren; + nsWindow* mParent; + + double mStartDist; + double mLastDist; + + nsCOMPtr<nsIIdleServiceInternal> mIdleService; + + bool mAwaitingFullScreen; + bool mIsFullScreen; + + virtual nsresult NotifyIMEInternal( + const IMENotification& aIMENotification) override; + + bool UseExternalCompositingSurface() const override { + return true; + } + + static void DumpWindows(); + static void DumpWindows(const nsTArray<nsWindow*>& wins, int indent = 0); + static void LogWindow(nsWindow *win, int index, int indent); + +private: + void CreateLayerManager(int aCompositorWidth, int aCompositorHeight); + void RedrawAll(); + + mozilla::java::LayerRenderer::Frame::GlobalRef mLayerRendererFrame; +}; + +#endif /* NSWINDOW_H_ */ |