arcore_java_utils.cc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // Copyright 2018 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 "components/webxr/android/arcore_java_utils.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "base/android/jni_string.h"
  8. #include "components/webxr/android/ar_jni_headers/ArCoreJavaUtils_jni.h"
  9. #include "components/webxr/android/webxr_utils.h"
  10. #include "device/vr/android/arcore/arcore_shim.h"
  11. #include "gpu/ipc/common/gpu_surface_tracker.h"
  12. #include "ui/android/window_android.h"
  13. using base::android::AttachCurrentThread;
  14. using base::android::ScopedJavaLocalRef;
  15. namespace webxr {
  16. ArCoreJavaUtils::ArCoreJavaUtils(
  17. webxr::ArCompositorDelegateProvider compositor_delegate_provider)
  18. : compositor_delegate_provider_(compositor_delegate_provider) {
  19. JNIEnv* env = AttachCurrentThread();
  20. if (!env)
  21. return;
  22. ScopedJavaLocalRef<jobject> j_arcore_java_utils =
  23. Java_ArCoreJavaUtils_create(env, (jlong)this);
  24. if (j_arcore_java_utils.is_null())
  25. return;
  26. j_arcore_java_utils_.Reset(j_arcore_java_utils);
  27. }
  28. ArCoreJavaUtils::~ArCoreJavaUtils() {
  29. JNIEnv* env = AttachCurrentThread();
  30. Java_ArCoreJavaUtils_onNativeDestroy(env, j_arcore_java_utils_);
  31. }
  32. void ArCoreJavaUtils::RequestArSession(
  33. int render_process_id,
  34. int render_frame_id,
  35. bool use_overlay,
  36. bool can_render_dom_content,
  37. device::SurfaceReadyCallback ready_callback,
  38. device::SurfaceTouchCallback touch_callback,
  39. device::SurfaceDestroyedCallback destroyed_callback) {
  40. DVLOG(1) << __func__;
  41. JNIEnv* env = AttachCurrentThread();
  42. surface_ready_callback_ = std::move(ready_callback);
  43. surface_touch_callback_ = std::move(touch_callback);
  44. surface_destroyed_callback_ = std::move(destroyed_callback);
  45. Java_ArCoreJavaUtils_startSession(
  46. env, j_arcore_java_utils_, compositor_delegate_provider_.GetJavaObject(),
  47. webxr::GetJavaWebContents(render_process_id, render_frame_id),
  48. use_overlay, can_render_dom_content);
  49. }
  50. void ArCoreJavaUtils::EndSession() {
  51. DVLOG(1) << __func__;
  52. JNIEnv* env = AttachCurrentThread();
  53. Java_ArCoreJavaUtils_endSession(env, j_arcore_java_utils_);
  54. }
  55. void ArCoreJavaUtils::OnDrawingSurfaceReady(
  56. JNIEnv* env,
  57. const base::android::JavaParamRef<jobject>& obj,
  58. const base::android::JavaParamRef<jobject>& surface,
  59. const base::android::JavaParamRef<jobject>& java_root_window,
  60. int rotation,
  61. int width,
  62. int height) {
  63. DVLOG(1) << __func__ << ": width=" << width << " height=" << height
  64. << " rotation=" << rotation;
  65. gfx::AcceleratedWidget window =
  66. ANativeWindow_fromSurface(base::android::AttachCurrentThread(), surface);
  67. gpu::SurfaceHandle surface_handle =
  68. gpu::GpuSurfaceTracker::Get()->AddSurfaceForNativeWidget(
  69. gpu::GpuSurfaceTracker::SurfaceRecord(
  70. window, surface, /*can_be_used_with_surface_control=*/false));
  71. ui::WindowAndroid* root_window =
  72. ui::WindowAndroid::FromJavaWindowAndroid(java_root_window);
  73. display::Display::Rotation display_rotation =
  74. static_cast<display::Display::Rotation>(rotation);
  75. surface_ready_callback_.Run(window, surface_handle, root_window,
  76. display_rotation, {width, height});
  77. }
  78. void ArCoreJavaUtils::OnDrawingSurfaceTouch(
  79. JNIEnv* env,
  80. const base::android::JavaParamRef<jobject>& obj,
  81. bool primary,
  82. bool touching,
  83. int32_t pointer_id,
  84. float x,
  85. float y) {
  86. DVLOG(3) << __func__ << ": pointer_id=" << pointer_id
  87. << " primary=" << primary << " touching=" << touching;
  88. surface_touch_callback_.Run(primary, touching, pointer_id, {x, y});
  89. }
  90. void ArCoreJavaUtils::OnDrawingSurfaceDestroyed(
  91. JNIEnv* env,
  92. const base::android::JavaParamRef<jobject>& obj) {
  93. DVLOG(1) << __func__ << ":::";
  94. if (surface_destroyed_callback_) {
  95. std::move(surface_destroyed_callback_).Run();
  96. }
  97. }
  98. bool ArCoreJavaUtils::EnsureLoaded() {
  99. DCHECK(device::IsArCoreSupported());
  100. JNIEnv* env = AttachCurrentThread();
  101. // TODO(crbug.com/884780): Allow loading the ARCore shim by name instead of by
  102. // absolute path.
  103. ScopedJavaLocalRef<jstring> java_path =
  104. Java_ArCoreJavaUtils_getArCoreShimLibraryPath(env);
  105. // Crash in debug builds if `java_path` is a null pointer but handle this
  106. // situation in release builds. This is done by design - the `java_path` will
  107. // be null only if there was a regression introduced to our gn/gni files w/o
  108. // causing a build break. In release builds, this approach will result in the
  109. // site not being able to request an AR session.
  110. DCHECK(java_path)
  111. << "Unable to find path to ARCore SDK library - please ensure that "
  112. "loadable_modules and secondary_abi_loadable_modules are set "
  113. "correctly when building";
  114. if (!java_path) {
  115. LOG(ERROR) << "Unable to find path to ARCore SDK library";
  116. return false;
  117. }
  118. return device::LoadArCoreSdk(
  119. base::android::ConvertJavaStringToUTF8(env, java_path));
  120. }
  121. ScopedJavaLocalRef<jobject> ArCoreJavaUtils::GetApplicationContext() {
  122. JNIEnv* env = AttachCurrentThread();
  123. return Java_ArCoreJavaUtils_getApplicationContext(env);
  124. }
  125. } // namespace webxr