/* -*- Mode: c++; c-basic-offset: 2; 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 <unistd.h> // for gettid
#include "nsCOMPtr.h"
#include "mozilla/jni/Refs.h"
#include "nsIMutableArray.h"
#include "nsIMIMEInfo.h"
#include "nsIGeckoViewBridge.h"
#include "mozilla/jni/Utils.h"
// Some debug #defines
// #define DEBUG_ANDROID_EVENTS
// #define DEBUG_ANDROID_WIDGET
namespace mozilla {
class AutoLocalJNIFrame;
namespace hal {
class BatteryInformation;
class NetworkInformation;
} // namespace hal
class AndroidBridge final {
public :
static bool IsJavaUiThread() {
return mozilla::jni::GetUIThreadId() == gettid();
}
static void ConstructBridge();
static void DeconstructBridge();
static AndroidBridge* Bridge() { return sBridge; }
void Vibrate(const nsTArray<uint32_t>& aPattern);
void GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSize,
uint8_t* const aBuf);
// 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 GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo);
void GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo);
nsresult GetProxyForURI(const nsACString& aSpec, const nsACString& aScheme,
const nsACString& aHost, const int32_t aPort,
nsACString& aResult);
bool PumpMessageLoop();
// Utility methods.
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);
protected :
static AndroidBridge* sBridge;
AndroidBridge();
~AndroidBridge();
jni::Object::GlobalRef mMessageQueue;
jfieldID mMessageQueueMessages;
jmethodID mMessageQueueNext;
};
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 :
explicit 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 :
explicit AutoLocalJNIFrame(int nEntries = 15)
: mEntries(nEntries),
mJNIEnv(jni::GetGeckoThreadEnv()),
mHasFrameBeenPushed(false ) {
MOZ_ASSERT(mJNIEnv);
Push();
}
explicit 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;
};
} // namespace mozilla
#define NS_ANDROIDBRIDGE_CID \
{ \
0x0FE2321D, 0xEBD9, 0x467D, { \
0xA7, 0x43, 0x03, 0xA6, 0x8D, 0x40, 0x59, 0x9E \
} \
}
class nsAndroidBridge final : public nsIGeckoViewBridge {
public :
NS_DECL_ISUPPORTS
NS_DECL_NSIGECKOVIEWBRIDGE
NS_FORWARD_SAFE_NSIGECKOVIEWEVENTDISPATCHER(mEventDispatcher)
nsAndroidBridge();
private :
~nsAndroidBridge();
nsCOMPtr<nsIGeckoViewEventDispatcher> mEventDispatcher;
protected :
};
#endif /* AndroidBridge_h__ */
quality 100%
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland