| Index: content/browser/geolocation/location_api_adapter_android.cc
|
| diff --git a/content/browser/geolocation/location_api_adapter_android.cc b/content/browser/geolocation/location_api_adapter_android.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..980d1bda3ab95812b15173556f08c0e4885ea04a
|
| --- /dev/null
|
| +++ b/content/browser/geolocation/location_api_adapter_android.cc
|
| @@ -0,0 +1,172 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "content/browser/geolocation/location_api_adapter_android.h"
|
| +
|
| +#include "base/android/context_utils.h"
|
| +#include "base/android/jni_android.h"
|
| +#include "base/android/jni_string.h"
|
| +#include "base/bind.h"
|
| +#include "base/location.h"
|
| +#include "base/threading/thread_task_runner_handle.h"
|
| +#include "content/browser/geolocation/location_provider_android.h"
|
| +#include "jni/LocationProviderAdapter_jni.h"
|
| +
|
| +using base::android::AttachCurrentThread;
|
| +using base::android::CheckException;
|
| +using base::android::ClearException;
|
| +using content::AndroidLocationApiAdapter;
|
| +
|
| +static void NewLocationAvailable(JNIEnv* env,
|
| + const JavaParamRef<jclass>&,
|
| + jdouble latitude,
|
| + jdouble longitude,
|
| + jdouble time_stamp,
|
| + jboolean has_altitude,
|
| + jdouble altitude,
|
| + jboolean has_accuracy,
|
| + jdouble accuracy,
|
| + jboolean has_heading,
|
| + jdouble heading,
|
| + jboolean has_speed,
|
| + jdouble speed) {
|
| + AndroidLocationApiAdapter::OnNewLocationAvailable(latitude, longitude,
|
| + time_stamp, has_altitude, altitude, has_accuracy, accuracy,
|
| + has_heading, heading, has_speed, speed);
|
| +}
|
| +
|
| +static void NewErrorAvailable(JNIEnv* env,
|
| + const JavaParamRef<jclass>&,
|
| + const JavaParamRef<jstring>& message) {
|
| + AndroidLocationApiAdapter::OnNewErrorAvailable(env, message);
|
| +}
|
| +
|
| +namespace content {
|
| +
|
| +AndroidLocationApiAdapter::AndroidLocationApiAdapter()
|
| + : location_provider_(NULL) {
|
| +}
|
| +
|
| +AndroidLocationApiAdapter::~AndroidLocationApiAdapter() {
|
| + CHECK(!location_provider_);
|
| + CHECK(!task_runner_.get());
|
| + CHECK(java_location_provider_android_object_.is_null());
|
| +}
|
| +
|
| +bool AndroidLocationApiAdapter::Start(
|
| + LocationProviderAndroid* location_provider, bool high_accuracy) {
|
| + JNIEnv* env = AttachCurrentThread();
|
| + if (!location_provider_) {
|
| + location_provider_ = location_provider;
|
| + CHECK(java_location_provider_android_object_.is_null());
|
| + CreateJavaObject(env);
|
| + {
|
| + base::AutoLock lock(lock_);
|
| + CHECK(!task_runner_.get());
|
| + task_runner_ = base::ThreadTaskRunnerHandle::Get();
|
| + }
|
| + }
|
| + // At this point we should have all our pre-conditions ready, and they'd only
|
| + // change in Stop() which must be called on the same thread as here.
|
| + CHECK(location_provider_);
|
| + CHECK(task_runner_.get());
|
| + CHECK(!java_location_provider_android_object_.is_null());
|
| + // We'll start receiving notifications from java in the main thread looper
|
| + // until Stop() is called.
|
| + return Java_LocationProviderAdapter_start(env,
|
| + java_location_provider_android_object_.obj(), high_accuracy);
|
| +}
|
| +
|
| +void AndroidLocationApiAdapter::Stop() {
|
| + if (!location_provider_) {
|
| + CHECK(!task_runner_.get());
|
| + CHECK(java_location_provider_android_object_.is_null());
|
| + return;
|
| + }
|
| +
|
| + {
|
| + base::AutoLock lock(lock_);
|
| + task_runner_ = NULL;
|
| + }
|
| +
|
| + location_provider_ = NULL;
|
| +
|
| + JNIEnv* env = AttachCurrentThread();
|
| + Java_LocationProviderAdapter_stop(
|
| + env, java_location_provider_android_object_.obj());
|
| + java_location_provider_android_object_.Reset();
|
| +}
|
| +
|
| +// static
|
| +void AndroidLocationApiAdapter::NotifyProviderNewGeoposition(
|
| + const Geoposition& geoposition) {
|
| + // Called on the geolocation thread, safe to access location_provider_ here.
|
| + if (GetInstance()->location_provider_) {
|
| + CHECK(GetInstance()->task_runner_->BelongsToCurrentThread());
|
| + GetInstance()->location_provider_->NotifyNewGeoposition(geoposition);
|
| + }
|
| +}
|
| +
|
| +// static
|
| +void AndroidLocationApiAdapter::OnNewLocationAvailable(
|
| + double latitude, double longitude, double time_stamp,
|
| + bool has_altitude, double altitude,
|
| + bool has_accuracy, double accuracy,
|
| + bool has_heading, double heading,
|
| + bool has_speed, double speed) {
|
| + Geoposition position;
|
| + position.latitude = latitude;
|
| + position.longitude = longitude;
|
| + position.timestamp = base::Time::FromDoubleT(time_stamp);
|
| + if (has_altitude)
|
| + position.altitude = altitude;
|
| + if (has_accuracy)
|
| + position.accuracy = accuracy;
|
| + if (has_heading)
|
| + position.heading = heading;
|
| + if (has_speed)
|
| + position.speed = speed;
|
| + GetInstance()->OnNewGeopositionInternal(position);
|
| +}
|
| +
|
| +// static
|
| +void AndroidLocationApiAdapter::OnNewErrorAvailable(JNIEnv* env,
|
| + jstring message) {
|
| + Geoposition position_error;
|
| + position_error.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
|
| + position_error.error_message =
|
| + base::android::ConvertJavaStringToUTF8(env, message);
|
| + GetInstance()->OnNewGeopositionInternal(position_error);
|
| +}
|
| +
|
| +// static
|
| +AndroidLocationApiAdapter* AndroidLocationApiAdapter::GetInstance() {
|
| + return base::Singleton<AndroidLocationApiAdapter>::get();
|
| +}
|
| +
|
| +// static
|
| +bool AndroidLocationApiAdapter::RegisterGeolocationService(JNIEnv* env) {
|
| + return RegisterNativesImpl(env);
|
| +}
|
| +
|
| +void AndroidLocationApiAdapter::CreateJavaObject(JNIEnv* env) {
|
| + // Create the Java LocationProviderAdapter object.
|
| + java_location_provider_android_object_.Reset(
|
| + Java_LocationProviderAdapter_create(env,
|
| + base::android::GetApplicationContext()));
|
| + CHECK(!java_location_provider_android_object_.is_null());
|
| +}
|
| +
|
| +void AndroidLocationApiAdapter::OnNewGeopositionInternal(
|
| + const Geoposition& geoposition) {
|
| + base::AutoLock lock(lock_);
|
| + if (!task_runner_.get())
|
| + return;
|
| + task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&AndroidLocationApiAdapter::NotifyProviderNewGeoposition,
|
| + geoposition));
|
| +}
|
| +
|
| +} // namespace content
|
|
|