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