1f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu/*
2f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu * Copyright 2009, The Android Open Source Project
3f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu *
4f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu * Redistribution and use in source and binary forms, with or without
5f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu * modification, are permitted provided that the following conditions
6f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu * are met:
7f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu *  * Redistributions of source code must retain the above copyright
8f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu *    notice, this list of conditions and the following disclaimer.
9f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu *  * Redistributions in binary form must reproduce the above copyright
10f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu *    notice, this list of conditions and the following disclaimer in the
11f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu *    documentation and/or other materials provided with the distribution.
12f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu *
13f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu */
25f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
26f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu#include "config.h"
27f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu#include "GeolocationServiceBridge.h"
28f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
29e07f6aabbe877315688b586c09a36cbe02b7a2a1Steve Block#include "Frame.h"
30f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu#include "GeolocationServiceAndroid.h"
31f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu#include "Geoposition.h"
32f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu#include "PositionError.h"
33f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu#include "WebViewCore.h"
34f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu#include <JNIHelp.h>
35f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
36f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescunamespace WebCore {
37f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
38f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescuusing JSC::Bindings::getJNIEnv;
39f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
40f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescustatic const char* javaGeolocationServiceClassName = "android/webkit/GeolocationService";
41f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescuenum javaGeolocationServiceClassMethods {
42f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    GeolocationServiceMethodInit = 0,
43f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    GeolocationServiceMethodStart,
44f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    GeolocationServiceMethodStop,
45f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    GeolocationServiceMethodSetEnableGps,
46f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    GeolocationServiceMethodCount,
47f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu};
48f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescustatic jmethodID javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodCount];
49f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
50f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescustatic const JNINativeMethod javaGeolocationServiceClassNativeMethods[] = {
51f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    { "nativeNewLocationAvailable", "(JLandroid/location/Location;)V",
52f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        (void*) GeolocationServiceBridge::newLocationAvailable },
53f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    { "nativeNewErrorAvailable", "(JLjava/lang/String;)V",
54f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        (void*) GeolocationServiceBridge::newErrorAvailable }
55f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu};
56f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
57f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescustatic const char *javaLocationClassName = "android/location/Location";
58f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescuenum javaLocationClassMethods {
59f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    LocationMethodGetLatitude = 0,
60f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    LocationMethodGetLongitude,
61f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    LocationMethodHasAltitude,
62f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    LocationMethodGetAltitude,
63f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    LocationMethodHasAccuracy,
64f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    LocationMethodGetAccuracy,
65f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    LocationMethodHasBearing,
66f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    LocationMethodGetBearing,
67f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    LocationMethodHasSpeed,
68f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    LocationMethodGetSpeed,
69f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    LocationMethodGetTime,
70f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    LocationMethodCount,
71f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu};
72f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescustatic jmethodID javaLocationClassMethodIDs[LocationMethodCount];
73f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
74e07f6aabbe877315688b586c09a36cbe02b7a2a1Steve BlockGeolocationServiceBridge::GeolocationServiceBridge(ListenerInterface* listener, Frame* frame)
75f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    : m_listener(listener)
76f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    , m_javaGeolocationServiceObject(0)
77f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu{
78f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    ASSERT(m_listener);
79e07f6aabbe877315688b586c09a36cbe02b7a2a1Steve Block    startJavaImplementation(frame);
80f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu}
81f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
82f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei PopescuGeolocationServiceBridge::~GeolocationServiceBridge()
83f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu{
84f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    stop();
85f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    stopJavaImplementation();
86f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu}
87f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
880394c84380567e7a4b3cee843340a3529eb73be1Steve Blockbool GeolocationServiceBridge::start()
89f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu{
90b4d178df818e8b6e7a1cfbb0e34bbf7bb9d74ec9Steve Block    if (!m_javaGeolocationServiceObject)
91b4d178df818e8b6e7a1cfbb0e34bbf7bb9d74ec9Steve Block        return false;
920394c84380567e7a4b3cee843340a3529eb73be1Steve Block    return getJNIEnv()->CallBooleanMethod(m_javaGeolocationServiceObject,
930394c84380567e7a4b3cee843340a3529eb73be1Steve Block                                          javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStart]);
94f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu}
95f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
96f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescuvoid GeolocationServiceBridge::stop()
97f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu{
98b4d178df818e8b6e7a1cfbb0e34bbf7bb9d74ec9Steve Block    if (!m_javaGeolocationServiceObject)
99b4d178df818e8b6e7a1cfbb0e34bbf7bb9d74ec9Steve Block        return;
100f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    getJNIEnv()->CallVoidMethod(m_javaGeolocationServiceObject,
101f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu                                javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStop]);
102f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu}
103f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
104f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescuvoid GeolocationServiceBridge::setEnableGps(bool enable)
105f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu{
106b4d178df818e8b6e7a1cfbb0e34bbf7bb9d74ec9Steve Block    if (!m_javaGeolocationServiceObject)
107b4d178df818e8b6e7a1cfbb0e34bbf7bb9d74ec9Steve Block        return;
108f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    getJNIEnv()->CallVoidMethod(m_javaGeolocationServiceObject,
109f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu                                javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodSetEnableGps],
110f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu                                enable);
111f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu}
112f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
113f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescuvoid GeolocationServiceBridge::newLocationAvailable(JNIEnv* env, jclass, jlong nativeObject, jobject location)
114f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu{
115f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    ASSERT(nativeObject);
116f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    ASSERT(location);
117f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    GeolocationServiceBridge* object = reinterpret_cast<GeolocationServiceBridge*>(nativeObject);
118f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    object->m_listener->newPositionAvailable(toGeoposition(env, location));
119f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu}
120f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
121f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescuvoid GeolocationServiceBridge::newErrorAvailable(JNIEnv* env, jclass, jlong nativeObject, jstring message)
122f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu{
123f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    GeolocationServiceBridge* object = reinterpret_cast<GeolocationServiceBridge*>(nativeObject);
124f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    RefPtr<PositionError> error =
12527dd31673790eed64c3e0e508bb900671f06bcb3Steve Block        PositionError::create(PositionError::POSITION_UNAVAILABLE, android::jstringToWtfString(env, message));
126f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    object->m_listener->newErrorAvailable(error.release());
127f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu}
128f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
129f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei PopescuPassRefPtr<Geoposition> GeolocationServiceBridge::toGeoposition(JNIEnv *env, const jobject &location)
130f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu{
131f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    // Altitude is optional and may not be supplied.
132f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    bool hasAltitude =
133f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasAltitude]);
134f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    double Altitude =
135f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        hasAltitude ?
136f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetAltitude]) :
137f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        0.0;
138f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    // Accuracy is required, but is not supplied by the emulator.
139f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    double Accuracy =
140f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasAccuracy]) ?
141f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->CallFloatMethod(location, javaLocationClassMethodIDs[LocationMethodGetAccuracy]) :
142f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        0.0;
143f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    // heading is optional and may not be supplied.
144f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    bool hasHeading =
145f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasBearing]);
146f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    double heading =
147f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        hasHeading ?
148f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->CallFloatMethod(location, javaLocationClassMethodIDs[LocationMethodGetBearing]) :
149f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        0.0;
150f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    // speed is optional and may not be supplied.
151f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    bool hasSpeed =
152f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasSpeed]);
153f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    double speed =
154f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        hasSpeed ?
155f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->CallFloatMethod(location, javaLocationClassMethodIDs[LocationMethodGetSpeed]) :
156f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        0.0;
157f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
158f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    RefPtr<Coordinates> newCoordinates = WebCore::Coordinates::create(
159f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetLatitude]),
160f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetLongitude]),
161f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        hasAltitude, Altitude,
162f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        Accuracy,
163f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        false, 0.0,  // AltitudeAccuracy not provided.
164f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        hasHeading, heading,
165f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        hasSpeed, speed);
166f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
167f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    return WebCore::Geoposition::create(
168f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu         newCoordinates.release(),
169f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu         env->CallLongMethod(location, javaLocationClassMethodIDs[LocationMethodGetTime]));
170f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu}
171f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
172e07f6aabbe877315688b586c09a36cbe02b7a2a1Steve Blockvoid GeolocationServiceBridge::startJavaImplementation(Frame* frame)
173f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu{
174f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    JNIEnv* env = getJNIEnv();
175f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
176f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    // Get the Java GeolocationService class.
177f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    jclass javaGeolocationServiceClass = env->FindClass(javaGeolocationServiceClassName);
178f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    ASSERT(javaGeolocationServiceClass);
179f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
180f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    // Set up the methods we wish to call on the Java GeolocationService class.
181f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodInit] =
182e07f6aabbe877315688b586c09a36cbe02b7a2a1Steve Block            env->GetMethodID(javaGeolocationServiceClass, "<init>", "(Landroid/content/Context;J)V");
183f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStart] =
1840394c84380567e7a4b3cee843340a3529eb73be1Steve Block            env->GetMethodID(javaGeolocationServiceClass, "start", "()Z");
185f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStop] =
186f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu            env->GetMethodID(javaGeolocationServiceClass, "stop", "()V");
187f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodSetEnableGps] =
188f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu            env->GetMethodID(javaGeolocationServiceClass, "setEnableGps", "(Z)V");
189f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
190f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    // Create the Java GeolocationService object.
191b4d178df818e8b6e7a1cfbb0e34bbf7bb9d74ec9Steve Block    jobject context = android::WebViewCore::getWebViewCore(frame->view())->getContext();
192b4d178df818e8b6e7a1cfbb0e34bbf7bb9d74ec9Steve Block    if (!context)
193b4d178df818e8b6e7a1cfbb0e34bbf7bb9d74ec9Steve Block        return;
194f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    jlong nativeObject = reinterpret_cast<jlong>(this);
195f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    jobject object = env->NewObject(javaGeolocationServiceClass,
196f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu                                    javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodInit],
197b4d178df818e8b6e7a1cfbb0e34bbf7bb9d74ec9Steve Block                                    context,
198f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu                                    nativeObject);
199f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
200f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    m_javaGeolocationServiceObject = getJNIEnv()->NewGlobalRef(object);
201f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    ASSERT(m_javaGeolocationServiceObject);
202f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
203f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    // Register to handle calls to native methods of the Java GeolocationService
204f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    // object. We register once only.
205f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    static int registered = jniRegisterNativeMethods(env,
206f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu                                                     javaGeolocationServiceClassName,
207f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu                                                     javaGeolocationServiceClassNativeMethods,
208f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu                                                     NELEM(javaGeolocationServiceClassNativeMethods));
209f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    ASSERT(registered == JNI_OK);
210f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
211f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    // Set up the methods we wish to call on the Java Location class.
212f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    jclass javaLocationClass = env->FindClass(javaLocationClassName);
213f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    ASSERT(javaLocationClass);
214f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    javaLocationClassMethodIDs[LocationMethodGetLatitude] =
215f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->GetMethodID(javaLocationClass, "getLatitude", "()D");
216f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    javaLocationClassMethodIDs[LocationMethodGetLongitude] =
217f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->GetMethodID(javaLocationClass, "getLongitude", "()D");
218f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    javaLocationClassMethodIDs[LocationMethodHasAltitude] =
219f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->GetMethodID(javaLocationClass, "hasAltitude", "()Z");
220f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    javaLocationClassMethodIDs[LocationMethodGetAltitude] =
221f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->GetMethodID(javaLocationClass, "getAltitude", "()D");
222f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    javaLocationClassMethodIDs[LocationMethodHasAccuracy] =
223f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->GetMethodID(javaLocationClass, "hasAccuracy", "()Z");
224f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    javaLocationClassMethodIDs[LocationMethodGetAccuracy] =
225f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->GetMethodID(javaLocationClass, "getAccuracy", "()F");
226f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    javaLocationClassMethodIDs[LocationMethodHasBearing] =
227f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->GetMethodID(javaLocationClass, "hasBearing", "()Z");
228f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    javaLocationClassMethodIDs[LocationMethodGetBearing] =
229f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->GetMethodID(javaLocationClass, "getBearing", "()F");
230f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    javaLocationClassMethodIDs[LocationMethodHasSpeed] =
231f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->GetMethodID(javaLocationClass, "hasSpeed", "()Z");
232f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    javaLocationClassMethodIDs[LocationMethodGetSpeed] =
233f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->GetMethodID(javaLocationClass, "getSpeed", "()F");
234f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    javaLocationClassMethodIDs[LocationMethodGetTime] =
235f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu        env->GetMethodID(javaLocationClass, "getTime", "()J");
236f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu}
237f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
238f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescuvoid GeolocationServiceBridge::stopJavaImplementation()
239f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu{
240f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    // Called by GeolocationServiceAndroid on WebKit thread.
241b4d178df818e8b6e7a1cfbb0e34bbf7bb9d74ec9Steve Block    if (!m_javaGeolocationServiceObject)
242b4d178df818e8b6e7a1cfbb0e34bbf7bb9d74ec9Steve Block        return;
243f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu    getJNIEnv()->DeleteGlobalRef(m_javaGeolocationServiceObject);
244f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu}
245f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu
246f5d1fa4f87a7635b624d77d39bd258bed6b66cd8Andrei Popescu} // namespace WebCore
247