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