widget/android/AndroidJavaWrappers.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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/. */
     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"
    14 using namespace mozilla;
    15 using namespace mozilla::dom;
    16 using namespace mozilla::widget::android;
    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;
    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;
    67 jclass AndroidGeckoEvent::jDomKeyLocationClass = 0;
    68 jfieldID AndroidGeckoEvent::jDomKeyLocationValueField = 0;
    70 jclass AndroidPoint::jPointClass = 0;
    71 jfieldID AndroidPoint::jXField = 0;
    72 jfieldID AndroidPoint::jYField = 0;
    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;
    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;
    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;
    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;
   101 RefCountedJavaObject::~RefCountedJavaObject() {
   102     if (mObject)
   103         GetJNIForThread()->DeleteGlobalRef(mObject);
   104     mObject = nullptr;
   105 }
   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 }
   119 void
   120 AndroidGeckoEvent::InitGeckoEventClass(JNIEnv *jEnv)
   121 {
   122     initInit();
   124     jGeckoEventClass = getClassGlobalRef("org/mozilla/gecko/GeckoEvent");
   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;");
   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;");
   172     // Init GeckoEvent.DomKeyLocation enum
   173     jDomKeyLocationClass = getClassGlobalRef("org/mozilla/gecko/GeckoEvent$DomKeyLocation");
   174     jDomKeyLocationValueField = getField("value", "I");
   175 }
   177 void
   178 AndroidLocation::InitLocationClass(JNIEnv *jEnv)
   179 {
   180     initInit();
   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 }
   192 nsGeoPosition*
   193 AndroidLocation::CreateGeoPosition(JNIEnv *jenv, jobject jobj)
   194 {
   195     AutoLocalJNIFrame jniFrame(jenv);
   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;
   212     return new nsGeoPosition(latitude, longitude,
   213                              altitude, accuracy,
   214                              accuracy, bearing,
   215                              speed,    time);
   216 }
   218 void
   219 AndroidPoint::InitPointClass(JNIEnv *jEnv)
   220 {
   221     initInit();
   223     jPointClass = getClassGlobalRef("android/graphics/Point");
   225     jXField = getField("x", "I");
   226     jYField = getField("y", "I");
   227 }
   229 void
   230 AndroidRect::InitRectClass(JNIEnv *jEnv)
   231 {
   232     initInit();
   234     jRectClass = getClassGlobalRef("android/graphics/Rect");
   236     jBottomField = getField("bottom", "I");
   237     jLeftField = getField("left", "I");
   238     jTopField = getField("top", "I");
   239     jRightField = getField("right", "I");
   240 }
   242 void
   243 AndroidRectF::InitRectFClass(JNIEnv *jEnv)
   244 {
   245     initInit();
   247     jRectClass = getClassGlobalRef("android/graphics/RectF");
   249     jBottomField = getField("bottom", "F");
   250     jLeftField = getField("left", "F");
   251     jTopField = getField("top", "F");
   252     jRightField = getField("right", "F");
   253 }
   255 void
   256 AndroidLayerRendererFrame::InitLayerRendererFrameClass(JNIEnv *jEnv)
   257 {
   258     initInit();
   260     jLayerRendererFrameClass = getClassGlobalRef("org/mozilla/gecko/gfx/LayerRenderer$Frame");
   262     jBeginDrawingMethod = getMethod("beginDrawing", "()V");
   263     jDrawBackgroundMethod = getMethod("drawBackground", "()V");
   264     jDrawForegroundMethod = getMethod("drawForeground", "()V");
   265     jEndDrawingMethod = getMethod("endDrawing", "()V");
   266 }
   268 #undef initInit
   269 #undef initClassGlobalRef
   270 #undef getField
   271 #undef getMethod
   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);
   284         nsIntPoint p(jpoint.X(), jpoint.Y());
   285         points.AppendElement(p);
   286     }
   287 }
   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 }
   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 }
   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 }
   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 }
   346 void
   347 AndroidGeckoEvent::ReadStringFromJString(nsString &aString, JNIEnv *jenv,
   348                                          jstring s)
   349 {
   350     if (!s) {
   351         aString.SetIsVoid(true);
   352         return;
   353     }
   355     int len = jenv->GetStringLength(s);
   356     aString.SetLength(len);
   357     jenv->GetStringRegion(s, 0, len, reinterpret_cast<jchar*>(aString.BeginWriting()));
   358 }
   360 void
   361 AndroidGeckoEvent::ReadCharactersField(JNIEnv *jenv)
   362 {
   363     jstring s = (jstring) jenv->GetObjectField(wrapped_obj, jCharactersField);
   364     ReadStringFromJString(mCharacters, jenv, s);
   365 }
   367 void
   368 AndroidGeckoEvent::ReadCharactersExtraField(JNIEnv *jenv)
   369 {
   370     jstring s = (jstring) jenv->GetObjectField(wrapped_obj, jCharactersExtraField);
   371     ReadStringFromJString(mCharactersExtra, jenv, s);
   372 }
   374 void
   375 AndroidGeckoEvent::ReadDataField(JNIEnv *jenv)
   376 {
   377     jstring s = (jstring) jenv->GetObjectField(wrapped_obj, jDataField);
   378     ReadStringFromJString(mData, jenv, s);
   379 }
   381 void
   382 AndroidGeckoEvent::UnionRect(nsIntRect const& aRect)
   383 {
   384     mRect = aRect.Union(mRect);
   385 }
   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 }
   399 void
   400 AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj)
   401 {
   402     NS_ASSERTION(!wrapped_obj, "Init called on non-null wrapped_obj!");
   404     wrapped_obj = jobj;
   406     if (!jobj)
   407         return;
   409     mAction = jenv->GetIntField(jobj, jActionField);
   410     mType = jenv->GetIntField(jobj, jTypeField);
   411     mAckNeeded = jenv->GetBooleanField(jobj, jAckNeededField);
   413     switch (mType) {
   414         case SIZE_CHANGED:
   415             ReadPointArray(mPoints, jenv, jPoints, 2);
   416             break;
   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;
   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);
   440             break;
   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);
   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);
   454             break;
   456         case IME_EVENT:
   457             mStart = jenv->GetIntField(jobj, jStartField);
   458             mEnd = jenv->GetIntField(jobj, jEndField);
   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;
   479         case DRAW:
   480             ReadRectField(jenv);
   481             break;
   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;
   491         case LOCATION_EVENT: {
   492             jobject location = jenv->GetObjectField(jobj, jLocationField);
   493             mGeoPosition = AndroidLocation::CreateGeoPosition(jenv, location);
   494             break;
   495         }
   497         case LOAD_URI: {
   498             ReadCharactersField(jenv);
   499             ReadCharactersExtraField(jenv);
   500             break;
   501         }
   503         case VIEWPORT:
   504         case BROADCAST: {
   505             ReadCharactersField(jenv);
   506             ReadCharactersExtraField(jenv);
   507             break;
   508         }
   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         }
   517         case VISITED: {
   518             ReadCharactersField(jenv);
   519             break;
   520         }
   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         }
   529         case SCREENORIENTATION_CHANGED: {
   530             mScreenOrientation = jenv->GetShortField(jobj, jScreenOrientationField);
   531             break;
   532         }
   534         case COMPOSITOR_CREATE: {
   535             mWidth = jenv->GetIntField(jobj, jWidthField);
   536             mHeight = jenv->GetIntField(jobj, jHeightField);
   537             break;
   538         }
   540         case CALL_OBSERVER: {
   541             ReadCharactersField(jenv);
   542             ReadCharactersExtraField(jenv);
   543             ReadDataField(jenv);
   544             break;
   545         }
   547         case REMOVE_OBSERVER: {
   548             ReadCharactersField(jenv);
   549             break;
   550         }
   552         case LOW_MEMORY: {
   553             mMetaState = jenv->GetIntField(jobj, jMetaStateField);
   554             break;
   555         }
   557         case NETWORK_LINK_CHANGE: {
   558             ReadCharactersField(jenv);
   559             break;
   560         }
   562         case TELEMETRY_HISTOGRAM_ADD: {
   563             ReadCharactersField(jenv);
   564             mCount = jenv->GetIntField(jobj, jCountField);
   565             break;
   566         }
   568         case TELEMETRY_UI_SESSION_START: {
   569             ReadCharactersField(jenv);
   570             mTime = jenv->GetLongField(jobj, jTimeField);
   571             break;
   572         }
   574         case TELEMETRY_UI_SESSION_STOP: {
   575             ReadCharactersField(jenv);
   576             ReadCharactersExtraField(jenv);
   577             mTime = jenv->GetLongField(jobj, jTimeField);
   578             break;
   579         }
   581         case TELEMETRY_UI_EVENT: {
   582             ReadCharactersField(jenv);
   583             ReadCharactersExtraField(jenv);
   584             ReadDataField(jenv);
   585             mTime = jenv->GetLongField(jobj, jTimeField);
   586             break;
   587         }
   589         case PREFERENCES_OBSERVE:
   590         case PREFERENCES_GET: {
   591             ReadStringArray(mPrefNames, jenv, jPrefNamesField);
   592             mCount = jenv->GetIntField(jobj, jCountField);
   593             break;
   594         }
   596         case PREFERENCES_REMOVE_OBSERVERS: {
   597             mCount = jenv->GetIntField(jobj, jCountField);
   598             break;
   599         }
   601         default:
   602             break;
   603     }
   605 #ifdef DEBUG_ANDROID_EVENTS
   606     ALOG("AndroidGeckoEvent: %p : %d", (void*)jobj, mType);
   607 #endif
   608 }
   610 void
   611 AndroidGeckoEvent::Init(int aType)
   612 {
   613     mType = aType;
   614     mAckNeeded = false;
   615 }
   617 void
   618 AndroidGeckoEvent::Init(AndroidGeckoEvent *aResizeEvent)
   619 {
   620     NS_ASSERTION(aResizeEvent->Type() == SIZE_CHANGED, "Init called on non-SIZE_CHANGED event");
   622     mType = FORCED_RESIZE;
   623     mAckNeeded = false;
   624     mTime = aResizeEvent->mTime;
   625     mPoints = aResizeEvent->mPoints; // x,y coordinates
   626 }
   628 WidgetTouchEvent
   629 AndroidGeckoEvent::MakeTouchEvent(nsIWidget* widget)
   630 {
   631     int type = NS_EVENT_NULL;
   632     int startIndex = 0;
   633     int endIndex = Count();
   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     }
   661     WidgetTouchEvent event(true, type, widget);
   662     if (type == NS_EVENT_NULL) {
   663         // An event we don't know about
   664         return event;
   665     }
   667     event.modifiers = DOMModifiers();
   668     event.time = Time();
   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     }
   692     return event;
   693 }
   695 MultiTouchInput
   696 AndroidGeckoEvent::MakeMultiTouchInput(nsIWidget* widget)
   697 {
   698     MultiTouchInput::MultiTouchType type = (MultiTouchInput::MultiTouchType)-1;
   699     int startIndex = 0;
   700     int endIndex = Count();
   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     }
   728     MultiTouchInput event(type, Time(), 0);
   729     event.modifiers = DOMModifiers();
   731     if (type < 0) {
   732         // An event we don't know about
   733         return event;
   734     }
   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     }
   751     return event;
   752 }
   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     }
   774     WidgetMouseEvent event(true, msg, widget,
   775                            WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
   777     if (msg == NS_EVENT_NULL) {
   778         // unknown type, or no point data. abort
   779         return event;
   780     }
   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();
   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);
   798     return event;
   799 }
   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 }
   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 }
   844 void
   845 AndroidLayerRendererFrame::Init(JNIEnv *env, jobject jobj)
   846 {
   847     if (!isNull()) {
   848         Dispose(env);
   849     }
   851     wrapped_obj = env->NewGlobalRef(jobj);
   852 }
   854 void
   855 AndroidLayerRendererFrame::Dispose(JNIEnv *env)
   856 {
   857     if (isNull()) {
   858         return;
   859     }
   861     env->DeleteGlobalRef(wrapped_obj);
   862     wrapped_obj = 0;
   863 }
   865 NS_IMPL_ISUPPORTS(nsAndroidDisplayport, nsIAndroidDisplayport)
   867 bool
   868 AndroidLayerRendererFrame::BeginDrawing(AutoLocalJNIFrame *jniFrame)
   869 {
   870     if (!jniFrame || !jniFrame->GetEnv())
   871         return false;
   873     jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jBeginDrawingMethod);
   874     if (jniFrame->CheckForException())
   875         return false;
   877     return true;
   878 }
   880 bool
   881 AndroidLayerRendererFrame::DrawBackground(AutoLocalJNIFrame *jniFrame)
   882 {
   883     if (!jniFrame || !jniFrame->GetEnv())
   884         return false;
   886     jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDrawBackgroundMethod);
   887     if (jniFrame->CheckForException())
   888         return false;
   890     return true;
   891 }
   893 bool
   894 AndroidLayerRendererFrame::DrawForeground(AutoLocalJNIFrame *jniFrame)
   895 {
   896     if (!jniFrame || !jniFrame->GetEnv())
   897         return false;
   899     jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDrawForegroundMethod);
   900     if (jniFrame->CheckForException())
   901         return false;
   903     return true;
   904 }
   906 bool
   907 AndroidLayerRendererFrame::EndDrawing(AutoLocalJNIFrame *jniFrame)
   908 {
   909     if (!jniFrame || !jniFrame->GetEnv())
   910         return false;
   912     jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jEndDrawingMethod);
   913     if (jniFrame->CheckForException())
   914         return false;
   916     return true;
   917 }
   919 void
   920 AndroidRect::Init(JNIEnv *jenv, jobject jobj)
   921 {
   922     NS_ASSERTION(wrapped_obj == nullptr, "Init called on non-null wrapped_obj!");
   924     wrapped_obj = jobj;
   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 }
   939 void
   940 AndroidRectF::Init(JNIEnv *jenv, jobject jobj)
   941 {
   942     NS_ASSERTION(wrapped_obj == nullptr, "Init called on non-null wrapped_obj!");
   944     wrapped_obj = jobj;
   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 }
   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);
   971     if (!jCharPtr) {
   972         SetIsVoid(true);
   973         return;
   974     }
   976     jsize len = jni->GetStringLength(jstr);
   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 }

mercurial