Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; 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 package org.mozilla.gecko;
8 import org.mozilla.gecko.gfx.DisplayPortMetrics;
9 import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
10 import org.mozilla.gecko.mozglue.JNITarget;
11 import org.mozilla.gecko.mozglue.generatorannotations.GeneratorOptions;
12 import org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI;
13 import org.mozilla.gecko.mozglue.RobocopTarget;
15 import android.content.res.Resources;
16 import android.graphics.Point;
17 import android.graphics.PointF;
18 import android.graphics.Rect;
19 import android.hardware.Sensor;
20 import android.hardware.SensorEvent;
21 import android.hardware.SensorManager;
22 import android.location.Address;
23 import android.location.Location;
24 import android.os.Build;
25 import android.os.SystemClock;
26 import android.util.DisplayMetrics;
27 import android.util.Log;
28 import android.util.SparseArray;
29 import android.view.KeyEvent;
30 import android.view.MotionEvent;
32 import java.nio.ByteBuffer;
33 import java.util.concurrent.ArrayBlockingQueue;
35 /* We're not allowed to hold on to most events given to us
36 * so we save the parts of the events we want to use in GeckoEvent.
37 * Fields have different meanings depending on the event type.
38 */
40 /* This class is referenced by Robocop via reflection; use care when
41 * modifying the signature.
42 */
43 @JNITarget
44 public class GeckoEvent {
45 private static final String LOGTAG = "GeckoEvent";
47 private static final int EVENT_FACTORY_SIZE = 5;
49 // Maybe we're probably better to just make mType non final, and just store GeckoEvents in here...
50 private static SparseArray<ArrayBlockingQueue<GeckoEvent>> mEvents = new SparseArray<ArrayBlockingQueue<GeckoEvent>>();
52 public static GeckoEvent get(NativeGeckoEvent type) {
53 synchronized (mEvents) {
54 ArrayBlockingQueue<GeckoEvent> events = mEvents.get(type.value);
55 if (events != null && events.size() > 0) {
56 return events.poll();
57 }
58 }
60 return new GeckoEvent(type);
61 }
63 public void recycle() {
64 synchronized (mEvents) {
65 ArrayBlockingQueue<GeckoEvent> events = mEvents.get(mType);
66 if (events == null) {
67 events = new ArrayBlockingQueue<GeckoEvent>(EVENT_FACTORY_SIZE);
68 mEvents.put(mType, events);
69 }
71 events.offer(this);
72 }
73 }
75 // Make sure to keep these values in sync with the enum in
76 // AndroidGeckoEvent in widget/android/AndroidJavaWrappers.h
77 @JNITarget
78 private enum NativeGeckoEvent {
79 NATIVE_POKE(0),
80 KEY_EVENT(1),
81 MOTION_EVENT(2),
82 SENSOR_EVENT(3),
83 LOCATION_EVENT(5),
84 IME_EVENT(6),
85 DRAW(7),
86 SIZE_CHANGED(8),
87 APP_BACKGROUNDING(9),
88 APP_FOREGROUNDING(10),
89 LOAD_URI(12),
90 NOOP(15),
91 BROADCAST(19),
92 VIEWPORT(20),
93 VISITED(21),
94 NETWORK_CHANGED(22),
95 THUMBNAIL(25),
96 SCREENORIENTATION_CHANGED(27),
97 COMPOSITOR_CREATE(28),
98 COMPOSITOR_PAUSE(29),
99 COMPOSITOR_RESUME(30),
100 NATIVE_GESTURE_EVENT(31),
101 IME_KEY_EVENT(32),
102 CALL_OBSERVER(33),
103 REMOVE_OBSERVER(34),
104 LOW_MEMORY(35),
105 NETWORK_LINK_CHANGE(36),
106 TELEMETRY_HISTOGRAM_ADD(37),
107 PREFERENCES_OBSERVE(39),
108 PREFERENCES_GET(40),
109 PREFERENCES_REMOVE_OBSERVERS(41),
110 TELEMETRY_UI_SESSION_START(42),
111 TELEMETRY_UI_SESSION_STOP(43),
112 TELEMETRY_UI_EVENT(44);
114 public final int value;
116 private NativeGeckoEvent(int value) {
117 this.value = value;
118 }
119 }
121 /**
122 * The DomKeyLocation enum encapsulates the DOM KeyboardEvent's constants.
123 * @see https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent#Key_location_constants
124 */
125 @GeneratorOptions(generatedClassName = "JavaDomKeyLocation")
126 @WrapEntireClassForJNI
127 public enum DomKeyLocation {
128 DOM_KEY_LOCATION_STANDARD(0),
129 DOM_KEY_LOCATION_LEFT(1),
130 DOM_KEY_LOCATION_RIGHT(2),
131 DOM_KEY_LOCATION_NUMPAD(3),
132 DOM_KEY_LOCATION_MOBILE(4),
133 DOM_KEY_LOCATION_JOYSTICK(5);
135 public final int value;
137 private DomKeyLocation(int value) {
138 this.value = value;
139 }
140 }
142 // Encapsulation of common IME actions.
143 @JNITarget
144 public enum ImeAction {
145 IME_SYNCHRONIZE(0),
146 IME_REPLACE_TEXT(1),
147 IME_SET_SELECTION(2),
148 IME_ADD_COMPOSITION_RANGE(3),
149 IME_UPDATE_COMPOSITION(4),
150 IME_REMOVE_COMPOSITION(5),
151 IME_ACKNOWLEDGE_FOCUS(6);
153 public final int value;
155 private ImeAction(int value) {
156 this.value = value;
157 }
158 }
160 public static final int IME_RANGE_CARETPOSITION = 1;
161 public static final int IME_RANGE_RAWINPUT = 2;
162 public static final int IME_RANGE_SELECTEDRAWTEXT = 3;
163 public static final int IME_RANGE_CONVERTEDTEXT = 4;
164 public static final int IME_RANGE_SELECTEDCONVERTEDTEXT = 5;
166 public static final int IME_RANGE_LINE_NONE = 0;
167 public static final int IME_RANGE_LINE_DOTTED = 1;
168 public static final int IME_RANGE_LINE_DASHED = 2;
169 public static final int IME_RANGE_LINE_SOLID = 3;
170 public static final int IME_RANGE_LINE_DOUBLE = 4;
171 public static final int IME_RANGE_LINE_WAVY = 5;
173 public static final int IME_RANGE_UNDERLINE = 1;
174 public static final int IME_RANGE_FORECOLOR = 2;
175 public static final int IME_RANGE_BACKCOLOR = 4;
176 public static final int IME_RANGE_LINECOLOR = 8;
178 public static final int ACTION_MAGNIFY_START = 11;
179 public static final int ACTION_MAGNIFY = 12;
180 public static final int ACTION_MAGNIFY_END = 13;
182 private final int mType;
183 private int mAction;
184 private boolean mAckNeeded;
185 private long mTime;
186 private Point[] mPoints;
187 private int[] mPointIndicies;
188 private int mPointerIndex; // index of the point that has changed
189 private float[] mOrientations;
190 private float[] mPressures;
191 private Point[] mPointRadii;
192 private Rect mRect;
193 private double mX;
194 private double mY;
195 private double mZ;
197 private int mMetaState;
198 private int mFlags;
199 private int mKeyCode;
200 private int mUnicodeChar;
201 private int mBaseUnicodeChar; // mUnicodeChar without meta states applied
202 private int mDOMPrintableKeyValue;
203 private int mRepeatCount;
204 private int mCount;
205 private int mStart;
206 private int mEnd;
207 private String mCharacters;
208 private String mCharactersExtra;
209 private String mData;
210 private int mRangeType;
211 private int mRangeStyles;
212 private int mRangeLineStyle;
213 private boolean mRangeBoldLine;
214 private int mRangeForeColor;
215 private int mRangeBackColor;
216 private int mRangeLineColor;
217 private Location mLocation;
218 private Address mAddress;
219 private DomKeyLocation mDomKeyLocation;
221 private int mConnectionType;
222 private boolean mIsWifi;
223 private int mDHCPGateway;
225 private int mNativeWindow;
227 private short mScreenOrientation;
229 private ByteBuffer mBuffer;
231 private int mWidth;
232 private int mHeight;
234 private String[] mPrefNames;
236 private GeckoEvent(NativeGeckoEvent event) {
237 mType = event.value;
238 }
240 public static GeckoEvent createAppBackgroundingEvent() {
241 return GeckoEvent.get(NativeGeckoEvent.APP_BACKGROUNDING);
242 }
244 public static GeckoEvent createAppForegroundingEvent() {
245 return GeckoEvent.get(NativeGeckoEvent.APP_FOREGROUNDING);
246 }
248 public static GeckoEvent createNoOpEvent() {
249 return GeckoEvent.get(NativeGeckoEvent.NOOP);
250 }
252 public static GeckoEvent createKeyEvent(KeyEvent k, int metaState) {
253 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.KEY_EVENT);
254 event.initKeyEvent(k, metaState);
255 return event;
256 }
258 public static GeckoEvent createCompositorCreateEvent(int width, int height) {
259 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.COMPOSITOR_CREATE);
260 event.mWidth = width;
261 event.mHeight = height;
262 return event;
263 }
265 public static GeckoEvent createCompositorPauseEvent() {
266 return GeckoEvent.get(NativeGeckoEvent.COMPOSITOR_PAUSE);
267 }
269 public static GeckoEvent createCompositorResumeEvent() {
270 return GeckoEvent.get(NativeGeckoEvent.COMPOSITOR_RESUME);
271 }
273 private void initKeyEvent(KeyEvent k, int metaState) {
274 mAction = k.getAction();
275 mTime = k.getEventTime();
276 // Normally we expect k.getMetaState() to reflect the current meta-state; however,
277 // some software-generated key events may not have k.getMetaState() set, e.g. key
278 // events from Swype. Therefore, it's necessary to combine the key's meta-states
279 // with the meta-states that we keep separately in KeyListener
280 mMetaState = k.getMetaState() | metaState;
281 mFlags = k.getFlags();
282 mKeyCode = k.getKeyCode();
283 mUnicodeChar = k.getUnicodeChar(mMetaState);
284 // e.g. for Ctrl+A, Android returns 0 for mUnicodeChar,
285 // but Gecko expects 'a', so we return that in mBaseUnicodeChar
286 mBaseUnicodeChar = k.getUnicodeChar(0);
287 mRepeatCount = k.getRepeatCount();
288 mCharacters = k.getCharacters();
289 if (mUnicodeChar >= ' ') {
290 mDOMPrintableKeyValue = mUnicodeChar;
291 } else {
292 int unmodifiedMetaState =
293 mMetaState & ~(KeyEvent.META_ALT_MASK |
294 KeyEvent.META_CTRL_MASK |
295 KeyEvent.META_META_MASK);
296 if (unmodifiedMetaState != mMetaState) {
297 mDOMPrintableKeyValue = k.getUnicodeChar(unmodifiedMetaState);
298 }
299 }
300 mDomKeyLocation = isJoystickButton(mKeyCode) ? DomKeyLocation.DOM_KEY_LOCATION_JOYSTICK
301 : DomKeyLocation.DOM_KEY_LOCATION_MOBILE;
302 }
304 /**
305 * This method tests if a key is one of the described in:
306 * https://bugzilla.mozilla.org/show_bug.cgi?id=756504#c0
307 * @param keyCode int with the key code (Android key constant from KeyEvent)
308 * @return true if the key is one of the listed above, false otherwise.
309 */
310 private static boolean isJoystickButton(int keyCode) {
311 switch (keyCode) {
312 case KeyEvent.KEYCODE_DPAD_CENTER:
313 case KeyEvent.KEYCODE_DPAD_LEFT:
314 case KeyEvent.KEYCODE_DPAD_RIGHT:
315 case KeyEvent.KEYCODE_DPAD_DOWN:
316 case KeyEvent.KEYCODE_DPAD_UP:
317 return true;
318 default:
319 if (Build.VERSION.SDK_INT >= 12) {
320 return KeyEvent.isGamepadButton(keyCode);
321 }
322 return GeckoEvent.isGamepadButton(keyCode);
323 }
324 }
326 /**
327 * This method is a replacement for the the KeyEvent.isGamepadButton method to be
328 * compatible with Build.VERSION.SDK_INT < 12. This is an implementantion of the
329 * same method isGamepadButton available after SDK 12.
330 * @param keyCode int with the key code (Android key constant from KeyEvent).
331 * @return True if the keycode is a gamepad button, such as {@link #KEYCODE_BUTTON_A}.
332 */
333 private static boolean isGamepadButton(int keyCode) {
334 switch (keyCode) {
335 case KeyEvent.KEYCODE_BUTTON_A:
336 case KeyEvent.KEYCODE_BUTTON_B:
337 case KeyEvent.KEYCODE_BUTTON_C:
338 case KeyEvent.KEYCODE_BUTTON_X:
339 case KeyEvent.KEYCODE_BUTTON_Y:
340 case KeyEvent.KEYCODE_BUTTON_Z:
341 case KeyEvent.KEYCODE_BUTTON_L1:
342 case KeyEvent.KEYCODE_BUTTON_R1:
343 case KeyEvent.KEYCODE_BUTTON_L2:
344 case KeyEvent.KEYCODE_BUTTON_R2:
345 case KeyEvent.KEYCODE_BUTTON_THUMBL:
346 case KeyEvent.KEYCODE_BUTTON_THUMBR:
347 case KeyEvent.KEYCODE_BUTTON_START:
348 case KeyEvent.KEYCODE_BUTTON_SELECT:
349 case KeyEvent.KEYCODE_BUTTON_MODE:
350 case KeyEvent.KEYCODE_BUTTON_1:
351 case KeyEvent.KEYCODE_BUTTON_2:
352 case KeyEvent.KEYCODE_BUTTON_3:
353 case KeyEvent.KEYCODE_BUTTON_4:
354 case KeyEvent.KEYCODE_BUTTON_5:
355 case KeyEvent.KEYCODE_BUTTON_6:
356 case KeyEvent.KEYCODE_BUTTON_7:
357 case KeyEvent.KEYCODE_BUTTON_8:
358 case KeyEvent.KEYCODE_BUTTON_9:
359 case KeyEvent.KEYCODE_BUTTON_10:
360 case KeyEvent.KEYCODE_BUTTON_11:
361 case KeyEvent.KEYCODE_BUTTON_12:
362 case KeyEvent.KEYCODE_BUTTON_13:
363 case KeyEvent.KEYCODE_BUTTON_14:
364 case KeyEvent.KEYCODE_BUTTON_15:
365 case KeyEvent.KEYCODE_BUTTON_16:
366 return true;
367 default:
368 return false;
369 }
370 }
372 public static GeckoEvent createNativeGestureEvent(int action, PointF pt, double size) {
373 try {
374 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.NATIVE_GESTURE_EVENT);
375 event.mAction = action;
376 event.mCount = 1;
377 event.mPoints = new Point[1];
379 PointF geckoPoint = new PointF(pt.x, pt.y);
380 geckoPoint = GeckoAppShell.getLayerView().convertViewPointToLayerPoint(geckoPoint);
382 if (geckoPoint == null) {
383 // This could happen if Gecko isn't ready yet.
384 return null;
385 }
387 event.mPoints[0] = new Point(Math.round(geckoPoint.x), Math.round(geckoPoint.y));
389 event.mX = size;
390 event.mTime = System.currentTimeMillis();
391 return event;
392 } catch (Exception e) {
393 // This can happen if Gecko isn't ready yet
394 return null;
395 }
396 }
398 /**
399 * Creates a GeckoEvent that contains the data from the MotionEvent.
400 * The keepInViewCoordinates parameter can be set to false to convert from the Java
401 * coordinate system (device pixels relative to the LayerView) to a coordinate system
402 * relative to gecko's coordinate system (CSS pixels relative to gecko scroll position).
403 */
404 public static GeckoEvent createMotionEvent(MotionEvent m, boolean keepInViewCoordinates) {
405 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.MOTION_EVENT);
406 event.initMotionEvent(m, keepInViewCoordinates);
407 return event;
408 }
410 private void initMotionEvent(MotionEvent m, boolean keepInViewCoordinates) {
411 mAction = m.getActionMasked();
412 mTime = (System.currentTimeMillis() - SystemClock.elapsedRealtime()) + m.getEventTime();
413 mMetaState = m.getMetaState();
415 switch (mAction) {
416 case MotionEvent.ACTION_CANCEL:
417 case MotionEvent.ACTION_UP:
418 case MotionEvent.ACTION_POINTER_UP:
419 case MotionEvent.ACTION_POINTER_DOWN:
420 case MotionEvent.ACTION_DOWN:
421 case MotionEvent.ACTION_MOVE:
422 case MotionEvent.ACTION_HOVER_ENTER:
423 case MotionEvent.ACTION_HOVER_MOVE:
424 case MotionEvent.ACTION_HOVER_EXIT: {
425 mCount = m.getPointerCount();
426 mPoints = new Point[mCount];
427 mPointIndicies = new int[mCount];
428 mOrientations = new float[mCount];
429 mPressures = new float[mCount];
430 mPointRadii = new Point[mCount];
431 mPointerIndex = m.getActionIndex();
432 for (int i = 0; i < mCount; i++) {
433 addMotionPoint(i, i, m, keepInViewCoordinates);
434 }
435 break;
436 }
437 default: {
438 mCount = 0;
439 mPointerIndex = -1;
440 mPoints = new Point[mCount];
441 mPointIndicies = new int[mCount];
442 mOrientations = new float[mCount];
443 mPressures = new float[mCount];
444 mPointRadii = new Point[mCount];
445 }
446 }
447 }
449 private void addMotionPoint(int index, int eventIndex, MotionEvent event, boolean keepInViewCoordinates) {
450 try {
451 PointF geckoPoint = new PointF(event.getX(eventIndex), event.getY(eventIndex));
452 if (!keepInViewCoordinates) {
453 geckoPoint = GeckoAppShell.getLayerView().convertViewPointToLayerPoint(geckoPoint);
454 }
456 mPoints[index] = new Point(Math.round(geckoPoint.x), Math.round(geckoPoint.y));
457 mPointIndicies[index] = event.getPointerId(eventIndex);
458 // getToolMajor, getToolMinor and getOrientation are API Level 9 features
459 if (Build.VERSION.SDK_INT >= 9) {
460 double radians = event.getOrientation(eventIndex);
461 mOrientations[index] = (float) Math.toDegrees(radians);
462 // w3c touchevents spec does not allow orientations == 90
463 // this shifts it to -90, which will be shifted to zero below
464 if (mOrientations[index] == 90)
465 mOrientations[index] = -90;
467 // w3c touchevent radius are given by an orientation between 0 and 90
468 // the radius is found by removing the orientation and measuring the x and y
469 // radius of the resulting ellipse
470 // for android orientations >= 0 and < 90, the major axis should correspond to
471 // just reporting the y radius as the major one, and x as minor
472 // however, for a radius < 0, we have to shift the orientation by adding 90, and
473 // reverse which radius is major and minor
474 if (mOrientations[index] < 0) {
475 mOrientations[index] += 90;
476 mPointRadii[index] = new Point((int)event.getToolMajor(eventIndex)/2,
477 (int)event.getToolMinor(eventIndex)/2);
478 } else {
479 mPointRadii[index] = new Point((int)event.getToolMinor(eventIndex)/2,
480 (int)event.getToolMajor(eventIndex)/2);
481 }
482 } else {
483 float size = event.getSize(eventIndex);
484 Resources resources = GeckoAppShell.getContext().getResources();
485 DisplayMetrics displaymetrics = resources.getDisplayMetrics();
486 size = size*Math.min(displaymetrics.heightPixels, displaymetrics.widthPixels);
487 mPointRadii[index] = new Point((int)size,(int)size);
488 mOrientations[index] = 0;
489 }
490 if (!keepInViewCoordinates) {
491 // If we are converting to gecko CSS pixels, then we should adjust the
492 // radii as well
493 float zoom = GeckoAppShell.getLayerView().getViewportMetrics().zoomFactor;
494 mPointRadii[index].x /= zoom;
495 mPointRadii[index].y /= zoom;
496 }
497 mPressures[index] = event.getPressure(eventIndex);
498 } catch (Exception ex) {
499 Log.e(LOGTAG, "Error creating motion point " + index, ex);
500 mPointRadii[index] = new Point(0, 0);
501 mPoints[index] = new Point(0, 0);
502 }
503 }
505 private static int HalSensorAccuracyFor(int androidAccuracy) {
506 switch (androidAccuracy) {
507 case SensorManager.SENSOR_STATUS_UNRELIABLE:
508 return GeckoHalDefines.SENSOR_ACCURACY_UNRELIABLE;
509 case SensorManager.SENSOR_STATUS_ACCURACY_LOW:
510 return GeckoHalDefines.SENSOR_ACCURACY_LOW;
511 case SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM:
512 return GeckoHalDefines.SENSOR_ACCURACY_MED;
513 case SensorManager.SENSOR_STATUS_ACCURACY_HIGH:
514 return GeckoHalDefines.SENSOR_ACCURACY_HIGH;
515 }
516 return GeckoHalDefines.SENSOR_ACCURACY_UNKNOWN;
517 }
519 public static GeckoEvent createSensorEvent(SensorEvent s) {
520 int sensor_type = s.sensor.getType();
521 GeckoEvent event = null;
523 switch(sensor_type) {
525 case Sensor.TYPE_ACCELEROMETER:
526 event = GeckoEvent.get(NativeGeckoEvent.SENSOR_EVENT);
527 event.mFlags = GeckoHalDefines.SENSOR_ACCELERATION;
528 event.mMetaState = HalSensorAccuracyFor(s.accuracy);
529 event.mX = s.values[0];
530 event.mY = s.values[1];
531 event.mZ = s.values[2];
532 break;
534 case 10 /* Requires API Level 9, so just use the raw value - Sensor.TYPE_LINEAR_ACCELEROMETER*/ :
535 event = GeckoEvent.get(NativeGeckoEvent.SENSOR_EVENT);
536 event.mFlags = GeckoHalDefines.SENSOR_LINEAR_ACCELERATION;
537 event.mMetaState = HalSensorAccuracyFor(s.accuracy);
538 event.mX = s.values[0];
539 event.mY = s.values[1];
540 event.mZ = s.values[2];
541 break;
543 case Sensor.TYPE_ORIENTATION:
544 event = GeckoEvent.get(NativeGeckoEvent.SENSOR_EVENT);
545 event.mFlags = GeckoHalDefines.SENSOR_ORIENTATION;
546 event.mMetaState = HalSensorAccuracyFor(s.accuracy);
547 event.mX = s.values[0];
548 event.mY = s.values[1];
549 event.mZ = s.values[2];
550 break;
552 case Sensor.TYPE_GYROSCOPE:
553 event = GeckoEvent.get(NativeGeckoEvent.SENSOR_EVENT);
554 event.mFlags = GeckoHalDefines.SENSOR_GYROSCOPE;
555 event.mMetaState = HalSensorAccuracyFor(s.accuracy);
556 event.mX = Math.toDegrees(s.values[0]);
557 event.mY = Math.toDegrees(s.values[1]);
558 event.mZ = Math.toDegrees(s.values[2]);
559 break;
561 case Sensor.TYPE_PROXIMITY:
562 event = GeckoEvent.get(NativeGeckoEvent.SENSOR_EVENT);
563 event.mFlags = GeckoHalDefines.SENSOR_PROXIMITY;
564 event.mMetaState = HalSensorAccuracyFor(s.accuracy);
565 event.mX = s.values[0];
566 event.mY = 0;
567 event.mZ = s.sensor.getMaximumRange();
568 break;
570 case Sensor.TYPE_LIGHT:
571 event = GeckoEvent.get(NativeGeckoEvent.SENSOR_EVENT);
572 event.mFlags = GeckoHalDefines.SENSOR_LIGHT;
573 event.mMetaState = HalSensorAccuracyFor(s.accuracy);
574 event.mX = s.values[0];
575 break;
576 }
577 return event;
578 }
580 public static GeckoEvent createLocationEvent(Location l) {
581 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.LOCATION_EVENT);
582 event.mLocation = l;
583 return event;
584 }
586 public static GeckoEvent createIMEEvent(ImeAction action) {
587 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.IME_EVENT);
588 event.mAction = action.value;
589 return event;
590 }
592 public static GeckoEvent createIMEKeyEvent(KeyEvent k) {
593 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.IME_KEY_EVENT);
594 event.initKeyEvent(k, 0);
595 return event;
596 }
598 public static GeckoEvent createIMEReplaceEvent(int start, int end,
599 String text) {
600 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.IME_EVENT);
601 event.mAction = ImeAction.IME_REPLACE_TEXT.value;
602 event.mStart = start;
603 event.mEnd = end;
604 event.mCharacters = text;
605 return event;
606 }
608 public static GeckoEvent createIMESelectEvent(int start, int end) {
609 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.IME_EVENT);
610 event.mAction = ImeAction.IME_SET_SELECTION.value;
611 event.mStart = start;
612 event.mEnd = end;
613 return event;
614 }
616 public static GeckoEvent createIMECompositionEvent(int start, int end) {
617 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.IME_EVENT);
618 event.mAction = ImeAction.IME_UPDATE_COMPOSITION.value;
619 event.mStart = start;
620 event.mEnd = end;
621 return event;
622 }
624 public static GeckoEvent createIMERangeEvent(int start,
625 int end, int rangeType,
626 int rangeStyles,
627 int rangeLineStyle,
628 boolean rangeBoldLine,
629 int rangeForeColor,
630 int rangeBackColor,
631 int rangeLineColor) {
632 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.IME_EVENT);
633 event.mAction = ImeAction.IME_ADD_COMPOSITION_RANGE.value;
634 event.mStart = start;
635 event.mEnd = end;
636 event.mRangeType = rangeType;
637 event.mRangeStyles = rangeStyles;
638 event.mRangeLineStyle = rangeLineStyle;
639 event.mRangeBoldLine = rangeBoldLine;
640 event.mRangeForeColor = rangeForeColor;
641 event.mRangeBackColor = rangeBackColor;
642 event.mRangeLineColor = rangeLineColor;
643 return event;
644 }
646 public static GeckoEvent createDrawEvent(Rect rect) {
647 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.DRAW);
648 event.mRect = rect;
649 return event;
650 }
652 public static GeckoEvent createSizeChangedEvent(int w, int h, int screenw, int screenh) {
653 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.SIZE_CHANGED);
654 event.mPoints = new Point[2];
655 event.mPoints[0] = new Point(w, h);
656 event.mPoints[1] = new Point(screenw, screenh);
657 return event;
658 }
660 @RobocopTarget
661 public static GeckoEvent createBroadcastEvent(String subject, String data) {
662 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.BROADCAST);
663 event.mCharacters = subject;
664 event.mCharactersExtra = data;
665 return event;
666 }
668 public static GeckoEvent createViewportEvent(ImmutableViewportMetrics metrics, DisplayPortMetrics displayPort) {
669 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.VIEWPORT);
670 event.mCharacters = "Viewport:Change";
671 StringBuilder sb = new StringBuilder(256);
672 sb.append("{ \"x\" : ").append(metrics.viewportRectLeft)
673 .append(", \"y\" : ").append(metrics.viewportRectTop)
674 .append(", \"zoom\" : ").append(metrics.zoomFactor)
675 .append(", \"fixedMarginLeft\" : ").append(metrics.marginLeft)
676 .append(", \"fixedMarginTop\" : ").append(metrics.marginTop)
677 .append(", \"fixedMarginRight\" : ").append(metrics.marginRight)
678 .append(", \"fixedMarginBottom\" : ").append(metrics.marginBottom)
679 .append(", \"displayPort\" :").append(displayPort.toJSON())
680 .append('}');
681 event.mCharactersExtra = sb.toString();
682 return event;
683 }
685 public static GeckoEvent createURILoadEvent(String uri) {
686 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.LOAD_URI);
687 event.mCharacters = uri;
688 event.mCharactersExtra = "";
689 return event;
690 }
692 public static GeckoEvent createWebappLoadEvent(String uri) {
693 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.LOAD_URI);
694 event.mCharacters = uri;
695 event.mCharactersExtra = "-webapp";
696 return event;
697 }
699 public static GeckoEvent createBookmarkLoadEvent(String uri) {
700 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.LOAD_URI);
701 event.mCharacters = uri;
702 event.mCharactersExtra = "-bookmark";
703 return event;
704 }
706 public static GeckoEvent createVisitedEvent(String data) {
707 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.VISITED);
708 event.mCharacters = data;
709 return event;
710 }
712 public static GeckoEvent createNetworkEvent(int connectionType, boolean isWifi, int DHCPGateway) {
713 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.NETWORK_CHANGED);
714 event.mConnectionType = connectionType;
715 event.mIsWifi = isWifi;
716 event.mDHCPGateway = DHCPGateway;
717 return event;
718 }
720 public static GeckoEvent createThumbnailEvent(int tabId, int bufw, int bufh, ByteBuffer buffer) {
721 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.THUMBNAIL);
722 event.mPoints = new Point[1];
723 event.mPoints[0] = new Point(bufw, bufh);
724 event.mMetaState = tabId;
725 event.mBuffer = buffer;
726 return event;
727 }
729 public static GeckoEvent createScreenOrientationEvent(short aScreenOrientation) {
730 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.SCREENORIENTATION_CHANGED);
731 event.mScreenOrientation = aScreenOrientation;
732 return event;
733 }
735 public static GeckoEvent createCallObserverEvent(String observerKey, String topic, String data) {
736 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.CALL_OBSERVER);
737 event.mCharacters = observerKey;
738 event.mCharactersExtra = topic;
739 event.mData = data;
740 return event;
741 }
743 public static GeckoEvent createRemoveObserverEvent(String observerKey) {
744 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.REMOVE_OBSERVER);
745 event.mCharacters = observerKey;
746 return event;
747 }
749 @RobocopTarget
750 public static GeckoEvent createPreferencesObserveEvent(int requestId, String[] prefNames) {
751 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.PREFERENCES_OBSERVE);
752 event.mCount = requestId;
753 event.mPrefNames = prefNames;
754 return event;
755 }
757 @RobocopTarget
758 public static GeckoEvent createPreferencesGetEvent(int requestId, String[] prefNames) {
759 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.PREFERENCES_GET);
760 event.mCount = requestId;
761 event.mPrefNames = prefNames;
762 return event;
763 }
765 @RobocopTarget
766 public static GeckoEvent createPreferencesRemoveObserversEvent(int requestId) {
767 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.PREFERENCES_REMOVE_OBSERVERS);
768 event.mCount = requestId;
769 return event;
770 }
772 public static GeckoEvent createLowMemoryEvent(int level) {
773 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.LOW_MEMORY);
774 event.mMetaState = level;
775 return event;
776 }
778 public static GeckoEvent createNetworkLinkChangeEvent(String status) {
779 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.NETWORK_LINK_CHANGE);
780 event.mCharacters = status;
781 return event;
782 }
784 public static GeckoEvent createTelemetryHistogramAddEvent(String histogram,
785 int value) {
786 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.TELEMETRY_HISTOGRAM_ADD);
787 event.mCharacters = histogram;
788 event.mCount = value;
789 return event;
790 }
792 public static GeckoEvent createTelemetryUISessionStartEvent(String session, long timestamp) {
793 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.TELEMETRY_UI_SESSION_START);
794 event.mCharacters = session;
795 event.mTime = timestamp;
796 return event;
797 }
799 public static GeckoEvent createTelemetryUISessionStopEvent(String session, String reason, long timestamp) {
800 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.TELEMETRY_UI_SESSION_STOP);
801 event.mCharacters = session;
802 event.mCharactersExtra = reason;
803 event.mTime = timestamp;
804 return event;
805 }
807 public static GeckoEvent createTelemetryUIEvent(String action, String method, long timestamp, String extras) {
808 GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.TELEMETRY_UI_EVENT);
809 event.mData = action;
810 event.mCharacters = method;
811 event.mCharactersExtra = extras;
812 event.mTime = timestamp;
813 return event;
814 }
816 public void setAckNeeded(boolean ackNeeded) {
817 mAckNeeded = ackNeeded;
818 }
819 }