OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "content/browser/geolocation/location_api_adapter_android.h" | |
6 | |
7 #include "base/android/context_utils.h" | |
8 #include "base/android/jni_android.h" | |
9 #include "base/android/jni_string.h" | |
10 #include "base/bind.h" | |
11 #include "base/location.h" | |
12 #include "base/threading/thread_task_runner_handle.h" | |
13 #include "content/browser/geolocation/location_provider_android.h" | |
14 #include "jni/LocationProviderAdapter_jni.h" | |
15 | |
16 using base::android::AttachCurrentThread; | |
17 using base::android::CheckException; | |
18 using base::android::ClearException; | |
19 using content::AndroidLocationApiAdapter; | |
20 | |
21 static void NewLocationAvailable(JNIEnv* env, | |
22 const JavaParamRef<jclass>&, | |
23 jdouble latitude, | |
24 jdouble longitude, | |
25 jdouble time_stamp, | |
26 jboolean has_altitude, | |
27 jdouble altitude, | |
28 jboolean has_accuracy, | |
29 jdouble accuracy, | |
30 jboolean has_heading, | |
31 jdouble heading, | |
32 jboolean has_speed, | |
33 jdouble speed) { | |
34 AndroidLocationApiAdapter::OnNewLocationAvailable(latitude, longitude, | |
35 time_stamp, has_altitude, altitude, has_accuracy, accuracy, | |
36 has_heading, heading, has_speed, speed); | |
37 } | |
38 | |
39 static void NewErrorAvailable(JNIEnv* env, | |
40 const JavaParamRef<jclass>&, | |
41 const JavaParamRef<jstring>& message) { | |
42 AndroidLocationApiAdapter::OnNewErrorAvailable(env, message); | |
43 } | |
44 | |
45 namespace content { | |
46 | |
47 AndroidLocationApiAdapter::AndroidLocationApiAdapter() | |
48 : location_provider_(NULL) { | |
49 } | |
50 | |
51 AndroidLocationApiAdapter::~AndroidLocationApiAdapter() { | |
52 CHECK(!location_provider_); | |
53 CHECK(!task_runner_.get()); | |
54 CHECK(java_location_provider_android_object_.is_null()); | |
55 } | |
56 | |
57 bool AndroidLocationApiAdapter::Start( | |
58 LocationProviderAndroid* location_provider, bool high_accuracy) { | |
59 JNIEnv* env = AttachCurrentThread(); | |
60 if (!location_provider_) { | |
61 location_provider_ = location_provider; | |
62 CHECK(java_location_provider_android_object_.is_null()); | |
63 CreateJavaObject(env); | |
64 { | |
65 base::AutoLock lock(lock_); | |
66 CHECK(!task_runner_.get()); | |
67 task_runner_ = base::ThreadTaskRunnerHandle::Get(); | |
68 } | |
69 } | |
70 // At this point we should have all our pre-conditions ready, and they'd only | |
71 // change in Stop() which must be called on the same thread as here. | |
72 CHECK(location_provider_); | |
73 CHECK(task_runner_.get()); | |
74 CHECK(!java_location_provider_android_object_.is_null()); | |
75 // We'll start receiving notifications from java in the main thread looper | |
76 // until Stop() is called. | |
77 return Java_LocationProviderAdapter_start(env, | |
78 java_location_provider_android_object_.obj(), high_accuracy); | |
79 } | |
80 | |
81 void AndroidLocationApiAdapter::Stop() { | |
82 if (!location_provider_) { | |
83 CHECK(!task_runner_.get()); | |
84 CHECK(java_location_provider_android_object_.is_null()); | |
85 return; | |
86 } | |
87 | |
88 { | |
89 base::AutoLock lock(lock_); | |
90 task_runner_ = NULL; | |
91 } | |
92 | |
93 location_provider_ = NULL; | |
94 | |
95 JNIEnv* env = AttachCurrentThread(); | |
96 Java_LocationProviderAdapter_stop( | |
97 env, java_location_provider_android_object_.obj()); | |
98 java_location_provider_android_object_.Reset(); | |
99 } | |
100 | |
101 // static | |
102 void AndroidLocationApiAdapter::NotifyProviderNewGeoposition( | |
103 const Geoposition& geoposition) { | |
104 // Called on the geolocation thread, safe to access location_provider_ here. | |
105 if (GetInstance()->location_provider_) { | |
106 CHECK(GetInstance()->task_runner_->BelongsToCurrentThread()); | |
107 GetInstance()->location_provider_->NotifyNewGeoposition(geoposition); | |
108 } | |
109 } | |
110 | |
111 // static | |
112 void AndroidLocationApiAdapter::OnNewLocationAvailable( | |
113 double latitude, double longitude, double time_stamp, | |
114 bool has_altitude, double altitude, | |
115 bool has_accuracy, double accuracy, | |
116 bool has_heading, double heading, | |
117 bool has_speed, double speed) { | |
118 Geoposition position; | |
119 position.latitude = latitude; | |
120 position.longitude = longitude; | |
121 position.timestamp = base::Time::FromDoubleT(time_stamp); | |
122 if (has_altitude) | |
123 position.altitude = altitude; | |
124 if (has_accuracy) | |
125 position.accuracy = accuracy; | |
126 if (has_heading) | |
127 position.heading = heading; | |
128 if (has_speed) | |
129 position.speed = speed; | |
130 GetInstance()->OnNewGeopositionInternal(position); | |
131 } | |
132 | |
133 // static | |
134 void AndroidLocationApiAdapter::OnNewErrorAvailable(JNIEnv* env, | |
135 jstring message) { | |
136 Geoposition position_error; | |
137 position_error.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; | |
138 position_error.error_message = | |
139 base::android::ConvertJavaStringToUTF8(env, message); | |
140 GetInstance()->OnNewGeopositionInternal(position_error); | |
141 } | |
142 | |
143 // static | |
144 AndroidLocationApiAdapter* AndroidLocationApiAdapter::GetInstance() { | |
145 return base::Singleton<AndroidLocationApiAdapter>::get(); | |
146 } | |
147 | |
148 // static | |
149 bool AndroidLocationApiAdapter::RegisterGeolocationService(JNIEnv* env) { | |
150 return RegisterNativesImpl(env); | |
151 } | |
152 | |
153 void AndroidLocationApiAdapter::CreateJavaObject(JNIEnv* env) { | |
154 // Create the Java LocationProviderAdapter object. | |
155 java_location_provider_android_object_.Reset( | |
156 Java_LocationProviderAdapter_create(env, | |
157 base::android::GetApplicationContext())); | |
158 CHECK(!java_location_provider_android_object_.is_null()); | |
159 } | |
160 | |
161 void AndroidLocationApiAdapter::OnNewGeopositionInternal( | |
162 const Geoposition& geoposition) { | |
163 base::AutoLock lock(lock_); | |
164 if (!task_runner_.get()) | |
165 return; | |
166 task_runner_->PostTask( | |
167 FROM_HERE, | |
168 base::Bind(&AndroidLocationApiAdapter::NotifyProviderNewGeoposition, | |
169 geoposition)); | |
170 } | |
171 | |
172 } // namespace content | |
OLD | NEW |