[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

benm at google.com benm at google.com
Wed Apr 7 23:45:04 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 90c278de5659aa68b25852626fc87f9c7815d53b
Author: benm at google.com <benm at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Nov 17 12:40:14 2009 +0000

    [Android] Android is missing the implementation of the GeolocationService iface.
    https://bugs.webkit.org/show_bug.cgi?id=31554
    
    Patch by Andrei Popescu <andreip at google.com> on 2009-11-17
    Reviewed by Dimitri Glazkov.
    
    No new tests required as this is platform specific code.
    
    * platform/android/GeolocationServiceAndroid.cpp: Added.
    (WebCore::GeolocationServiceAndroid::create):
    (WebCore::GeolocationServiceAndroid::GeolocationServiceAndroid):
    (WebCore::GeolocationServiceAndroid::startUpdating):
    (WebCore::GeolocationServiceAndroid::stopUpdating):
    (WebCore::GeolocationServiceAndroid::suspend):
    (WebCore::GeolocationServiceAndroid::resume):
    (WebCore::GeolocationServiceAndroid::newPositionAvailable):
    (WebCore::GeolocationServiceAndroid::newErrorAvailable):
    (WebCore::GeolocationServiceAndroid::timerFired):
    (WebCore::GeolocationServiceAndroid::isPositionMovement):
    (WebCore::GeolocationServiceAndroid::isPositionMoreAccurate):
    (WebCore::GeolocationServiceAndroid::isPositionMoreTimely):
    * platform/android/GeolocationServiceAndroid.h: Added.
    (WebCore::GeolocationServiceAndroid::~GeolocationServiceAndroid):
    (WebCore::GeolocationServiceAndroid::lastPosition):
    (WebCore::GeolocationServiceAndroid::lastError):
    * platform/android/GeolocationServiceBridge.cpp: Added.
    (WebCore::):
    (WebCore::GeolocationServiceBridge::GeolocationServiceBridge):
    (WebCore::GeolocationServiceBridge::~GeolocationServiceBridge):
    (WebCore::GeolocationServiceBridge::start):
    (WebCore::GeolocationServiceBridge::stop):
    (WebCore::GeolocationServiceBridge::setEnableGps):
    (WebCore::GeolocationServiceBridge::newLocationAvailable):
    (WebCore::GeolocationServiceBridge::newErrorAvailable):
    (WebCore::GeolocationServiceBridge::toGeoposition):
    (WebCore::GeolocationServiceBridge::startJavaImplementation):
    (WebCore::GeolocationServiceBridge::stopJavaImplementation):
    * platform/android/GeolocationServiceBridge.h: Added.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@51071 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 4d8c80b..16a3fe1 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,43 @@
+2009-11-17  Andrei Popescu  <andreip at google.com>
+
+        Reviewed by Dimitri Glazkov.
+
+        [Android] Android is missing the implementation of the GeolocationService iface.
+        https://bugs.webkit.org/show_bug.cgi?id=31554
+
+        No new tests required as this is platform specific code.
+
+        * platform/android/GeolocationServiceAndroid.cpp: Added.
+        (WebCore::GeolocationServiceAndroid::create):
+        (WebCore::GeolocationServiceAndroid::GeolocationServiceAndroid):
+        (WebCore::GeolocationServiceAndroid::startUpdating):
+        (WebCore::GeolocationServiceAndroid::stopUpdating):
+        (WebCore::GeolocationServiceAndroid::suspend):
+        (WebCore::GeolocationServiceAndroid::resume):
+        (WebCore::GeolocationServiceAndroid::newPositionAvailable):
+        (WebCore::GeolocationServiceAndroid::newErrorAvailable):
+        (WebCore::GeolocationServiceAndroid::timerFired):
+        (WebCore::GeolocationServiceAndroid::isPositionMovement):
+        (WebCore::GeolocationServiceAndroid::isPositionMoreAccurate):
+        (WebCore::GeolocationServiceAndroid::isPositionMoreTimely):
+        * platform/android/GeolocationServiceAndroid.h: Added.
+        (WebCore::GeolocationServiceAndroid::~GeolocationServiceAndroid):
+        (WebCore::GeolocationServiceAndroid::lastPosition):
+        (WebCore::GeolocationServiceAndroid::lastError):
+        * platform/android/GeolocationServiceBridge.cpp: Added.
+        (WebCore::):
+        (WebCore::GeolocationServiceBridge::GeolocationServiceBridge):
+        (WebCore::GeolocationServiceBridge::~GeolocationServiceBridge):
+        (WebCore::GeolocationServiceBridge::start):
+        (WebCore::GeolocationServiceBridge::stop):
+        (WebCore::GeolocationServiceBridge::setEnableGps):
+        (WebCore::GeolocationServiceBridge::newLocationAvailable):
+        (WebCore::GeolocationServiceBridge::newErrorAvailable):
+        (WebCore::GeolocationServiceBridge::toGeoposition):
+        (WebCore::GeolocationServiceBridge::startJavaImplementation):
+        (WebCore::GeolocationServiceBridge::stopJavaImplementation):
+        * platform/android/GeolocationServiceBridge.h: Added.
+
 2009-11-16  Kent Tamura  <tkent at chromium.org>
 
         Unreviewd build fix.
diff --git a/WebCore/platform/android/GeolocationServiceAndroid.cpp b/WebCore/platform/android/GeolocationServiceAndroid.cpp
new file mode 100644
index 0000000..d44b3f0
--- /dev/null
+++ b/WebCore/platform/android/GeolocationServiceAndroid.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GeolocationServiceAndroid.h"
+
+#include "GeolocationServiceBridge.h"
+#include "Geoposition.h"
+#include "PositionError.h"
+#include "PositionOptions.h"
+
+#include <wtf/CurrentTime.h>
+
+using JSC::Bindings::getJNIEnv;
+using namespace std;
+
+namespace WebCore {
+
+// GeolocationServiceAndroid is the Android implmentation of Geolocation
+// service. Each object of this class owns an object of type
+// GeolocationServiceBridge, which in turn owns a Java GeolocationService
+// object. Therefore, there is a 1:1 mapping between Geolocation,
+// GeolocationServiceAndroid, GeolocationServiceBridge and Java
+// GeolocationService objects. In the case where multiple Geolocation objects
+// exist simultaneously, the corresponsing Java GeolocationService objects all
+// register with the platform location service. It is the platform service that
+// handles making sure that updates are passed to all Geolocation objects.
+GeolocationService* GeolocationServiceAndroid::create(GeolocationServiceClient* client)
+{
+    return new GeolocationServiceAndroid(client);
+}
+
+GeolocationService::FactoryFunction* GeolocationService::s_factoryFunction = &GeolocationServiceAndroid::create;
+
+GeolocationServiceAndroid::GeolocationServiceAndroid(GeolocationServiceClient* client)
+    : GeolocationService(client)
+    , m_timer(this, &GeolocationServiceAndroid::timerFired)
+    , m_javaBridge(0)
+{
+}
+
+bool GeolocationServiceAndroid::startUpdating(PositionOptions* options)
+{
+    // This method is called every time a new watch or one-shot position request
+    // is started. If we already have a position or an error, call back
+    // immediately.
+    if (m_lastPosition || m_lastError) {
+        ASSERT(m_javaBridge);
+        m_timer.startOneShot(0);
+    }
+
+    // Lazilly create the Java object.
+    bool haveJavaBridge = m_javaBridge;
+    if (!haveJavaBridge)
+        m_javaBridge.set(new GeolocationServiceBridge(this));
+    ASSERT(m_javaBridge);
+
+    // On Android, high power == GPS. Set whether to use GPS before we start the
+    // implementation.
+    ASSERT(options);
+    if (options->enableHighAccuracy())
+        m_javaBridge->setEnableGps(true);
+
+    if (!haveJavaBridge)
+        m_javaBridge->start();
+
+    return true;
+}
+
+void GeolocationServiceAndroid::stopUpdating()
+{
+    // Called when the Geolocation object has no watches or one shots in
+    // progress.
+    m_javaBridge.clear();
+    // Reset last position and error to make sure that we always try to get a
+    // new position from the system service when a request is first made.
+    m_lastPosition = 0;
+    m_lastError = 0;
+}
+
+void GeolocationServiceAndroid::suspend()
+{
+    ASSERT(m_javaBridge);
+    m_javaBridge->stop();
+}
+
+void GeolocationServiceAndroid::resume()
+{
+    ASSERT(m_javaBridge);
+    m_javaBridge->start();
+}
+
+// Note that there is no guarantee that subsequent calls to this method offer a
+// more accurate or updated position.
+void GeolocationServiceAndroid::newPositionAvailable(PassRefPtr<Geoposition> position)
+{
+    ASSERT(position);
+    if (!m_lastPosition
+        || isPositionMovement(m_lastPosition.get(), position.get())
+        || isPositionMoreAccurate(m_lastPosition.get(), position.get())
+        || isPositionMoreTimely(m_lastPosition.get(), position.get())) {
+        m_lastPosition = position;
+        // Remove the last error.
+        m_lastError = 0;
+        positionChanged();
+    }
+}
+
+void GeolocationServiceAndroid::newErrorAvailable(PassRefPtr<PositionError> error)
+{
+    ASSERT(error);
+    // We leave the last position
+    m_lastError = error;
+    errorOccurred();
+}
+
+void GeolocationServiceAndroid::timerFired(Timer<GeolocationServiceAndroid>* timer)
+{
+    ASSERT(&m_timer == timer);
+    ASSERT(m_lastPosition || m_lastError);
+    if (m_lastPosition)
+        positionChanged();
+    else
+        errorOccurred();
+}
+
+bool GeolocationServiceAndroid::isPositionMovement(Geoposition* position1, Geoposition* position2)
+{
+    ASSERT(position1 && position2);
+    // For the small distances in which we are likely concerned, it's reasonable
+    // to approximate the distance between the two positions as the sum of the
+    // differences in latitude and longitude.
+    double delta = fabs(position1->coords()->latitude() - position2->coords()->latitude())
+        + fabs(position1->coords()->longitude() - position2->coords()->longitude());
+    // Approximate conversion from degrees of arc to metres.
+    delta *= 60 * 1852;
+    // The threshold is when the distance between the two positions exceeds the
+    // worse (larger) of the two accuracies.
+    int maxAccuracy = max(position1->coords()->accuracy(), position2->coords()->accuracy());
+    return delta > maxAccuracy;
+}
+
+bool GeolocationServiceAndroid::isPositionMoreAccurate(Geoposition* position1, Geoposition* position2)
+{
+    ASSERT(position1 && position2);
+    return position2->coords()->accuracy() < position1->coords()->accuracy();
+}
+
+bool GeolocationServiceAndroid::isPositionMoreTimely(Geoposition* position1, Geoposition* position2)
+{
+    ASSERT(position1 && position2);
+    DOMTimeStamp currentTimeMillis = WTF::currentTime() * 1000.0;
+    DOMTimeStamp maximumAgeMillis = 10 * 60 * 1000;  // 10 minutes
+    return currentTimeMillis - position1->timestamp() > maximumAgeMillis;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/android/GeolocationServiceAndroid.h b/WebCore/platform/android/GeolocationServiceAndroid.h
new file mode 100644
index 0000000..b2be750
--- /dev/null
+++ b/WebCore/platform/android/GeolocationServiceAndroid.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GeolocationServiceAndroid_h
+#define GeolocationServiceAndroid_h
+
+#include "GeolocationService.h"
+#include "Timer.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+// The GeolocationServiceBridge is the bridge to the Java implementation of
+// the Geolocation service. It is an implementation detail of
+// GeolocationServiceAndroid.
+class GeolocationServiceBridge;
+
+class GeolocationServiceAndroid : public GeolocationService {
+public:
+    static GeolocationService* create(GeolocationServiceClient*);
+
+    virtual ~GeolocationServiceAndroid() { };
+
+    virtual bool startUpdating(PositionOptions*);
+    virtual void stopUpdating();
+
+    virtual Geoposition* lastPosition() const { return m_lastPosition.get(); }
+    virtual PositionError* lastError() const { return m_lastError.get(); }
+
+    virtual void suspend();
+    virtual void resume();
+
+    // Android-specific
+    void newPositionAvailable(PassRefPtr<Geoposition>);
+    void newErrorAvailable(PassRefPtr<PositionError>);
+    void timerFired(Timer<GeolocationServiceAndroid>* timer);
+
+private:
+    GeolocationServiceAndroid(GeolocationServiceClient*);
+
+    static bool isPositionMovement(Geoposition* position1, Geoposition* position2);
+    static bool isPositionMoreAccurate(Geoposition* position1, Geoposition* position2);
+    static bool isPositionMoreTimely(Geoposition* position1, Geoposition* position2);
+
+    Timer<GeolocationServiceAndroid> m_timer;
+    RefPtr<Geoposition> m_lastPosition;
+    RefPtr<PositionError> m_lastError;
+    OwnPtr<GeolocationServiceBridge> m_javaBridge;
+};
+
+} // namespace WebCore
+
+#endif // GeolocationServiceAndroid_h
diff --git a/WebCore/platform/android/GeolocationServiceBridge.cpp b/WebCore/platform/android/GeolocationServiceBridge.cpp
new file mode 100644
index 0000000..c8ba85d
--- /dev/null
+++ b/WebCore/platform/android/GeolocationServiceBridge.cpp
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GeolocationServiceBridge.h"
+
+#include "GeolocationServiceAndroid.h"
+#include "Geoposition.h"
+#include "PositionError.h"
+#include "WebViewCore.h"
+#include <JNIHelp.h>
+#include <jni_utility.h>
+
+namespace WebCore {
+
+using JSC::Bindings::getJNIEnv;
+
+static const char* javaGeolocationServiceClassName = "android/webkit/GeolocationService";
+enum javaGeolocationServiceClassMethods {
+    GeolocationServiceMethodInit = 0,
+    GeolocationServiceMethodStart,
+    GeolocationServiceMethodStop,
+    GeolocationServiceMethodSetEnableGps,
+    GeolocationServiceMethodCount,
+};
+static jmethodID javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodCount];
+
+static const JNINativeMethod javaGeolocationServiceClassNativeMethods[] = {
+    { "nativeNewLocationAvailable", "(JLandroid/location/Location;)V",
+        (void*) GeolocationServiceBridge::newLocationAvailable },
+    { "nativeNewErrorAvailable", "(JLjava/lang/String;)V",
+        (void*) GeolocationServiceBridge::newErrorAvailable }
+};
+
+static const char *javaLocationClassName = "android/location/Location";
+enum javaLocationClassMethods {
+    LocationMethodGetLatitude = 0,
+    LocationMethodGetLongitude,
+    LocationMethodHasAltitude,
+    LocationMethodGetAltitude,
+    LocationMethodHasAccuracy,
+    LocationMethodGetAccuracy,
+    LocationMethodHasBearing,
+    LocationMethodGetBearing,
+    LocationMethodHasSpeed,
+    LocationMethodGetSpeed,
+    LocationMethodGetTime,
+    LocationMethodCount,
+};
+static jmethodID javaLocationClassMethodIDs[LocationMethodCount];
+
+GeolocationServiceBridge::GeolocationServiceBridge(ListenerInterface* listener)
+    : m_listener(listener)
+    , m_javaGeolocationServiceObject(0)
+{
+    ASSERT(m_listener);
+    startJavaImplementation();
+}
+
+GeolocationServiceBridge::~GeolocationServiceBridge()
+{
+    stop();
+    stopJavaImplementation();
+}
+
+void GeolocationServiceBridge::start()
+{
+    ASSERT(m_javaGeolocationServiceObject);
+    getJNIEnv()->CallVoidMethod(m_javaGeolocationServiceObject,
+                                javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStart]);
+}
+
+void GeolocationServiceBridge::stop()
+{
+    ASSERT(m_javaGeolocationServiceObject);
+    getJNIEnv()->CallVoidMethod(m_javaGeolocationServiceObject,
+                                javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStop]);
+}
+
+void GeolocationServiceBridge::setEnableGps(bool enable)
+{
+    ASSERT(m_javaGeolocationServiceObject);
+    getJNIEnv()->CallVoidMethod(m_javaGeolocationServiceObject,
+                                javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodSetEnableGps],
+                                enable);
+}
+
+void GeolocationServiceBridge::newLocationAvailable(JNIEnv* env, jclass, jlong nativeObject, jobject location)
+{
+    ASSERT(nativeObject);
+    ASSERT(location);
+    GeolocationServiceBridge* object = reinterpret_cast<GeolocationServiceBridge*>(nativeObject);
+    object->m_listener->newPositionAvailable(toGeoposition(env, location));
+}
+
+void GeolocationServiceBridge::newErrorAvailable(JNIEnv* env, jclass, jlong nativeObject, jstring message)
+{
+    GeolocationServiceBridge* object = reinterpret_cast<GeolocationServiceBridge*>(nativeObject);
+    RefPtr<PositionError> error =
+        PositionError::create(PositionError::POSITION_UNAVAILABLE, android::to_string(env, message));
+    object->m_listener->newErrorAvailable(error.release());
+}
+
+PassRefPtr<Geoposition> GeolocationServiceBridge::toGeoposition(JNIEnv *env, const jobject &location)
+{
+    // Altitude is optional and may not be supplied.
+    bool hasAltitude =
+        env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasAltitude]);
+    double Altitude =
+        hasAltitude ?
+        env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetAltitude]) :
+        0.0;
+    // Accuracy is required, but is not supplied by the emulator.
+    double Accuracy =
+        env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasAccuracy]) ?
+        env->CallFloatMethod(location, javaLocationClassMethodIDs[LocationMethodGetAccuracy]) :
+        0.0;
+    // heading is optional and may not be supplied.
+    bool hasHeading =
+        env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasBearing]);
+    double heading =
+        hasHeading ?
+        env->CallFloatMethod(location, javaLocationClassMethodIDs[LocationMethodGetBearing]) :
+        0.0;
+    // speed is optional and may not be supplied.
+    bool hasSpeed =
+        env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasSpeed]);
+    double speed =
+        hasSpeed ?
+        env->CallFloatMethod(location, javaLocationClassMethodIDs[LocationMethodGetSpeed]) :
+        0.0;
+
+    RefPtr<Coordinates> newCoordinates = WebCore::Coordinates::create(
+        env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetLatitude]),
+        env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetLongitude]),
+        hasAltitude, Altitude,
+        Accuracy,
+        false, 0.0,  // AltitudeAccuracy not provided.
+        hasHeading, heading,
+        hasSpeed, speed);
+
+    return WebCore::Geoposition::create(
+         newCoordinates.release(),
+         env->CallLongMethod(location, javaLocationClassMethodIDs[LocationMethodGetTime]));
+}
+
+void GeolocationServiceBridge::startJavaImplementation()
+{
+    JNIEnv* env = getJNIEnv();
+
+    // Get the Java GeolocationService class.
+    jclass javaGeolocationServiceClass = env->FindClass(javaGeolocationServiceClassName);
+    ASSERT(javaGeolocationServiceClass);
+
+    // Set up the methods we wish to call on the Java GeolocationService class.
+    javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodInit] =
+            env->GetMethodID(javaGeolocationServiceClass, "<init>", "(J)V");
+    javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStart] =
+            env->GetMethodID(javaGeolocationServiceClass, "start", "()V");
+    javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStop] =
+            env->GetMethodID(javaGeolocationServiceClass, "stop", "()V");
+    javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodSetEnableGps] =
+            env->GetMethodID(javaGeolocationServiceClass, "setEnableGps", "(Z)V");
+
+    // Create the Java GeolocationService object.
+    jlong nativeObject = reinterpret_cast<jlong>(this);
+    jobject object = env->NewObject(javaGeolocationServiceClass,
+                                    javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodInit],
+                                    nativeObject);
+
+    m_javaGeolocationServiceObject = getJNIEnv()->NewGlobalRef(object);
+    ASSERT(m_javaGeolocationServiceObject);
+
+    // Register to handle calls to native methods of the Java GeolocationService
+    // object. We register once only.
+    static int registered = jniRegisterNativeMethods(env,
+                                                     javaGeolocationServiceClassName,
+                                                     javaGeolocationServiceClassNativeMethods,
+                                                     NELEM(javaGeolocationServiceClassNativeMethods));
+    ASSERT(registered == JNI_OK);
+
+    // Set up the methods we wish to call on the Java Location class.
+    jclass javaLocationClass = env->FindClass(javaLocationClassName);
+    ASSERT(javaLocationClass);
+    javaLocationClassMethodIDs[LocationMethodGetLatitude] =
+        env->GetMethodID(javaLocationClass, "getLatitude", "()D");
+    javaLocationClassMethodIDs[LocationMethodGetLongitude] =
+        env->GetMethodID(javaLocationClass, "getLongitude", "()D");
+    javaLocationClassMethodIDs[LocationMethodHasAltitude] =
+        env->GetMethodID(javaLocationClass, "hasAltitude", "()Z");
+    javaLocationClassMethodIDs[LocationMethodGetAltitude] =
+        env->GetMethodID(javaLocationClass, "getAltitude", "()D");
+    javaLocationClassMethodIDs[LocationMethodHasAccuracy] =
+        env->GetMethodID(javaLocationClass, "hasAccuracy", "()Z");
+    javaLocationClassMethodIDs[LocationMethodGetAccuracy] =
+        env->GetMethodID(javaLocationClass, "getAccuracy", "()F");
+    javaLocationClassMethodIDs[LocationMethodHasBearing] =
+        env->GetMethodID(javaLocationClass, "hasBearing", "()Z");
+    javaLocationClassMethodIDs[LocationMethodGetBearing] =
+        env->GetMethodID(javaLocationClass, "getBearing", "()F");
+    javaLocationClassMethodIDs[LocationMethodHasSpeed] =
+        env->GetMethodID(javaLocationClass, "hasSpeed", "()Z");
+    javaLocationClassMethodIDs[LocationMethodGetSpeed] =
+        env->GetMethodID(javaLocationClass, "getSpeed", "()F");
+    javaLocationClassMethodIDs[LocationMethodGetTime] =
+        env->GetMethodID(javaLocationClass, "getTime", "()J");
+}
+
+void GeolocationServiceBridge::stopJavaImplementation()
+{
+    // Called by GeolocationServiceAndroid on WebKit thread.
+    ASSERT(m_javaGeolocationServiceObject);
+    getJNIEnv()->DeleteGlobalRef(m_javaGeolocationServiceObject);
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/android/GeolocationServiceBridge.h b/WebCore/platform/android/GeolocationServiceBridge.h
new file mode 100644
index 0000000..0a83ba7
--- /dev/null
+++ b/WebCore/platform/android/GeolocationServiceBridge.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GeolocationServiceBridge_h
+#define GeolocationServiceBridge_h
+
+#include <jni_utility.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class GeolocationServiceAndroid;
+class Geoposition;
+
+// GeolocationServiceBridge is the bridge to the Java implementation. It manages
+// the lifetime of the Java object. It is an implementation detail of
+// GeolocationServiceAndroid.
+class GeolocationServiceBridge {
+public:
+    typedef GeolocationServiceAndroid ListenerInterface;
+    GeolocationServiceBridge(ListenerInterface* listener);
+    ~GeolocationServiceBridge();
+
+    void start();
+    void stop();
+    void setEnableGps(bool enable);
+
+    // Static wrapper functions to hide JNI nastiness.
+    static void newLocationAvailable(JNIEnv *env, jclass, jlong nativeObject, jobject location);
+    static void newErrorAvailable(JNIEnv *env, jclass, jlong nativeObject, jstring message);
+    static PassRefPtr<Geoposition> toGeoposition(JNIEnv *env, const jobject &location);
+
+private:
+    void startJavaImplementation();
+    void stopJavaImplementation();
+
+    ListenerInterface* m_listener;
+    jobject m_javaGeolocationServiceObject;
+};
+
+} // namespace WebCore
+
+#endif // GeolocationServiceBridge_h

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list