Issue #1053 - Remove Android Widget Toolkit specific files

This commit is contained in:
Matt A. Tobin 2020-02-20 11:22:40 -05:00 committed by Roy Tam
commit 27b8966a39
73 changed files with 0 additions and 24492 deletions

View file

@ -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

View file

@ -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__

View file

@ -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

View file

@ -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

View file

@ -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__ */

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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_ */

View file

@ -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_ */

View file

@ -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
*/
}

View file

@ -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();
}
}

View file

@ -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__ */

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;
}
}
}

View file

@ -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__ */

View file

@ -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

View file

@ -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__

View file

@ -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

View file

@ -1,2 +0,0 @@
android.graphics.Rect
android.graphics.RectF

View file

@ -1 +0,0 @@
android.os.Bundle

View file

@ -1 +0,0 @@
android.view.KeyEvent

View file

@ -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

View file

@ -1,5 +0,0 @@
android.media.MediaCodec
android.media.MediaCodec$BufferInfo
android.media.MediaCodec$CryptoInfo
android.media.MediaDrm$KeyStatus
android.media.MediaFormat

View file

@ -1 +0,0 @@
android.view.MotionEvent

View file

@ -1,2 +0,0 @@
android.graphics.SurfaceTexture
android.view.Surface

View file

@ -1 +0,0 @@
android.view.ViewConfiguration

View file

@ -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',
]

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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__

View file

@ -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

View file

@ -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',
]

View file

@ -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__

View file

@ -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__

View file

@ -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__

View file

@ -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__

View file

@ -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

View file

@ -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__

View file

@ -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',
]

View file

@ -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

View file

@ -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);
}

View file

@ -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___ */

View file

@ -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();
}
}

View file

@ -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__

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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;
};

View file

@ -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);
};

View file

@ -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;
}

View file

@ -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__

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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__ */

View file

@ -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);
}
}
}

View file

@ -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___ */

View file

@ -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

View file

@ -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_ */