location_api_adapter_android.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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. #include "services/device/geolocation/location_api_adapter_android.h"
  5. #include "base/android/jni_android.h"
  6. #include "base/android/jni_string.h"
  7. #include "base/bind.h"
  8. #include "base/location.h"
  9. #include "base/threading/thread_task_runner_handle.h"
  10. #include "base/time/time.h"
  11. #include "services/device/geolocation/geolocation_jni_headers/LocationProviderAdapter_jni.h"
  12. #include "services/device/geolocation/location_provider_android.h"
  13. using base::android::AttachCurrentThread;
  14. using base::android::JavaParamRef;
  15. using device::LocationApiAdapterAndroid;
  16. static void JNI_LocationProviderAdapter_NewLocationAvailable(
  17. JNIEnv* env,
  18. jdouble latitude,
  19. jdouble longitude,
  20. jdouble time_stamp,
  21. jboolean has_altitude,
  22. jdouble altitude,
  23. jboolean has_accuracy,
  24. jdouble accuracy,
  25. jboolean has_heading,
  26. jdouble heading,
  27. jboolean has_speed,
  28. jdouble speed) {
  29. LocationApiAdapterAndroid::OnNewLocationAvailable(
  30. latitude, longitude, time_stamp, has_altitude, altitude, has_accuracy,
  31. accuracy, has_heading, heading, has_speed, speed);
  32. }
  33. static void JNI_LocationProviderAdapter_NewErrorAvailable(
  34. JNIEnv* env,
  35. const JavaParamRef<jstring>& message) {
  36. LocationApiAdapterAndroid::OnNewErrorAvailable(env, message);
  37. }
  38. namespace device {
  39. void LocationApiAdapterAndroid::Start(OnGeopositionCB on_geoposition_callback,
  40. bool high_accuracy) {
  41. DCHECK(thread_checker_.CalledOnValidThread());
  42. DCHECK(on_geoposition_callback);
  43. JNIEnv* env = AttachCurrentThread();
  44. if (!on_geoposition_callback_) {
  45. on_geoposition_callback_ = on_geoposition_callback;
  46. DCHECK(java_location_provider_adapter_.is_null());
  47. java_location_provider_adapter_.Reset(
  48. Java_LocationProviderAdapter_create(env));
  49. }
  50. // At this point we should have all our pre-conditions ready, and they'd only
  51. // change in Stop() which must be called on the same thread as here. We'll
  52. // start receiving notifications from java in the main thread looper until
  53. // Stop() is called.
  54. DCHECK(!java_location_provider_adapter_.is_null());
  55. Java_LocationProviderAdapter_start(env, java_location_provider_adapter_,
  56. high_accuracy);
  57. }
  58. void LocationApiAdapterAndroid::Stop() {
  59. DCHECK(thread_checker_.CalledOnValidThread());
  60. if (!on_geoposition_callback_)
  61. return;
  62. on_geoposition_callback_.Reset();
  63. JNIEnv* env = AttachCurrentThread();
  64. Java_LocationProviderAdapter_stop(env, java_location_provider_adapter_);
  65. java_location_provider_adapter_.Reset();
  66. }
  67. // static
  68. void LocationApiAdapterAndroid::OnNewLocationAvailable(double latitude,
  69. double longitude,
  70. double time_stamp,
  71. bool has_altitude,
  72. double altitude,
  73. bool has_accuracy,
  74. double accuracy,
  75. bool has_heading,
  76. double heading,
  77. bool has_speed,
  78. double speed) {
  79. mojom::Geoposition position;
  80. position.latitude = latitude;
  81. position.longitude = longitude;
  82. position.timestamp = base::Time::FromDoubleT(time_stamp);
  83. if (has_altitude)
  84. position.altitude = altitude;
  85. if (has_accuracy)
  86. position.accuracy = accuracy;
  87. if (has_heading)
  88. position.heading = heading;
  89. if (has_speed)
  90. position.speed = speed;
  91. LocationApiAdapterAndroid* self = GetInstance();
  92. self->task_runner_->PostTask(
  93. FROM_HERE,
  94. base::BindOnce(&LocationApiAdapterAndroid::NotifyNewGeoposition,
  95. base::Unretained(self), position));
  96. }
  97. // static
  98. void LocationApiAdapterAndroid::OnNewErrorAvailable(JNIEnv* env,
  99. jstring message) {
  100. mojom::Geoposition position_error;
  101. position_error.error_code =
  102. mojom::Geoposition::ErrorCode::POSITION_UNAVAILABLE;
  103. position_error.error_message =
  104. base::android::ConvertJavaStringToUTF8(env, message);
  105. LocationApiAdapterAndroid* self = GetInstance();
  106. self->task_runner_->PostTask(
  107. FROM_HERE,
  108. base::BindOnce(&LocationApiAdapterAndroid::NotifyNewGeoposition,
  109. base::Unretained(self), position_error));
  110. }
  111. // static
  112. LocationApiAdapterAndroid* LocationApiAdapterAndroid::GetInstance() {
  113. return base::Singleton<LocationApiAdapterAndroid>::get();
  114. }
  115. LocationApiAdapterAndroid::LocationApiAdapterAndroid()
  116. : task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
  117. LocationApiAdapterAndroid::~LocationApiAdapterAndroid() {
  118. DCHECK(thread_checker_.CalledOnValidThread());
  119. }
  120. void LocationApiAdapterAndroid::NotifyNewGeoposition(
  121. const mojom::Geoposition& geoposition) {
  122. DCHECK(thread_checker_.CalledOnValidThread());
  123. if (on_geoposition_callback_)
  124. on_geoposition_callback_.Run(geoposition);
  125. }
  126. } // namespace device