|
1 /* -*- Mode: c++; c-basic-offset: 4; 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/. */ |
|
5 |
|
6 #include "AndroidJavaWrappers.h" |
|
7 #include "AndroidBridge.h" |
|
8 #include "AndroidBridgeUtilities.h" |
|
9 #include "nsIDOMKeyEvent.h" |
|
10 #include "nsIWidget.h" |
|
11 #include "mozilla/BasicEvents.h" |
|
12 #include "mozilla/TouchEvents.h" |
|
13 |
|
14 using namespace mozilla; |
|
15 using namespace mozilla::dom; |
|
16 using namespace mozilla::widget::android; |
|
17 |
|
18 jclass AndroidGeckoEvent::jGeckoEventClass = 0; |
|
19 jfieldID AndroidGeckoEvent::jActionField = 0; |
|
20 jfieldID AndroidGeckoEvent::jTypeField = 0; |
|
21 jfieldID AndroidGeckoEvent::jAckNeededField = 0; |
|
22 jfieldID AndroidGeckoEvent::jTimeField = 0; |
|
23 jfieldID AndroidGeckoEvent::jPoints = 0; |
|
24 jfieldID AndroidGeckoEvent::jPointIndicies = 0; |
|
25 jfieldID AndroidGeckoEvent::jPressures = 0; |
|
26 jfieldID AndroidGeckoEvent::jPointRadii = 0; |
|
27 jfieldID AndroidGeckoEvent::jOrientations = 0; |
|
28 jfieldID AndroidGeckoEvent::jXField = 0; |
|
29 jfieldID AndroidGeckoEvent::jYField = 0; |
|
30 jfieldID AndroidGeckoEvent::jZField = 0; |
|
31 jfieldID AndroidGeckoEvent::jDistanceField = 0; |
|
32 jfieldID AndroidGeckoEvent::jRectField = 0; |
|
33 jfieldID AndroidGeckoEvent::jNativeWindowField = 0; |
|
34 |
|
35 jfieldID AndroidGeckoEvent::jCharactersField = 0; |
|
36 jfieldID AndroidGeckoEvent::jCharactersExtraField = 0; |
|
37 jfieldID AndroidGeckoEvent::jDataField = 0; |
|
38 jfieldID AndroidGeckoEvent::jDOMPrintableKeyValueField = 0; |
|
39 jfieldID AndroidGeckoEvent::jKeyCodeField = 0; |
|
40 jfieldID AndroidGeckoEvent::jMetaStateField = 0; |
|
41 jfieldID AndroidGeckoEvent::jDomKeyLocationField = 0; |
|
42 jfieldID AndroidGeckoEvent::jFlagsField = 0; |
|
43 jfieldID AndroidGeckoEvent::jUnicodeCharField = 0; |
|
44 jfieldID AndroidGeckoEvent::jBaseUnicodeCharField = 0; |
|
45 jfieldID AndroidGeckoEvent::jRepeatCountField = 0; |
|
46 jfieldID AndroidGeckoEvent::jCountField = 0; |
|
47 jfieldID AndroidGeckoEvent::jStartField = 0; |
|
48 jfieldID AndroidGeckoEvent::jEndField = 0; |
|
49 jfieldID AndroidGeckoEvent::jPointerIndexField = 0; |
|
50 jfieldID AndroidGeckoEvent::jRangeTypeField = 0; |
|
51 jfieldID AndroidGeckoEvent::jRangeStylesField = 0; |
|
52 jfieldID AndroidGeckoEvent::jRangeLineStyleField = 0; |
|
53 jfieldID AndroidGeckoEvent::jRangeBoldLineField = 0; |
|
54 jfieldID AndroidGeckoEvent::jRangeForeColorField = 0; |
|
55 jfieldID AndroidGeckoEvent::jRangeBackColorField = 0; |
|
56 jfieldID AndroidGeckoEvent::jRangeLineColorField = 0; |
|
57 jfieldID AndroidGeckoEvent::jLocationField = 0; |
|
58 jfieldID AndroidGeckoEvent::jConnectionTypeField = 0; |
|
59 jfieldID AndroidGeckoEvent::jIsWifiField = 0; |
|
60 jfieldID AndroidGeckoEvent::jDHCPGatewayField = 0; |
|
61 jfieldID AndroidGeckoEvent::jScreenOrientationField = 0; |
|
62 jfieldID AndroidGeckoEvent::jByteBufferField = 0; |
|
63 jfieldID AndroidGeckoEvent::jWidthField = 0; |
|
64 jfieldID AndroidGeckoEvent::jHeightField = 0; |
|
65 jfieldID AndroidGeckoEvent::jPrefNamesField = 0; |
|
66 |
|
67 jclass AndroidGeckoEvent::jDomKeyLocationClass = 0; |
|
68 jfieldID AndroidGeckoEvent::jDomKeyLocationValueField = 0; |
|
69 |
|
70 jclass AndroidPoint::jPointClass = 0; |
|
71 jfieldID AndroidPoint::jXField = 0; |
|
72 jfieldID AndroidPoint::jYField = 0; |
|
73 |
|
74 jclass AndroidRect::jRectClass = 0; |
|
75 jfieldID AndroidRect::jBottomField = 0; |
|
76 jfieldID AndroidRect::jLeftField = 0; |
|
77 jfieldID AndroidRect::jRightField = 0; |
|
78 jfieldID AndroidRect::jTopField = 0; |
|
79 |
|
80 jclass AndroidRectF::jRectClass = 0; |
|
81 jfieldID AndroidRectF::jBottomField = 0; |
|
82 jfieldID AndroidRectF::jLeftField = 0; |
|
83 jfieldID AndroidRectF::jRightField = 0; |
|
84 jfieldID AndroidRectF::jTopField = 0; |
|
85 |
|
86 jclass AndroidLocation::jLocationClass = 0; |
|
87 jmethodID AndroidLocation::jGetLatitudeMethod = 0; |
|
88 jmethodID AndroidLocation::jGetLongitudeMethod = 0; |
|
89 jmethodID AndroidLocation::jGetAltitudeMethod = 0; |
|
90 jmethodID AndroidLocation::jGetAccuracyMethod = 0; |
|
91 jmethodID AndroidLocation::jGetBearingMethod = 0; |
|
92 jmethodID AndroidLocation::jGetSpeedMethod = 0; |
|
93 jmethodID AndroidLocation::jGetTimeMethod = 0; |
|
94 |
|
95 jclass AndroidLayerRendererFrame::jLayerRendererFrameClass = 0; |
|
96 jmethodID AndroidLayerRendererFrame::jBeginDrawingMethod = 0; |
|
97 jmethodID AndroidLayerRendererFrame::jDrawBackgroundMethod = 0; |
|
98 jmethodID AndroidLayerRendererFrame::jDrawForegroundMethod = 0; |
|
99 jmethodID AndroidLayerRendererFrame::jEndDrawingMethod = 0; |
|
100 |
|
101 RefCountedJavaObject::~RefCountedJavaObject() { |
|
102 if (mObject) |
|
103 GetJNIForThread()->DeleteGlobalRef(mObject); |
|
104 mObject = nullptr; |
|
105 } |
|
106 |
|
107 void |
|
108 mozilla::InitAndroidJavaWrappers(JNIEnv *jEnv) |
|
109 { |
|
110 AndroidGeckoEvent::InitGeckoEventClass(jEnv); |
|
111 AndroidPoint::InitPointClass(jEnv); |
|
112 AndroidLocation::InitLocationClass(jEnv); |
|
113 AndroidRect::InitRectClass(jEnv); |
|
114 AndroidRectF::InitRectFClass(jEnv); |
|
115 AndroidLayerRendererFrame::InitLayerRendererFrameClass(jEnv); |
|
116 InitStubs(jEnv); |
|
117 } |
|
118 |
|
119 void |
|
120 AndroidGeckoEvent::InitGeckoEventClass(JNIEnv *jEnv) |
|
121 { |
|
122 initInit(); |
|
123 |
|
124 jGeckoEventClass = getClassGlobalRef("org/mozilla/gecko/GeckoEvent"); |
|
125 |
|
126 jActionField = getField("mAction", "I"); |
|
127 jTypeField = getField("mType", "I"); |
|
128 jAckNeededField = getField("mAckNeeded", "Z"); |
|
129 jTimeField = getField("mTime", "J"); |
|
130 jPoints = getField("mPoints", "[Landroid/graphics/Point;"); |
|
131 jPointIndicies = getField("mPointIndicies", "[I"); |
|
132 jOrientations = getField("mOrientations", "[F"); |
|
133 jPressures = getField("mPressures", "[F"); |
|
134 jPointRadii = getField("mPointRadii", "[Landroid/graphics/Point;"); |
|
135 jXField = getField("mX", "D"); |
|
136 jYField = getField("mY", "D"); |
|
137 jZField = getField("mZ", "D"); |
|
138 jRectField = getField("mRect", "Landroid/graphics/Rect;"); |
|
139 |
|
140 jCharactersField = getField("mCharacters", "Ljava/lang/String;"); |
|
141 jCharactersExtraField = getField("mCharactersExtra", "Ljava/lang/String;"); |
|
142 jDataField = getField("mData", "Ljava/lang/String;"); |
|
143 jKeyCodeField = getField("mKeyCode", "I"); |
|
144 jMetaStateField = getField("mMetaState", "I"); |
|
145 jDomKeyLocationField = getField("mDomKeyLocation", "Lorg/mozilla/gecko/GeckoEvent$DomKeyLocation;"); |
|
146 jFlagsField = getField("mFlags", "I"); |
|
147 jUnicodeCharField = getField("mUnicodeChar", "I"); |
|
148 jBaseUnicodeCharField = getField("mBaseUnicodeChar", "I"); |
|
149 jDOMPrintableKeyValueField = getField("mDOMPrintableKeyValue", "I"); |
|
150 jRepeatCountField = getField("mRepeatCount", "I"); |
|
151 jCountField = getField("mCount", "I"); |
|
152 jStartField = getField("mStart", "I"); |
|
153 jEndField = getField("mEnd", "I"); |
|
154 jPointerIndexField = getField("mPointerIndex", "I"); |
|
155 jRangeTypeField = getField("mRangeType", "I"); |
|
156 jRangeStylesField = getField("mRangeStyles", "I"); |
|
157 jRangeLineStyleField = getField("mRangeLineStyle", "I"); |
|
158 jRangeBoldLineField = getField("mRangeBoldLine", "Z"); |
|
159 jRangeForeColorField = getField("mRangeForeColor", "I"); |
|
160 jRangeBackColorField = getField("mRangeBackColor", "I"); |
|
161 jRangeLineColorField = getField("mRangeLineColor", "I"); |
|
162 jLocationField = getField("mLocation", "Landroid/location/Location;"); |
|
163 jConnectionTypeField = getField("mConnectionType", "I"); |
|
164 jIsWifiField = getField("mIsWifi", "Z"); |
|
165 jDHCPGatewayField = getField("mDHCPGateway", "I"); |
|
166 jScreenOrientationField = getField("mScreenOrientation", "S"); |
|
167 jByteBufferField = getField("mBuffer", "Ljava/nio/ByteBuffer;"); |
|
168 jWidthField = getField("mWidth", "I"); |
|
169 jHeightField = getField("mHeight", "I"); |
|
170 jPrefNamesField = getField("mPrefNames", "[Ljava/lang/String;"); |
|
171 |
|
172 // Init GeckoEvent.DomKeyLocation enum |
|
173 jDomKeyLocationClass = getClassGlobalRef("org/mozilla/gecko/GeckoEvent$DomKeyLocation"); |
|
174 jDomKeyLocationValueField = getField("value", "I"); |
|
175 } |
|
176 |
|
177 void |
|
178 AndroidLocation::InitLocationClass(JNIEnv *jEnv) |
|
179 { |
|
180 initInit(); |
|
181 |
|
182 jLocationClass = getClassGlobalRef("android/location/Location"); |
|
183 jGetLatitudeMethod = getMethod("getLatitude", "()D"); |
|
184 jGetLongitudeMethod = getMethod("getLongitude", "()D"); |
|
185 jGetAltitudeMethod = getMethod("getAltitude", "()D"); |
|
186 jGetAccuracyMethod = getMethod("getAccuracy", "()F"); |
|
187 jGetBearingMethod = getMethod("getBearing", "()F"); |
|
188 jGetSpeedMethod = getMethod("getSpeed", "()F"); |
|
189 jGetTimeMethod = getMethod("getTime", "()J"); |
|
190 } |
|
191 |
|
192 nsGeoPosition* |
|
193 AndroidLocation::CreateGeoPosition(JNIEnv *jenv, jobject jobj) |
|
194 { |
|
195 AutoLocalJNIFrame jniFrame(jenv); |
|
196 |
|
197 double latitude = jenv->CallDoubleMethod(jobj, jGetLatitudeMethod); |
|
198 if (jniFrame.CheckForException()) return nullptr; |
|
199 double longitude = jenv->CallDoubleMethod(jobj, jGetLongitudeMethod); |
|
200 if (jniFrame.CheckForException()) return nullptr; |
|
201 double altitude = jenv->CallDoubleMethod(jobj, jGetAltitudeMethod); |
|
202 if (jniFrame.CheckForException()) return nullptr; |
|
203 float accuracy = jenv->CallFloatMethod (jobj, jGetAccuracyMethod); |
|
204 if (jniFrame.CheckForException()) return nullptr; |
|
205 float bearing = jenv->CallFloatMethod (jobj, jGetBearingMethod); |
|
206 if (jniFrame.CheckForException()) return nullptr; |
|
207 float speed = jenv->CallFloatMethod (jobj, jGetSpeedMethod); |
|
208 if (jniFrame.CheckForException()) return nullptr; |
|
209 long long time = jenv->CallLongMethod (jobj, jGetTimeMethod); |
|
210 if (jniFrame.CheckForException()) return nullptr; |
|
211 |
|
212 return new nsGeoPosition(latitude, longitude, |
|
213 altitude, accuracy, |
|
214 accuracy, bearing, |
|
215 speed, time); |
|
216 } |
|
217 |
|
218 void |
|
219 AndroidPoint::InitPointClass(JNIEnv *jEnv) |
|
220 { |
|
221 initInit(); |
|
222 |
|
223 jPointClass = getClassGlobalRef("android/graphics/Point"); |
|
224 |
|
225 jXField = getField("x", "I"); |
|
226 jYField = getField("y", "I"); |
|
227 } |
|
228 |
|
229 void |
|
230 AndroidRect::InitRectClass(JNIEnv *jEnv) |
|
231 { |
|
232 initInit(); |
|
233 |
|
234 jRectClass = getClassGlobalRef("android/graphics/Rect"); |
|
235 |
|
236 jBottomField = getField("bottom", "I"); |
|
237 jLeftField = getField("left", "I"); |
|
238 jTopField = getField("top", "I"); |
|
239 jRightField = getField("right", "I"); |
|
240 } |
|
241 |
|
242 void |
|
243 AndroidRectF::InitRectFClass(JNIEnv *jEnv) |
|
244 { |
|
245 initInit(); |
|
246 |
|
247 jRectClass = getClassGlobalRef("android/graphics/RectF"); |
|
248 |
|
249 jBottomField = getField("bottom", "F"); |
|
250 jLeftField = getField("left", "F"); |
|
251 jTopField = getField("top", "F"); |
|
252 jRightField = getField("right", "F"); |
|
253 } |
|
254 |
|
255 void |
|
256 AndroidLayerRendererFrame::InitLayerRendererFrameClass(JNIEnv *jEnv) |
|
257 { |
|
258 initInit(); |
|
259 |
|
260 jLayerRendererFrameClass = getClassGlobalRef("org/mozilla/gecko/gfx/LayerRenderer$Frame"); |
|
261 |
|
262 jBeginDrawingMethod = getMethod("beginDrawing", "()V"); |
|
263 jDrawBackgroundMethod = getMethod("drawBackground", "()V"); |
|
264 jDrawForegroundMethod = getMethod("drawForeground", "()V"); |
|
265 jEndDrawingMethod = getMethod("endDrawing", "()V"); |
|
266 } |
|
267 |
|
268 #undef initInit |
|
269 #undef initClassGlobalRef |
|
270 #undef getField |
|
271 #undef getMethod |
|
272 |
|
273 void |
|
274 AndroidGeckoEvent::ReadPointArray(nsTArray<nsIntPoint> &points, |
|
275 JNIEnv *jenv, |
|
276 jfieldID field, |
|
277 int32_t count) |
|
278 { |
|
279 jobjectArray jObjArray = (jobjectArray)jenv->GetObjectField(wrapped_obj, field); |
|
280 for (int32_t i = 0; i < count; i++) { |
|
281 jobject jObj = jenv->GetObjectArrayElement(jObjArray, i); |
|
282 AndroidPoint jpoint(jenv, jObj); |
|
283 |
|
284 nsIntPoint p(jpoint.X(), jpoint.Y()); |
|
285 points.AppendElement(p); |
|
286 } |
|
287 } |
|
288 |
|
289 void |
|
290 AndroidGeckoEvent::ReadIntArray(nsTArray<int> &aVals, |
|
291 JNIEnv *jenv, |
|
292 jfieldID field, |
|
293 int32_t count) |
|
294 { |
|
295 jintArray jIntArray = (jintArray)jenv->GetObjectField(wrapped_obj, field); |
|
296 jint *vals = jenv->GetIntArrayElements(jIntArray, nullptr); |
|
297 for (int32_t i = 0; i < count; i++) { |
|
298 aVals.AppendElement(vals[i]); |
|
299 } |
|
300 jenv->ReleaseIntArrayElements(jIntArray, vals, JNI_ABORT); |
|
301 } |
|
302 |
|
303 void |
|
304 AndroidGeckoEvent::ReadFloatArray(nsTArray<float> &aVals, |
|
305 JNIEnv *jenv, |
|
306 jfieldID field, |
|
307 int32_t count) |
|
308 { |
|
309 jfloatArray jFloatArray = (jfloatArray)jenv->GetObjectField(wrapped_obj, field); |
|
310 jfloat *vals = jenv->GetFloatArrayElements(jFloatArray, nullptr); |
|
311 for (int32_t i = 0; i < count; i++) { |
|
312 aVals.AppendElement(vals[i]); |
|
313 } |
|
314 jenv->ReleaseFloatArrayElements(jFloatArray, vals, JNI_ABORT); |
|
315 } |
|
316 |
|
317 void |
|
318 AndroidGeckoEvent::ReadStringArray(nsTArray<nsString> &array, |
|
319 JNIEnv *jenv, |
|
320 jfieldID field) |
|
321 { |
|
322 jarray jArray = (jarray)jenv->GetObjectField(wrapped_obj, field); |
|
323 jsize length = jenv->GetArrayLength(jArray); |
|
324 jobjectArray jStringArray = (jobjectArray)jArray; |
|
325 nsString *strings = array.AppendElements(length); |
|
326 for (jsize i = 0; i < length; ++i) { |
|
327 jstring javastring = (jstring) jenv->GetObjectArrayElement(jStringArray, i); |
|
328 ReadStringFromJString(strings[i], jenv, javastring); |
|
329 } |
|
330 } |
|
331 |
|
332 void |
|
333 AndroidGeckoEvent::ReadRectField(JNIEnv *jenv) |
|
334 { |
|
335 AndroidRect r(jenv, jenv->GetObjectField(wrappedObject(), jRectField)); |
|
336 if (!r.isNull()) { |
|
337 mRect.SetRect(r.Left(), |
|
338 r.Top(), |
|
339 r.Width(), |
|
340 r.Height()); |
|
341 } else { |
|
342 mRect.SetEmpty(); |
|
343 } |
|
344 } |
|
345 |
|
346 void |
|
347 AndroidGeckoEvent::ReadStringFromJString(nsString &aString, JNIEnv *jenv, |
|
348 jstring s) |
|
349 { |
|
350 if (!s) { |
|
351 aString.SetIsVoid(true); |
|
352 return; |
|
353 } |
|
354 |
|
355 int len = jenv->GetStringLength(s); |
|
356 aString.SetLength(len); |
|
357 jenv->GetStringRegion(s, 0, len, reinterpret_cast<jchar*>(aString.BeginWriting())); |
|
358 } |
|
359 |
|
360 void |
|
361 AndroidGeckoEvent::ReadCharactersField(JNIEnv *jenv) |
|
362 { |
|
363 jstring s = (jstring) jenv->GetObjectField(wrapped_obj, jCharactersField); |
|
364 ReadStringFromJString(mCharacters, jenv, s); |
|
365 } |
|
366 |
|
367 void |
|
368 AndroidGeckoEvent::ReadCharactersExtraField(JNIEnv *jenv) |
|
369 { |
|
370 jstring s = (jstring) jenv->GetObjectField(wrapped_obj, jCharactersExtraField); |
|
371 ReadStringFromJString(mCharactersExtra, jenv, s); |
|
372 } |
|
373 |
|
374 void |
|
375 AndroidGeckoEvent::ReadDataField(JNIEnv *jenv) |
|
376 { |
|
377 jstring s = (jstring) jenv->GetObjectField(wrapped_obj, jDataField); |
|
378 ReadStringFromJString(mData, jenv, s); |
|
379 } |
|
380 |
|
381 void |
|
382 AndroidGeckoEvent::UnionRect(nsIntRect const& aRect) |
|
383 { |
|
384 mRect = aRect.Union(mRect); |
|
385 } |
|
386 |
|
387 uint32_t |
|
388 AndroidGeckoEvent::ReadDomKeyLocation(JNIEnv* jenv, jobject jGeckoEventObj) |
|
389 { |
|
390 jobject enumObject = jenv->GetObjectField(jGeckoEventObj, |
|
391 jDomKeyLocationField); |
|
392 MOZ_ASSERT(enumObject); |
|
393 int enumValue = jenv->GetIntField(enumObject, jDomKeyLocationValueField); |
|
394 MOZ_ASSERT(enumValue >= nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD && |
|
395 enumValue <= nsIDOMKeyEvent::DOM_KEY_LOCATION_JOYSTICK); |
|
396 return static_cast<uint32_t>(enumValue); |
|
397 } |
|
398 |
|
399 void |
|
400 AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj) |
|
401 { |
|
402 NS_ASSERTION(!wrapped_obj, "Init called on non-null wrapped_obj!"); |
|
403 |
|
404 wrapped_obj = jobj; |
|
405 |
|
406 if (!jobj) |
|
407 return; |
|
408 |
|
409 mAction = jenv->GetIntField(jobj, jActionField); |
|
410 mType = jenv->GetIntField(jobj, jTypeField); |
|
411 mAckNeeded = jenv->GetBooleanField(jobj, jAckNeededField); |
|
412 |
|
413 switch (mType) { |
|
414 case SIZE_CHANGED: |
|
415 ReadPointArray(mPoints, jenv, jPoints, 2); |
|
416 break; |
|
417 |
|
418 case KEY_EVENT: |
|
419 case IME_KEY_EVENT: |
|
420 mTime = jenv->GetLongField(jobj, jTimeField); |
|
421 mMetaState = jenv->GetIntField(jobj, jMetaStateField); |
|
422 mDomKeyLocation = ReadDomKeyLocation(jenv, jobj); |
|
423 mFlags = jenv->GetIntField(jobj, jFlagsField); |
|
424 mKeyCode = jenv->GetIntField(jobj, jKeyCodeField); |
|
425 mUnicodeChar = jenv->GetIntField(jobj, jUnicodeCharField); |
|
426 mBaseUnicodeChar = jenv->GetIntField(jobj, jBaseUnicodeCharField); |
|
427 mDOMPrintableKeyValue = |
|
428 jenv->GetIntField(jobj, jDOMPrintableKeyValueField); |
|
429 mRepeatCount = jenv->GetIntField(jobj, jRepeatCountField); |
|
430 ReadCharactersField(jenv); |
|
431 break; |
|
432 |
|
433 case NATIVE_GESTURE_EVENT: |
|
434 mTime = jenv->GetLongField(jobj, jTimeField); |
|
435 mMetaState = jenv->GetIntField(jobj, jMetaStateField); |
|
436 mCount = jenv->GetIntField(jobj, jCountField); |
|
437 ReadPointArray(mPoints, jenv, jPoints, mCount); |
|
438 mX = jenv->GetDoubleField(jobj, jXField); |
|
439 |
|
440 break; |
|
441 |
|
442 case MOTION_EVENT: |
|
443 mTime = jenv->GetLongField(jobj, jTimeField); |
|
444 mMetaState = jenv->GetIntField(jobj, jMetaStateField); |
|
445 mCount = jenv->GetIntField(jobj, jCountField); |
|
446 mPointerIndex = jenv->GetIntField(jobj, jPointerIndexField); |
|
447 |
|
448 ReadPointArray(mPointRadii, jenv, jPointRadii, mCount); |
|
449 ReadFloatArray(mOrientations, jenv, jOrientations, mCount); |
|
450 ReadFloatArray(mPressures, jenv, jPressures, mCount); |
|
451 ReadPointArray(mPoints, jenv, jPoints, mCount); |
|
452 ReadIntArray(mPointIndicies, jenv, jPointIndicies, mCount); |
|
453 |
|
454 break; |
|
455 |
|
456 case IME_EVENT: |
|
457 mStart = jenv->GetIntField(jobj, jStartField); |
|
458 mEnd = jenv->GetIntField(jobj, jEndField); |
|
459 |
|
460 if (mAction == IME_REPLACE_TEXT) { |
|
461 ReadCharactersField(jenv); |
|
462 } else if (mAction == IME_UPDATE_COMPOSITION || |
|
463 mAction == IME_ADD_COMPOSITION_RANGE) { |
|
464 mRangeType = jenv->GetIntField(jobj, jRangeTypeField); |
|
465 mRangeStyles = jenv->GetIntField(jobj, jRangeStylesField); |
|
466 mRangeLineStyle = |
|
467 jenv->GetIntField(jobj, jRangeLineStyleField); |
|
468 mRangeBoldLine = |
|
469 jenv->GetBooleanField(jobj, jRangeBoldLineField); |
|
470 mRangeForeColor = |
|
471 jenv->GetIntField(jobj, jRangeForeColorField); |
|
472 mRangeBackColor = |
|
473 jenv->GetIntField(jobj, jRangeBackColorField); |
|
474 mRangeLineColor = |
|
475 jenv->GetIntField(jobj, jRangeLineColorField); |
|
476 } |
|
477 break; |
|
478 |
|
479 case DRAW: |
|
480 ReadRectField(jenv); |
|
481 break; |
|
482 |
|
483 case SENSOR_EVENT: |
|
484 mX = jenv->GetDoubleField(jobj, jXField); |
|
485 mY = jenv->GetDoubleField(jobj, jYField); |
|
486 mZ = jenv->GetDoubleField(jobj, jZField); |
|
487 mFlags = jenv->GetIntField(jobj, jFlagsField); |
|
488 mMetaState = jenv->GetIntField(jobj, jMetaStateField); |
|
489 break; |
|
490 |
|
491 case LOCATION_EVENT: { |
|
492 jobject location = jenv->GetObjectField(jobj, jLocationField); |
|
493 mGeoPosition = AndroidLocation::CreateGeoPosition(jenv, location); |
|
494 break; |
|
495 } |
|
496 |
|
497 case LOAD_URI: { |
|
498 ReadCharactersField(jenv); |
|
499 ReadCharactersExtraField(jenv); |
|
500 break; |
|
501 } |
|
502 |
|
503 case VIEWPORT: |
|
504 case BROADCAST: { |
|
505 ReadCharactersField(jenv); |
|
506 ReadCharactersExtraField(jenv); |
|
507 break; |
|
508 } |
|
509 |
|
510 case NETWORK_CHANGED: { |
|
511 mConnectionType = jenv->GetIntField(jobj, jConnectionTypeField); |
|
512 mIsWifi = jenv->GetBooleanField(jobj, jIsWifiField); |
|
513 mDHCPGateway = jenv->GetIntField(jobj, jDHCPGatewayField); |
|
514 break; |
|
515 } |
|
516 |
|
517 case VISITED: { |
|
518 ReadCharactersField(jenv); |
|
519 break; |
|
520 } |
|
521 |
|
522 case THUMBNAIL: { |
|
523 mMetaState = jenv->GetIntField(jobj, jMetaStateField); |
|
524 ReadPointArray(mPoints, jenv, jPoints, 1); |
|
525 mByteBuffer = new RefCountedJavaObject(jenv, jenv->GetObjectField(jobj, jByteBufferField)); |
|
526 break; |
|
527 } |
|
528 |
|
529 case SCREENORIENTATION_CHANGED: { |
|
530 mScreenOrientation = jenv->GetShortField(jobj, jScreenOrientationField); |
|
531 break; |
|
532 } |
|
533 |
|
534 case COMPOSITOR_CREATE: { |
|
535 mWidth = jenv->GetIntField(jobj, jWidthField); |
|
536 mHeight = jenv->GetIntField(jobj, jHeightField); |
|
537 break; |
|
538 } |
|
539 |
|
540 case CALL_OBSERVER: { |
|
541 ReadCharactersField(jenv); |
|
542 ReadCharactersExtraField(jenv); |
|
543 ReadDataField(jenv); |
|
544 break; |
|
545 } |
|
546 |
|
547 case REMOVE_OBSERVER: { |
|
548 ReadCharactersField(jenv); |
|
549 break; |
|
550 } |
|
551 |
|
552 case LOW_MEMORY: { |
|
553 mMetaState = jenv->GetIntField(jobj, jMetaStateField); |
|
554 break; |
|
555 } |
|
556 |
|
557 case NETWORK_LINK_CHANGE: { |
|
558 ReadCharactersField(jenv); |
|
559 break; |
|
560 } |
|
561 |
|
562 case TELEMETRY_HISTOGRAM_ADD: { |
|
563 ReadCharactersField(jenv); |
|
564 mCount = jenv->GetIntField(jobj, jCountField); |
|
565 break; |
|
566 } |
|
567 |
|
568 case TELEMETRY_UI_SESSION_START: { |
|
569 ReadCharactersField(jenv); |
|
570 mTime = jenv->GetLongField(jobj, jTimeField); |
|
571 break; |
|
572 } |
|
573 |
|
574 case TELEMETRY_UI_SESSION_STOP: { |
|
575 ReadCharactersField(jenv); |
|
576 ReadCharactersExtraField(jenv); |
|
577 mTime = jenv->GetLongField(jobj, jTimeField); |
|
578 break; |
|
579 } |
|
580 |
|
581 case TELEMETRY_UI_EVENT: { |
|
582 ReadCharactersField(jenv); |
|
583 ReadCharactersExtraField(jenv); |
|
584 ReadDataField(jenv); |
|
585 mTime = jenv->GetLongField(jobj, jTimeField); |
|
586 break; |
|
587 } |
|
588 |
|
589 case PREFERENCES_OBSERVE: |
|
590 case PREFERENCES_GET: { |
|
591 ReadStringArray(mPrefNames, jenv, jPrefNamesField); |
|
592 mCount = jenv->GetIntField(jobj, jCountField); |
|
593 break; |
|
594 } |
|
595 |
|
596 case PREFERENCES_REMOVE_OBSERVERS: { |
|
597 mCount = jenv->GetIntField(jobj, jCountField); |
|
598 break; |
|
599 } |
|
600 |
|
601 default: |
|
602 break; |
|
603 } |
|
604 |
|
605 #ifdef DEBUG_ANDROID_EVENTS |
|
606 ALOG("AndroidGeckoEvent: %p : %d", (void*)jobj, mType); |
|
607 #endif |
|
608 } |
|
609 |
|
610 void |
|
611 AndroidGeckoEvent::Init(int aType) |
|
612 { |
|
613 mType = aType; |
|
614 mAckNeeded = false; |
|
615 } |
|
616 |
|
617 void |
|
618 AndroidGeckoEvent::Init(AndroidGeckoEvent *aResizeEvent) |
|
619 { |
|
620 NS_ASSERTION(aResizeEvent->Type() == SIZE_CHANGED, "Init called on non-SIZE_CHANGED event"); |
|
621 |
|
622 mType = FORCED_RESIZE; |
|
623 mAckNeeded = false; |
|
624 mTime = aResizeEvent->mTime; |
|
625 mPoints = aResizeEvent->mPoints; // x,y coordinates |
|
626 } |
|
627 |
|
628 WidgetTouchEvent |
|
629 AndroidGeckoEvent::MakeTouchEvent(nsIWidget* widget) |
|
630 { |
|
631 int type = NS_EVENT_NULL; |
|
632 int startIndex = 0; |
|
633 int endIndex = Count(); |
|
634 |
|
635 switch (Action()) { |
|
636 case AndroidMotionEvent::ACTION_DOWN: |
|
637 case AndroidMotionEvent::ACTION_POINTER_DOWN: { |
|
638 type = NS_TOUCH_START; |
|
639 break; |
|
640 } |
|
641 case AndroidMotionEvent::ACTION_MOVE: { |
|
642 type = NS_TOUCH_MOVE; |
|
643 break; |
|
644 } |
|
645 case AndroidMotionEvent::ACTION_UP: |
|
646 case AndroidMotionEvent::ACTION_POINTER_UP: { |
|
647 type = NS_TOUCH_END; |
|
648 // for pointer-up events we only want the data from |
|
649 // the one pointer that went up |
|
650 startIndex = PointerIndex(); |
|
651 endIndex = startIndex + 1; |
|
652 break; |
|
653 } |
|
654 case AndroidMotionEvent::ACTION_OUTSIDE: |
|
655 case AndroidMotionEvent::ACTION_CANCEL: { |
|
656 type = NS_TOUCH_CANCEL; |
|
657 break; |
|
658 } |
|
659 } |
|
660 |
|
661 WidgetTouchEvent event(true, type, widget); |
|
662 if (type == NS_EVENT_NULL) { |
|
663 // An event we don't know about |
|
664 return event; |
|
665 } |
|
666 |
|
667 event.modifiers = DOMModifiers(); |
|
668 event.time = Time(); |
|
669 |
|
670 const nsIntPoint& offset = widget->WidgetToScreenOffset(); |
|
671 event.touches.SetCapacity(endIndex - startIndex); |
|
672 for (int i = startIndex; i < endIndex; i++) { |
|
673 // In this code branch, we are dispatching this event directly |
|
674 // into Gecko (as opposed to going through the AsyncPanZoomController), |
|
675 // and the Points() array has points in CSS pixels, which we need |
|
676 // to convert. |
|
677 CSSToLayoutDeviceScale scale = widget->GetDefaultScale(); |
|
678 nsIntPoint pt( |
|
679 (Points()[i].x * scale.scale) - offset.x, |
|
680 (Points()[i].y * scale.scale) - offset.y); |
|
681 nsIntPoint radii( |
|
682 PointRadii()[i].x * scale.scale, |
|
683 PointRadii()[i].y * scale.scale); |
|
684 nsRefPtr<Touch> t = new Touch(PointIndicies()[i], |
|
685 pt, |
|
686 radii, |
|
687 Orientations()[i], |
|
688 Pressures()[i]); |
|
689 event.touches.AppendElement(t); |
|
690 } |
|
691 |
|
692 return event; |
|
693 } |
|
694 |
|
695 MultiTouchInput |
|
696 AndroidGeckoEvent::MakeMultiTouchInput(nsIWidget* widget) |
|
697 { |
|
698 MultiTouchInput::MultiTouchType type = (MultiTouchInput::MultiTouchType)-1; |
|
699 int startIndex = 0; |
|
700 int endIndex = Count(); |
|
701 |
|
702 switch (Action()) { |
|
703 case AndroidMotionEvent::ACTION_DOWN: |
|
704 case AndroidMotionEvent::ACTION_POINTER_DOWN: { |
|
705 type = MultiTouchInput::MULTITOUCH_START; |
|
706 break; |
|
707 } |
|
708 case AndroidMotionEvent::ACTION_MOVE: { |
|
709 type = MultiTouchInput::MULTITOUCH_MOVE; |
|
710 break; |
|
711 } |
|
712 case AndroidMotionEvent::ACTION_UP: |
|
713 case AndroidMotionEvent::ACTION_POINTER_UP: { |
|
714 // for pointer-up events we only want the data from |
|
715 // the one pointer that went up |
|
716 startIndex = PointerIndex(); |
|
717 endIndex = startIndex + 1; |
|
718 type = MultiTouchInput::MULTITOUCH_END; |
|
719 break; |
|
720 } |
|
721 case AndroidMotionEvent::ACTION_OUTSIDE: |
|
722 case AndroidMotionEvent::ACTION_CANCEL: { |
|
723 type = MultiTouchInput::MULTITOUCH_CANCEL; |
|
724 break; |
|
725 } |
|
726 } |
|
727 |
|
728 MultiTouchInput event(type, Time(), 0); |
|
729 event.modifiers = DOMModifiers(); |
|
730 |
|
731 if (type < 0) { |
|
732 // An event we don't know about |
|
733 return event; |
|
734 } |
|
735 |
|
736 const nsIntPoint& offset = widget->WidgetToScreenOffset(); |
|
737 event.mTouches.SetCapacity(endIndex - startIndex); |
|
738 for (int i = startIndex; i < endIndex; i++) { |
|
739 nsIntPoint point = Points()[i] - offset; |
|
740 nsIntPoint radius = PointRadii()[i]; |
|
741 SingleTouchData data(PointIndicies()[i], |
|
742 ScreenIntPoint::FromUnknownPoint( |
|
743 gfx::IntPoint(point.x, point.y)), |
|
744 ScreenSize::FromUnknownSize( |
|
745 gfx::Size(radius.x, radius.y)), |
|
746 Orientations()[i], |
|
747 Pressures()[i]); |
|
748 event.mTouches.AppendElement(data); |
|
749 } |
|
750 |
|
751 return event; |
|
752 } |
|
753 |
|
754 WidgetMouseEvent |
|
755 AndroidGeckoEvent::MakeMouseEvent(nsIWidget* widget) |
|
756 { |
|
757 uint32_t msg = NS_EVENT_NULL; |
|
758 if (Points().Length() > 0) { |
|
759 switch (Action()) { |
|
760 case AndroidMotionEvent::ACTION_HOVER_MOVE: |
|
761 msg = NS_MOUSE_MOVE; |
|
762 break; |
|
763 case AndroidMotionEvent::ACTION_HOVER_ENTER: |
|
764 msg = NS_MOUSEENTER; |
|
765 break; |
|
766 case AndroidMotionEvent::ACTION_HOVER_EXIT: |
|
767 msg = NS_MOUSELEAVE; |
|
768 break; |
|
769 default: |
|
770 break; |
|
771 } |
|
772 } |
|
773 |
|
774 WidgetMouseEvent event(true, msg, widget, |
|
775 WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal); |
|
776 |
|
777 if (msg == NS_EVENT_NULL) { |
|
778 // unknown type, or no point data. abort |
|
779 return event; |
|
780 } |
|
781 |
|
782 // XXX can we synthesize different buttons? |
|
783 event.button = WidgetMouseEvent::eLeftButton; |
|
784 if (msg != NS_MOUSE_MOVE) { |
|
785 event.clickCount = 1; |
|
786 } |
|
787 event.modifiers = DOMModifiers(); |
|
788 event.time = Time(); |
|
789 |
|
790 // We are dispatching this event directly into Gecko (as opposed to going |
|
791 // through the AsyncPanZoomController), and the Points() array has points |
|
792 // in CSS pixels, which we need to convert to LayoutDevice pixels. |
|
793 const nsIntPoint& offset = widget->WidgetToScreenOffset(); |
|
794 CSSToLayoutDeviceScale scale = widget->GetDefaultScale(); |
|
795 event.refPoint = LayoutDeviceIntPoint((Points()[0].x * scale.scale) - offset.x, |
|
796 (Points()[0].y * scale.scale) - offset.y); |
|
797 |
|
798 return event; |
|
799 } |
|
800 |
|
801 Modifiers |
|
802 AndroidGeckoEvent::DOMModifiers() const |
|
803 { |
|
804 Modifiers result = 0; |
|
805 if (mMetaState & AMETA_ALT_MASK) { |
|
806 result |= MODIFIER_ALT; |
|
807 } |
|
808 if (mMetaState & AMETA_SHIFT_MASK) { |
|
809 result |= MODIFIER_SHIFT; |
|
810 } |
|
811 if (mMetaState & AMETA_CTRL_MASK) { |
|
812 result |= MODIFIER_CONTROL; |
|
813 } |
|
814 if (mMetaState & AMETA_META_MASK) { |
|
815 result |= MODIFIER_META; |
|
816 } |
|
817 if (mMetaState & AMETA_FUNCTION_ON) { |
|
818 result |= MODIFIER_FN; |
|
819 } |
|
820 if (mMetaState & AMETA_CAPS_LOCK_ON) { |
|
821 result |= MODIFIER_CAPSLOCK; |
|
822 } |
|
823 if (mMetaState & AMETA_NUM_LOCK_ON) { |
|
824 result |= MODIFIER_NUMLOCK; |
|
825 } |
|
826 if (mMetaState & AMETA_SCROLL_LOCK_ON) { |
|
827 result |= MODIFIER_SCROLLLOCK; |
|
828 } |
|
829 return result; |
|
830 } |
|
831 |
|
832 void |
|
833 AndroidPoint::Init(JNIEnv *jenv, jobject jobj) |
|
834 { |
|
835 if (jobj) { |
|
836 mX = jenv->GetIntField(jobj, jXField); |
|
837 mY = jenv->GetIntField(jobj, jYField); |
|
838 } else { |
|
839 mX = 0; |
|
840 mY = 0; |
|
841 } |
|
842 } |
|
843 |
|
844 void |
|
845 AndroidLayerRendererFrame::Init(JNIEnv *env, jobject jobj) |
|
846 { |
|
847 if (!isNull()) { |
|
848 Dispose(env); |
|
849 } |
|
850 |
|
851 wrapped_obj = env->NewGlobalRef(jobj); |
|
852 } |
|
853 |
|
854 void |
|
855 AndroidLayerRendererFrame::Dispose(JNIEnv *env) |
|
856 { |
|
857 if (isNull()) { |
|
858 return; |
|
859 } |
|
860 |
|
861 env->DeleteGlobalRef(wrapped_obj); |
|
862 wrapped_obj = 0; |
|
863 } |
|
864 |
|
865 NS_IMPL_ISUPPORTS(nsAndroidDisplayport, nsIAndroidDisplayport) |
|
866 |
|
867 bool |
|
868 AndroidLayerRendererFrame::BeginDrawing(AutoLocalJNIFrame *jniFrame) |
|
869 { |
|
870 if (!jniFrame || !jniFrame->GetEnv()) |
|
871 return false; |
|
872 |
|
873 jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jBeginDrawingMethod); |
|
874 if (jniFrame->CheckForException()) |
|
875 return false; |
|
876 |
|
877 return true; |
|
878 } |
|
879 |
|
880 bool |
|
881 AndroidLayerRendererFrame::DrawBackground(AutoLocalJNIFrame *jniFrame) |
|
882 { |
|
883 if (!jniFrame || !jniFrame->GetEnv()) |
|
884 return false; |
|
885 |
|
886 jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDrawBackgroundMethod); |
|
887 if (jniFrame->CheckForException()) |
|
888 return false; |
|
889 |
|
890 return true; |
|
891 } |
|
892 |
|
893 bool |
|
894 AndroidLayerRendererFrame::DrawForeground(AutoLocalJNIFrame *jniFrame) |
|
895 { |
|
896 if (!jniFrame || !jniFrame->GetEnv()) |
|
897 return false; |
|
898 |
|
899 jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDrawForegroundMethod); |
|
900 if (jniFrame->CheckForException()) |
|
901 return false; |
|
902 |
|
903 return true; |
|
904 } |
|
905 |
|
906 bool |
|
907 AndroidLayerRendererFrame::EndDrawing(AutoLocalJNIFrame *jniFrame) |
|
908 { |
|
909 if (!jniFrame || !jniFrame->GetEnv()) |
|
910 return false; |
|
911 |
|
912 jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jEndDrawingMethod); |
|
913 if (jniFrame->CheckForException()) |
|
914 return false; |
|
915 |
|
916 return true; |
|
917 } |
|
918 |
|
919 void |
|
920 AndroidRect::Init(JNIEnv *jenv, jobject jobj) |
|
921 { |
|
922 NS_ASSERTION(wrapped_obj == nullptr, "Init called on non-null wrapped_obj!"); |
|
923 |
|
924 wrapped_obj = jobj; |
|
925 |
|
926 if (jobj) { |
|
927 mTop = jenv->GetIntField(jobj, jTopField); |
|
928 mLeft = jenv->GetIntField(jobj, jLeftField); |
|
929 mRight = jenv->GetIntField(jobj, jRightField); |
|
930 mBottom = jenv->GetIntField(jobj, jBottomField); |
|
931 } else { |
|
932 mTop = 0; |
|
933 mLeft = 0; |
|
934 mRight = 0; |
|
935 mBottom = 0; |
|
936 } |
|
937 } |
|
938 |
|
939 void |
|
940 AndroidRectF::Init(JNIEnv *jenv, jobject jobj) |
|
941 { |
|
942 NS_ASSERTION(wrapped_obj == nullptr, "Init called on non-null wrapped_obj!"); |
|
943 |
|
944 wrapped_obj = jobj; |
|
945 |
|
946 if (jobj) { |
|
947 mTop = jenv->GetFloatField(jobj, jTopField); |
|
948 mLeft = jenv->GetFloatField(jobj, jLeftField); |
|
949 mRight = jenv->GetFloatField(jobj, jRightField); |
|
950 mBottom = jenv->GetFloatField(jobj, jBottomField); |
|
951 } else { |
|
952 mTop = 0; |
|
953 mLeft = 0; |
|
954 mRight = 0; |
|
955 mBottom = 0; |
|
956 } |
|
957 } |
|
958 |
|
959 nsJNIString::nsJNIString(jstring jstr, JNIEnv *jenv) |
|
960 { |
|
961 if (!jstr) { |
|
962 SetIsVoid(true); |
|
963 return; |
|
964 } |
|
965 JNIEnv *jni = jenv; |
|
966 if (!jni) { |
|
967 jni = AndroidBridge::GetJNIEnv(); |
|
968 } |
|
969 const jchar* jCharPtr = jni->GetStringChars(jstr, nullptr); |
|
970 |
|
971 if (!jCharPtr) { |
|
972 SetIsVoid(true); |
|
973 return; |
|
974 } |
|
975 |
|
976 jsize len = jni->GetStringLength(jstr); |
|
977 |
|
978 if (len <= 0) { |
|
979 SetIsVoid(true); |
|
980 } else { |
|
981 Assign(reinterpret_cast<const char16_t*>(jCharPtr), len); |
|
982 } |
|
983 jni->ReleaseStringChars(jstr, jCharPtr); |
|
984 } |