mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-15 08:53:07 +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