mobile/android/base/GeckoEvent.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     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 }

mercurial