Commit bfac2c0f authored by Piotr Bialecki's avatar Piotr Bialecki Committed by Commit Bot

ARCore move: add interfaces to enable moving ArCoreJavaUtils

In order to allow us to move ArCoreJavaUtils (Java & C++
implementation) and ArImmersiveOverlay to components/webxr, we
need to introduce an interface that allows underlying layers to call
into chrome/'s compositor (required for DOM overlay to work properly).

Changes:
- add ArCompositorDelegate & ArCompositorDelegateProvider along with
their implementations for chrome/
- ArCoreJavaUtils now accepts an instance of
ArCompositorDelegateProvider that will be used when creating the
delegate (which, in turn, is fed into ArImmersiveOverlay)

Bug: 843374
Change-Id: I4665d8a110941164dbb626c77e18364f4ff1e4cb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2469397
Commit-Queue: Piotr Bialecki <bialpio@chromium.org>
Reviewed-by: default avatarAlexander Cooper <alcooper@chromium.org>
Reviewed-by: default avatarMichael Thiessen <mthiesse@chromium.org>
Cr-Commit-Position: refs/heads/master@{#817767}
parent 1be1ff8f
......@@ -392,7 +392,7 @@ specific_include_rules = {
"SuspendedTab\.java": [
"+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java",
],
"ArImmersiveOverlay\.java": [
"ArCompositorDelegateImpl\.java": [
"+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java",
],
"WebApkActivityCoordinator\.java": [
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.vr;
import android.view.MotionEvent;
import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.compositor.CompositorView;
import org.chromium.chrome.browser.compositor.CompositorViewHolder;
import org.chromium.components.webxr.ArCompositorDelegate;
import org.chromium.content_public.browser.WebContents;
/**
* Concrete, Chrome-specific implementation of ArCompositorDelegate interface.
*/
public class ArCompositorDelegateImpl implements ArCompositorDelegate {
private ChromeActivity mActivity;
private CompositorViewHolder mCompositorViewHolder;
private CompositorView mCompositorView;
ArCompositorDelegateImpl(WebContents webContents) {
mActivity = ChromeActivity.fromWebContents(webContents);
mCompositorViewHolder = mActivity.getCompositorViewHolder();
mCompositorView = mCompositorViewHolder.getCompositorView();
}
@Override
public void setOverlayImmersiveArMode(boolean enabled) {
mCompositorView.setOverlayImmersiveArMode(enabled);
}
@Override
public void dispatchTouchEvent(MotionEvent ev) {
mCompositorViewHolder.dispatchTouchEvent(ev);
}
}
\ No newline at end of file
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.vr;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.components.webxr.ArCompositorDelegate;
import org.chromium.components.webxr.ArCompositorDelegateProvider;
import org.chromium.content_public.browser.WebContents;
/**
* Concrete, Chrome-specific implementation of ArCompositorDelegateProvider interface.
*/
@JNINamespace("vr")
public class ArCompositorDelegateProviderImpl implements ArCompositorDelegateProvider {
@CalledByNative
public ArCompositorDelegateProviderImpl() {}
@Override
public ArCompositorDelegate create(WebContents webContents) {
return new ArCompositorDelegateImpl(webContents);
}
}
......@@ -4,6 +4,7 @@
package org.chromium.chrome.browser.vr;
import android.app.Activity;
import android.content.Context;
import android.view.Surface;
......@@ -16,7 +17,9 @@ import org.chromium.base.ThreadUtils;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.components.webxr.ArCompositorDelegateProvider;
import org.chromium.content_public.browser.WebContents;
import org.chromium.ui.base.WindowAndroid;
/**
* Provides ARCore classes access to java-related app functionality.
......@@ -44,6 +47,16 @@ public class ArCoreJavaUtils {
// session.
private static ArCoreJavaUtils sActiveSessionInstance;
// Helper, obtains android Activity out of passed in WebContents instance.
// Equivalent to ChromeActivity.fromWebContents(), but does not require that
// the resulting instance is a ChromeActivity.
public static Activity getActivity(final WebContents webContents) {
if (webContents == null) return null;
WindowAndroid window = webContents.getTopLevelNativeWindow();
if (window == null) return null;
return window.getActivity().get();
}
@CalledByNative
private static ArCoreJavaUtils create(long nativeArCoreJavaUtils) {
ThreadUtils.assertOnUiThread();
......@@ -74,11 +87,13 @@ public class ArCoreJavaUtils {
}
@CalledByNative
private void startSession(final WebContents webContents, boolean useOverlay) {
private void startSession(final ArCompositorDelegateProvider compositorDelegateProvider,
final WebContents webContents, boolean useOverlay) {
if (DEBUG_LOGS) Log.i(TAG, "startSession");
mArImmersiveOverlay = new ArImmersiveOverlay();
sActiveSessionInstance = this;
mArImmersiveOverlay.show(webContents, this, useOverlay);
mArImmersiveOverlay.show(
compositorDelegateProvider.create(webContents), webContents, this, useOverlay);
}
@CalledByNative
......
......@@ -24,8 +24,7 @@ import androidx.annotation.NonNull;
import org.chromium.base.Log;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.compositor.CompositorView;
import org.chromium.components.webxr.ArCompositorDelegate;
import org.chromium.content_public.browser.ScreenOrientationDelegate;
import org.chromium.content_public.browser.ScreenOrientationProvider;
import org.chromium.content_public.browser.WebContents;
......@@ -45,7 +44,8 @@ public class ArImmersiveOverlay
private static final boolean DEBUG_LOGS = false;
private ArCoreJavaUtils mArCoreJavaUtils;
private ChromeActivity mActivity;
private ArCompositorDelegate mArCompositorDelegate;
private Activity mActivity;
private boolean mSurfaceReportedReady;
private Integer mRestoreOrientation;
private boolean mCleanupInProgress;
......@@ -57,13 +57,15 @@ public class ArImmersiveOverlay
// ID of primary pointer (if present).
private Integer mPrimaryPointerId;
public void show(
public void show(@NonNull ArCompositorDelegate compositorDelegate,
@NonNull WebContents webContents, @NonNull ArCoreJavaUtils caller, boolean useOverlay) {
if (DEBUG_LOGS) Log.i(TAG, "constructor");
mArCoreJavaUtils = caller;
mWebContents = webContents;
mActivity = ChromeActivity.fromWebContents(webContents);
mArCompositorDelegate = compositorDelegate;
mActivity = ArCoreJavaUtils.getActivity(webContents);
mPointerIdToData = new HashMap<Integer, PointerData>();
mPrimaryPointerId = null;
......@@ -163,7 +165,6 @@ public class ArImmersiveOverlay
private class SurfaceUiCompositor implements SurfaceUiWrapper {
private SurfaceView mSurfaceView;
private CompositorView mCompositorView;
private WebContentsObserver mWebContentsObserver;
public SurfaceUiCompositor() {
......@@ -182,12 +183,12 @@ public class ArImmersiveOverlay
ViewGroup group = (ViewGroup) content.getParent();
group.addView(mSurfaceView);
mCompositorView = mActivity.getCompositorViewHolder().getCompositorView();
// Enable alpha channel for the compositor and make the background
// transparent. (A variant of CompositorView::SetOverlayVideoMode.)
if (DEBUG_LOGS) Log.i(TAG, "calling mCompositorView.setOverlayImmersiveArMode(true)");
mCompositorView.setOverlayImmersiveArMode(true);
if (DEBUG_LOGS) {
Log.i(TAG, "calling mArCompositorDelegate.setOverlayImmersiveArMode(true)");
}
mArCompositorDelegate.setOverlayImmersiveArMode(true);
mWebContentsObserver = new WebContentsObserver() {
@Override
......@@ -213,8 +214,7 @@ public class ArImmersiveOverlay
@Override // SurfaceUiWrapper
public void forwardMotionEvent(MotionEvent ev) {
View contentView = mActivity.getCompositorViewHolder();
contentView.dispatchTouchEvent(ev);
mArCompositorDelegate.dispatchTouchEvent(ev);
}
@Override // SurfaceUiWrapper
......@@ -224,7 +224,7 @@ public class ArImmersiveOverlay
ViewGroup group = (ViewGroup) content.getParent();
group.removeView(mSurfaceView);
mSurfaceView = null;
mCompositorView.setOverlayImmersiveArMode(false);
mArCompositorDelegate.setOverlayImmersiveArMode(false);
}
}
......
include_rules = [
"+components/webxr/android/java/src/org/chromium/components/webxr",
]
\ No newline at end of file
......@@ -42,6 +42,8 @@ chrome_junit_test_java_sources += share_junit_test_java_sources
if (enable_arcore) {
chrome_java_sources += [
"java/src/org/chromium/chrome/browser/vr/ArCompositorDelegateImpl.java",
"java/src/org/chromium/chrome/browser/vr/ArCompositorDelegateProviderImpl.java",
"java/src/org/chromium/chrome/browser/vr/ArCoreDeviceUtils.java",
"java/src/org/chromium/chrome/browser/vr/ArCoreJavaUtils.java",
"java/src/org/chromium/chrome/browser/vr/ArDelegateImpl.java",
......
......@@ -175,6 +175,7 @@ group("module_factory") {
if (enable_arcore) {
generate_jni("ar_jni_headers") {
sources = [
"//chrome/android/java/src/org/chromium/chrome/browser/vr/ArCompositorDelegateProviderImpl.java",
"//chrome/android/java/src/org/chromium/chrome/browser/vr/ArCoreDeviceUtils.java",
"//chrome/android/java/src/org/chromium/chrome/browser/vr/ArCoreJavaUtils.java",
]
......
......@@ -13,7 +13,9 @@
namespace device {
ArCoreDeviceProvider::ArCoreDeviceProvider() = default;
ArCoreDeviceProvider::ArCoreDeviceProvider(
webxr::ArCompositorDelegateProvider compositor_delegate_provider)
: compositor_delegate_provider_(compositor_delegate_provider) {}
ArCoreDeviceProvider::~ArCoreDeviceProvider() = default;
......@@ -27,11 +29,12 @@ void ArCoreDeviceProvider::Initialize(
base::OnceClosure initialization_complete) {
if (vr::IsArCoreSupported()) {
DVLOG(2) << __func__ << ": ARCore is supported, creating device";
arcore_device_ = std::make_unique<ArCoreDevice>(
std::make_unique<ArCoreImplFactory>(),
std::make_unique<ArImageTransportFactory>(),
std::make_unique<webxr::MailboxToSurfaceBridgeFactoryImpl>(),
std::make_unique<vr::ArCoreJavaUtils>());
std::make_unique<vr::ArCoreJavaUtils>(compositor_delegate_provider_));
add_device_callback.Run(
arcore_device_->GetId(), arcore_device_->GetVRDisplayInfo(),
......
......@@ -7,6 +7,7 @@
#include <memory>
#include "base/macros.h"
#include "components/webxr/android/ar_compositor_delegate_provider.h"
#include "device/vr/public/cpp/vr_device_provider.h"
#include "device/vr/vr_export.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
......@@ -17,7 +18,8 @@ class ArCoreDevice;
class ArCoreDeviceProvider : public VRDeviceProvider {
public:
ArCoreDeviceProvider();
explicit ArCoreDeviceProvider(
webxr::ArCompositorDelegateProvider compositor_delegate_provider);
~ArCoreDeviceProvider() override;
void Initialize(
base::RepeatingCallback<void(mojom::XRDeviceId,
......@@ -30,6 +32,8 @@ class ArCoreDeviceProvider : public VRDeviceProvider {
bool Initialized() override;
private:
webxr::ArCompositorDelegateProvider compositor_delegate_provider_;
std::unique_ptr<ArCoreDevice> arcore_device_;
bool initialized_ = false;
DISALLOW_COPY_AND_ASSIGN(ArCoreDeviceProvider);
......
......@@ -4,8 +4,10 @@
#include <memory>
#include "chrome/browser/android/vr/ar_jni_headers/ArCompositorDelegateProviderImpl_jni.h"
#include "chrome/browser/android/vr/ar_jni_headers/ArCoreDeviceUtils_jni.h"
#include "chrome/browser/android/vr/arcore_device/arcore_device_provider.h"
#include "components/webxr/android/ar_compositor_delegate_provider.h"
#include "device/vr/android/arcore/arcore_device_provider_factory.h"
namespace vr {
......@@ -24,7 +26,13 @@ class ArCoreDeviceProviderFactoryImpl
std::unique_ptr<device::VRDeviceProvider>
ArCoreDeviceProviderFactoryImpl::CreateDeviceProvider() {
return std::make_unique<device::ArCoreDeviceProvider>();
base::android::ScopedJavaLocalRef<jobject> j_ar_compositor_delegate_provider =
vr::Java_ArCompositorDelegateProviderImpl_Constructor(
base::android::AttachCurrentThread());
return std::make_unique<device::ArCoreDeviceProvider>(
webxr::ArCompositorDelegateProvider(
std::move(j_ar_compositor_delegate_provider)));
}
} // namespace
......
......@@ -17,7 +17,9 @@ using base::android::ScopedJavaLocalRef;
namespace vr {
ArCoreJavaUtils::ArCoreJavaUtils() {
ArCoreJavaUtils::ArCoreJavaUtils(
webxr::ArCompositorDelegateProvider compositor_delegate_provider)
: compositor_delegate_provider_(compositor_delegate_provider) {
JNIEnv* env = AttachCurrentThread();
if (!env)
return;
......@@ -48,7 +50,7 @@ void ArCoreJavaUtils::RequestArSession(
surface_destroyed_callback_ = std::move(destroyed_callback);
Java_ArCoreJavaUtils_startSession(
env, j_arcore_java_utils_,
env, j_arcore_java_utils_, compositor_delegate_provider_.GetJavaObject(),
webxr::GetJavaWebContents(render_process_id, render_frame_id),
use_overlay);
}
......
......@@ -11,13 +11,15 @@
#include "base/android/scoped_java_ref.h"
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "components/webxr/android/ar_compositor_delegate_provider.h"
#include "device/vr/android/arcore/arcore_session_utils.h"
namespace vr {
class ArCoreJavaUtils : public ArCoreSessionUtils {
public:
ArCoreJavaUtils();
explicit ArCoreJavaUtils(
webxr::ArCompositorDelegateProvider compositor_delegate_provider);
~ArCoreJavaUtils() override;
// ArCoreSessionUtils:
......@@ -53,6 +55,8 @@ class ArCoreJavaUtils : public ArCoreSessionUtils {
private:
base::android::ScopedJavaGlobalRef<jobject> j_arcore_java_utils_;
webxr::ArCompositorDelegateProvider compositor_delegate_provider_;
SurfaceReadyCallback surface_ready_callback_;
SurfaceTouchCallback surface_touch_callback_;
SurfaceDestroyedCallback surface_destroyed_callback_;
......
......@@ -21,6 +21,8 @@ source_set("android_utils") {
source_set("android") {
sources = [
"ar_compositor_delegate_provider.cc",
"ar_compositor_delegate_provider.h",
"xr_install_helper_delegate.h",
"xr_install_infobar.cc",
"xr_install_infobar.h",
......@@ -63,6 +65,8 @@ android_library("ar_java_base") {
]
sources = [
"//components/webxr/android/java/src/org/chromium/components/webxr/ArCompositorDelegate.java",
"//components/webxr/android/java/src/org/chromium/components/webxr/ArCompositorDelegateProvider.java",
"//components/webxr/android/java/src/org/chromium/components/webxr/ArCoreInstallUtils.java",
"//components/webxr/android/java/src/org/chromium/components/webxr/ArCoreShim.java",
]
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/webxr/android/ar_compositor_delegate_provider.h"
namespace webxr {
ArCompositorDelegateProvider::ArCompositorDelegateProvider(
base::android::JavaRef<jobject>&& j_compositor_delegate_provider)
: j_compositor_delegate_provider_(
std::move(j_compositor_delegate_provider)) {}
ArCompositorDelegateProvider::~ArCompositorDelegateProvider() = default;
ArCompositorDelegateProvider::ArCompositorDelegateProvider(
const ArCompositorDelegateProvider& other) = default;
ArCompositorDelegateProvider& ArCompositorDelegateProvider::operator=(
const ArCompositorDelegateProvider& other) = default;
base::android::ScopedJavaLocalRef<jobject>
ArCompositorDelegateProvider::GetJavaObject() const {
return base::android::ScopedJavaLocalRef<jobject>(
j_compositor_delegate_provider_);
}
} // namespace webxr
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_WEBXR_ANDROID_AR_COMPOSITOR_DELEGATE_PROVIDER_H_
#define COMPONENTS_WEBXR_ANDROID_AR_COMPOSITOR_DELEGATE_PROVIDER_H_
#include "base/android/scoped_java_ref.h"
namespace webxr {
// Wrapper around Java object that implements ArCompositorDelegateProvider
// interface (see ArCompositorDelegateProvider.java).
class ArCompositorDelegateProvider {
public:
explicit ArCompositorDelegateProvider(
base::android::JavaRef<jobject>&& j_compositor_delegate_provider);
~ArCompositorDelegateProvider();
ArCompositorDelegateProvider(const ArCompositorDelegateProvider& other);
ArCompositorDelegateProvider& operator=(
const ArCompositorDelegateProvider& other);
base::android::ScopedJavaLocalRef<jobject> GetJavaObject() const;
private:
base::android::ScopedJavaGlobalRef<jobject> j_compositor_delegate_provider_;
};
} // namespace webxr
#endif // COMPONENTS_WEBXR_ANDROID_AR_COMPOSITOR_DELEGATE_PROVIDER_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.components.webxr;
import android.view.MotionEvent;
/**
* Interface used by ArImmersiveOverlay to communicate with the underlying
* compositor. Used to implement WebXR's DOM Overlay mode correctly.
*/
public interface ArCompositorDelegate {
/**
* Enables/disables immersive AR mode in the compositor.
*/
void setOverlayImmersiveArMode(boolean enabled);
/**
* Dispatches a touch event that was consumed by the immersive AR overlay.
* This touch event should be propagated to the View where the DOM Overlay
* content is displayed so that it can react to the user's actions.
*/
void dispatchTouchEvent(MotionEvent ev);
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.components.webxr;
import org.chromium.content_public.browser.WebContents;
/**
* Interface used to create instances of ArCompositorDelegates, needed by
* ArImmersiveOverlay to work correctly for WebXR's DOM Overlay.
*/
public interface ArCompositorDelegateProvider {
ArCompositorDelegate create(WebContents webContents);
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment