Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / content / browser / geolocation / location_api_adapter_android.cc
blob2396b55d98597626b7633ee45d2297f8e5465314
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/geolocation/location_api_adapter_android.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/bind.h"
10 #include "base/location.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "content/browser/geolocation/location_provider_android.h"
13 #include "jni/LocationProviderAdapter_jni.h"
15 using base::android::AttachCurrentThread;
16 using base::android::CheckException;
17 using base::android::ClearException;
18 using content::AndroidLocationApiAdapter;
20 static void NewLocationAvailable(JNIEnv* env,
21 const JavaParamRef<jclass>&,
22 jdouble latitude,
23 jdouble longitude,
24 jdouble time_stamp,
25 jboolean has_altitude,
26 jdouble altitude,
27 jboolean has_accuracy,
28 jdouble accuracy,
29 jboolean has_heading,
30 jdouble heading,
31 jboolean has_speed,
32 jdouble speed) {
33 AndroidLocationApiAdapter::OnNewLocationAvailable(latitude, longitude,
34 time_stamp, has_altitude, altitude, has_accuracy, accuracy,
35 has_heading, heading, has_speed, speed);
38 static void NewErrorAvailable(JNIEnv* env,
39 const JavaParamRef<jclass>&,
40 const JavaParamRef<jstring>& message) {
41 AndroidLocationApiAdapter::OnNewErrorAvailable(env, message);
44 namespace content {
46 AndroidLocationApiAdapter::AndroidLocationApiAdapter()
47 : location_provider_(NULL) {
50 AndroidLocationApiAdapter::~AndroidLocationApiAdapter() {
51 CHECK(!location_provider_);
52 CHECK(!task_runner_.get());
53 CHECK(java_location_provider_android_object_.is_null());
56 bool AndroidLocationApiAdapter::Start(
57 LocationProviderAndroid* location_provider, bool high_accuracy) {
58 JNIEnv* env = AttachCurrentThread();
59 if (!location_provider_) {
60 location_provider_ = location_provider;
61 CHECK(java_location_provider_android_object_.is_null());
62 CreateJavaObject(env);
64 base::AutoLock lock(lock_);
65 CHECK(!task_runner_.get());
66 task_runner_ = base::ThreadTaskRunnerHandle::Get();
69 // At this point we should have all our pre-conditions ready, and they'd only
70 // change in Stop() which must be called on the same thread as here.
71 CHECK(location_provider_);
72 CHECK(task_runner_.get());
73 CHECK(!java_location_provider_android_object_.is_null());
74 // We'll start receiving notifications from java in the main thread looper
75 // until Stop() is called.
76 return Java_LocationProviderAdapter_start(env,
77 java_location_provider_android_object_.obj(), high_accuracy);
80 void AndroidLocationApiAdapter::Stop() {
81 if (!location_provider_) {
82 CHECK(!task_runner_.get());
83 CHECK(java_location_provider_android_object_.is_null());
84 return;
88 base::AutoLock lock(lock_);
89 task_runner_ = NULL;
92 location_provider_ = NULL;
94 JNIEnv* env = AttachCurrentThread();
95 Java_LocationProviderAdapter_stop(
96 env, java_location_provider_android_object_.obj());
97 java_location_provider_android_object_.Reset();
100 // static
101 void AndroidLocationApiAdapter::NotifyProviderNewGeoposition(
102 const Geoposition& geoposition) {
103 // Called on the geolocation thread, safe to access location_provider_ here.
104 if (GetInstance()->location_provider_) {
105 CHECK(GetInstance()->task_runner_->BelongsToCurrentThread());
106 GetInstance()->location_provider_->NotifyNewGeoposition(geoposition);
110 // static
111 void AndroidLocationApiAdapter::OnNewLocationAvailable(
112 double latitude, double longitude, double time_stamp,
113 bool has_altitude, double altitude,
114 bool has_accuracy, double accuracy,
115 bool has_heading, double heading,
116 bool has_speed, double speed) {
117 Geoposition position;
118 position.latitude = latitude;
119 position.longitude = longitude;
120 position.timestamp = base::Time::FromDoubleT(time_stamp);
121 if (has_altitude)
122 position.altitude = altitude;
123 if (has_accuracy)
124 position.accuracy = accuracy;
125 if (has_heading)
126 position.heading = heading;
127 if (has_speed)
128 position.speed = speed;
129 GetInstance()->OnNewGeopositionInternal(position);
132 // static
133 void AndroidLocationApiAdapter::OnNewErrorAvailable(JNIEnv* env,
134 jstring message) {
135 Geoposition position_error;
136 position_error.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
137 position_error.error_message =
138 base::android::ConvertJavaStringToUTF8(env, message);
139 GetInstance()->OnNewGeopositionInternal(position_error);
142 // static
143 AndroidLocationApiAdapter* AndroidLocationApiAdapter::GetInstance() {
144 return base::Singleton<AndroidLocationApiAdapter>::get();
147 // static
148 bool AndroidLocationApiAdapter::RegisterGeolocationService(JNIEnv* env) {
149 return RegisterNativesImpl(env);
152 void AndroidLocationApiAdapter::CreateJavaObject(JNIEnv* env) {
153 // Create the Java AndroidLocationProvider object.
154 java_location_provider_android_object_.Reset(
155 Java_LocationProviderAdapter_create(env,
156 base::android::GetApplicationContext()));
157 CHECK(!java_location_provider_android_object_.is_null());
160 void AndroidLocationApiAdapter::OnNewGeopositionInternal(
161 const Geoposition& geoposition) {
162 base::AutoLock lock(lock_);
163 if (!task_runner_.get())
164 return;
165 task_runner_->PostTask(
166 FROM_HERE,
167 base::Bind(&AndroidLocationApiAdapter::NotifyProviderNewGeoposition,
168 geoposition));
171 } // namespace content