Backed out changeset f1426851ae30 (bug 1844755) for causing failures on test_printpre...
[gecko.git] / widget / android / AndroidBridge.h
blobf2070ef31a21aa73489b3266de70f36c927eb962
1 /* -*- Mode: c++; c-basic-offset: 2; tab-width: 20; indent-tabs-mode: nil; -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef AndroidBridge_h__
7 #define AndroidBridge_h__
9 #include <unistd.h> // for gettid
11 #include "nsCOMPtr.h"
13 #include "mozilla/jni/Refs.h"
15 #include "nsIMutableArray.h"
16 #include "nsIMIMEInfo.h"
18 #include "nsIAndroidBridge.h"
20 #include "mozilla/jni/Utils.h"
21 #include "nsTHashMap.h"
23 // Some debug #defines
24 // #define DEBUG_ANDROID_EVENTS
25 // #define DEBUG_ANDROID_WIDGET
27 namespace mozilla {
29 class AutoLocalJNIFrame;
31 namespace hal {
32 class BatteryInformation;
33 class NetworkInformation;
34 enum class ScreenOrientation : uint32_t;
35 } // namespace hal
37 class AndroidBridge final {
38 public:
39 static bool IsJavaUiThread() {
40 return mozilla::jni::GetUIThreadId() == gettid();
43 static void ConstructBridge();
44 static void DeconstructBridge();
46 static AndroidBridge* Bridge() { return sBridge; }
48 bool GetHandlersForURL(const nsAString& aURL,
49 nsIMutableArray* handlersArray = nullptr,
50 nsIHandlerApp** aDefaultApp = nullptr,
51 const nsAString& aAction = u""_ns);
53 bool GetHandlersForMimeType(const nsAString& aMimeType,
54 nsIMutableArray* handlersArray = nullptr,
55 nsIHandlerApp** aDefaultApp = nullptr,
56 const nsAString& aAction = u""_ns);
58 void GetMimeTypeFromExtensions(const nsACString& aFileExt,
59 nsCString& aMimeType);
60 void GetExtensionFromMimeType(const nsACString& aMimeType,
61 nsACString& aFileExt);
63 void Vibrate(const nsTArray<uint32_t>& aPattern);
65 void GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSize,
66 uint8_t* const aBuf);
68 // Returns a global reference to the Context for Fennec's Activity. The
69 // caller is responsible for ensuring this doesn't leak by calling
70 // DeleteGlobalRef() when the context is no longer needed.
71 jobject GetGlobalContextRef(void);
73 void GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo);
75 void GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo);
77 hal::ScreenOrientation GetScreenOrientation();
78 uint16_t GetScreenAngle();
80 nsresult GetProxyForURI(const nsACString& aSpec, const nsACString& aScheme,
81 const nsACString& aHost, const int32_t aPort,
82 nsACString& aResult);
84 bool PumpMessageLoop();
86 // Utility methods.
87 static jfieldID GetFieldID(JNIEnv* env, jclass jClass, const char* fieldName,
88 const char* fieldType);
89 static jfieldID GetStaticFieldID(JNIEnv* env, jclass jClass,
90 const char* fieldName,
91 const char* fieldType);
92 static jmethodID GetMethodID(JNIEnv* env, jclass jClass,
93 const char* methodName, const char* methodType);
94 static jmethodID GetStaticMethodID(JNIEnv* env, jclass jClass,
95 const char* methodName,
96 const char* methodType);
98 static jni::Object::LocalRef ChannelCreate(jni::Object::Param);
100 static void InputStreamClose(jni::Object::Param obj);
101 static uint32_t InputStreamAvailable(jni::Object::Param obj);
102 static nsresult InputStreamRead(jni::Object::Param obj, char* aBuf,
103 uint32_t aCount, uint32_t* aRead);
105 protected:
106 static nsTHashMap<nsStringHashKey, nsString> sStoragePaths;
108 static AndroidBridge* sBridge;
110 AndroidBridge();
111 ~AndroidBridge();
113 jni::Object::GlobalRef mMessageQueue;
114 jfieldID mMessageQueueMessages;
115 jmethodID mMessageQueueNext;
118 class AutoJNIClass {
119 private:
120 JNIEnv* const mEnv;
121 const jclass mClass;
123 public:
124 AutoJNIClass(JNIEnv* jEnv, const char* name)
125 : mEnv(jEnv), mClass(jni::GetClassRef(jEnv, name)) {}
127 ~AutoJNIClass() { mEnv->DeleteLocalRef(mClass); }
129 jclass getRawRef() const { return mClass; }
131 jclass getGlobalRef() const {
132 return static_cast<jclass>(mEnv->NewGlobalRef(mClass));
135 jfieldID getField(const char* name, const char* type) const {
136 return AndroidBridge::GetFieldID(mEnv, mClass, name, type);
139 jfieldID getStaticField(const char* name, const char* type) const {
140 return AndroidBridge::GetStaticFieldID(mEnv, mClass, name, type);
143 jmethodID getMethod(const char* name, const char* type) const {
144 return AndroidBridge::GetMethodID(mEnv, mClass, name, type);
147 jmethodID getStaticMethod(const char* name, const char* type) const {
148 return AndroidBridge::GetStaticMethodID(mEnv, mClass, name, type);
152 class AutoJObject {
153 public:
154 explicit AutoJObject(JNIEnv* aJNIEnv = nullptr) : mObject(nullptr) {
155 mJNIEnv = aJNIEnv ? aJNIEnv : jni::GetGeckoThreadEnv();
158 AutoJObject(JNIEnv* aJNIEnv, jobject aObject) {
159 mJNIEnv = aJNIEnv ? aJNIEnv : jni::GetGeckoThreadEnv();
160 mObject = aObject;
163 ~AutoJObject() {
164 if (mObject) mJNIEnv->DeleteLocalRef(mObject);
167 jobject operator=(jobject aObject) {
168 if (mObject) {
169 mJNIEnv->DeleteLocalRef(mObject);
171 return mObject = aObject;
174 operator jobject() { return mObject; }
176 private:
177 JNIEnv* mJNIEnv;
178 jobject mObject;
181 class AutoLocalJNIFrame {
182 public:
183 explicit AutoLocalJNIFrame(int nEntries = 15)
184 : mEntries(nEntries),
185 mJNIEnv(jni::GetGeckoThreadEnv()),
186 mHasFrameBeenPushed(false) {
187 MOZ_ASSERT(mJNIEnv);
188 Push();
191 explicit AutoLocalJNIFrame(JNIEnv* aJNIEnv, int nEntries = 15)
192 : mEntries(nEntries),
193 mJNIEnv(aJNIEnv ? aJNIEnv : jni::GetGeckoThreadEnv()),
194 mHasFrameBeenPushed(false) {
195 MOZ_ASSERT(mJNIEnv);
196 Push();
199 ~AutoLocalJNIFrame() {
200 if (mHasFrameBeenPushed) {
201 Pop();
205 JNIEnv* GetEnv() { return mJNIEnv; }
207 bool CheckForException() {
208 if (mJNIEnv->ExceptionCheck()) {
209 MOZ_CATCH_JNI_EXCEPTION(mJNIEnv);
210 return true;
212 return false;
215 // Note! Calling Purge makes all previous local refs created in
216 // the AutoLocalJNIFrame's scope INVALID; be sure that you locked down
217 // any local refs that you need to keep around in global refs!
218 void Purge() {
219 Pop();
220 Push();
223 template <typename ReturnType = jobject>
224 ReturnType Pop(ReturnType aResult = nullptr) {
225 MOZ_ASSERT(mHasFrameBeenPushed);
226 mHasFrameBeenPushed = false;
227 return static_cast<ReturnType>(
228 mJNIEnv->PopLocalFrame(static_cast<jobject>(aResult)));
231 private:
232 void Push() {
233 MOZ_ASSERT(!mHasFrameBeenPushed);
234 // Make sure there is enough space to store a local ref to the
235 // exception. I am not completely sure this is needed, but does
236 // not hurt.
237 if (mJNIEnv->PushLocalFrame(mEntries + 1) != 0) {
238 CheckForException();
239 return;
241 mHasFrameBeenPushed = true;
244 const int mEntries;
245 JNIEnv* const mJNIEnv;
246 bool mHasFrameBeenPushed;
249 } // namespace mozilla
251 #define NS_ANDROIDBRIDGE_CID \
253 0x0FE2321D, 0xEBD9, 0x467D, { \
254 0xA7, 0x43, 0x03, 0xA6, 0x8D, 0x40, 0x59, 0x9E \
258 class nsAndroidBridge final : public nsIAndroidBridge {
259 public:
260 NS_DECL_ISUPPORTS
261 NS_DECL_NSIANDROIDBRIDGE
263 NS_FORWARD_SAFE_NSIANDROIDEVENTDISPATCHER(mEventDispatcher)
265 nsAndroidBridge();
267 private:
268 ~nsAndroidBridge();
270 nsCOMPtr<nsIAndroidEventDispatcher> mEventDispatcher;
272 protected:
275 #endif /* AndroidBridge_h__ */