Commit 29f357a0 authored by Suman Nelson Kancherla's avatar Suman Nelson Kancherla Committed by Commit Bot

Moved ArCore's module install to ArConsentDialog.

This is a no-op. All that is done is to separate DFM and ArCore install
into a separate class and call the install API from consent dialog instead
of from ArCoreDevice.

Bug: 907591
Change-Id: I742db94cf896a4955d4de1938d7323d19a04664e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1694401Reviewed-by: default avatarMichael Thiessen <mthiesse@chromium.org>
Reviewed-by: default avatarTibor Goldschwendt <tiborg@chromium.org>
Reviewed-by: default avatarPiotr Bialecki <bialpio@chromium.org>
Commit-Queue: Suman Kancherla <sumankancherla@chromium.org>
Cr-Commit-Position: refs/heads/master@{#676543}
parent 21a01ed8
......@@ -142,6 +142,6 @@ public class ArConsentDialog implements ModalDialogProperties.Controller {
@NativeMethods
/* package */ interface Natives {
void onUserConsentResult(long nativeArcoreConsentPrompt, boolean allowed);
void onUserConsentResult(long nativeArCoreConsentPrompt, boolean allowed);
}
}
// Copyright 2019 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.app.Activity;
import org.chromium.base.BundleUtils;
import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.infobar.InfoBarIdentifier;
import org.chromium.chrome.browser.infobar.SimpleConfirmInfoBarBuilder;
import org.chromium.chrome.browser.modules.ModuleInstallUi;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.components.module_installer.ModuleInstaller;
/**
* Installs AR DFM and ArCore runtimes.
*/
@JNINamespace("vr")
public class ArCoreInstallUtils implements ModuleInstallUi.FailureUiListener {
private static final String TAG = "ArCoreInstallUtils";
private long mNativeArCoreInstallUtils;
private Tab mTab;
// Instance that requested installation of ARCore.
// Should be non-null only if there is a pending request to install ARCore.
private static ArCoreInstallUtils sRequestInstallInstance;
// Cached ArCoreShim instance - valid only after AR module was installed and
// getArCoreShimInstance() was called.
private static ArCoreShim sArCoreInstance;
private static ArCoreShim getArCoreShimInstance() {
if (sArCoreInstance != null) return sArCoreInstance;
try {
sArCoreInstance =
(ArCoreShim) Class.forName("org.chromium.chrome.browser.vr.ArCoreShimImpl")
.newInstance();
} catch (ClassNotFoundException e) {
// shouldn't happen - we should only call this method once AR module is installed.
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
return sArCoreInstance;
}
private ArCoreInstallUtils(long nativeArCoreInstallUtils) {
mNativeArCoreInstallUtils = nativeArCoreInstallUtils;
// Need to be called before trying to access the AR module.
ModuleInstaller.init();
}
@Override
public void onRetry() {
if (mNativeArCoreInstallUtils == 0) return;
requestInstallArModule(mTab);
}
@Override
public void onCancel() {
if (mNativeArCoreInstallUtils == 0) return;
ArCoreInstallUtilsJni.get().onRequestInstallArModuleResult(
mNativeArCoreInstallUtils, false);
}
@CalledByNative
private boolean canRequestInstallArModule() {
// We can only try to install the AR module if we are in a bundle mode.
return BundleUtils.isBundle();
}
@CalledByNative
private boolean shouldRequestInstallArModule() {
try {
// Try to find class in AR module that has not been obfuscated.
Class.forName("com.google.ar.core.ArCoreApk");
return false;
} catch (ClassNotFoundException e) {
return true;
}
}
@CalledByNative
private void requestInstallArModule(Tab tab) {
mTab = tab;
ModuleInstallUi ui = new ModuleInstallUi(mTab, R.string.ar_module_title, this);
ui.showInstallStartUi();
ModuleInstaller.install("ar", success -> {
assert shouldRequestInstallArModule() != success;
if (success) {
// As per documentation, it's recommended to issue a call to
// ArCoreApk.checkAvailability() early in application lifecycle & ignore the result
// so that subsequent calls can return cached result:
// https://developers.google.com/ar/develop/java/enable-arcore
// This is as early in the app lifecycle as it gets for us - just after installing
// AR module.
getArCoreInstallStatus();
}
if (mNativeArCoreInstallUtils != 0) {
if (success) {
ui.showInstallSuccessUi();
ArCoreInstallUtilsJni.get().onRequestInstallArModuleResult(
mNativeArCoreInstallUtils, success);
} else {
ui.showInstallFailureUi();
// early exit - user will be offered a choice to retry & install flow will
// continue from onRetry / onCancel
return;
}
}
});
}
private @ArCoreShim.Availability int getArCoreInstallStatus() {
return getArCoreShimInstance().checkAvailability(ContextUtils.getApplicationContext());
}
@CalledByNative
private boolean shouldRequestInstallSupportedArCore() {
@ArCoreShim.Availability
int availability = getArCoreInstallStatus();
// Skip ARCore installation if we are certain that it is already installed.
// In all other cases, we might as well try to install it and handle installation failures.
return availability != ArCoreShim.Availability.SUPPORTED_INSTALLED;
}
@CalledByNative
private void requestInstallSupportedArCore(final Tab tab) {
assert shouldRequestInstallSupportedArCore();
@ArCoreShim.Availability
int arCoreAvailability = getArCoreInstallStatus();
final Activity activity = tab.getActivity();
String infobarText = null;
String buttonText = null;
switch (arCoreAvailability) {
case ArCoreShim.Availability.UNSUPPORTED_DEVICE_NOT_CAPABLE:
maybeNotifyNativeOnRequestInstallSupportedArCoreResult(false);
break;
case ArCoreShim.Availability.UNKNOWN_CHECKING:
case ArCoreShim.Availability.UNKNOWN_ERROR:
case ArCoreShim.Availability.UNKNOWN_TIMED_OUT:
case ArCoreShim.Availability.SUPPORTED_NOT_INSTALLED:
infobarText = activity.getString(R.string.ar_core_check_infobar_install_text);
buttonText = activity.getString(R.string.app_banner_install);
break;
case ArCoreShim.Availability.SUPPORTED_APK_TOO_OLD:
infobarText = activity.getString(R.string.ar_core_check_infobar_update_text);
buttonText = activity.getString(R.string.update_from_market);
break;
case ArCoreShim.Availability.SUPPORTED_INSTALLED:
assert false;
break;
}
SimpleConfirmInfoBarBuilder.Listener listener = new SimpleConfirmInfoBarBuilder.Listener() {
@Override
public void onInfoBarDismissed() {
maybeNotifyNativeOnRequestInstallSupportedArCoreResult(
!shouldRequestInstallSupportedArCore());
}
@Override
public boolean onInfoBarButtonClicked(boolean isPrimary) {
try {
assert sRequestInstallInstance == null;
@ArCoreShim.InstallStatus
int installStatus = getArCoreShimInstance().requestInstall(activity, true);
if (installStatus == ArCoreShim.InstallStatus.INSTALL_REQUESTED) {
// Install flow will resume in onArCoreRequestInstallReturned, mark that
// there is active request. Native code notification will be deferred until
// our activity gets resumed.
sRequestInstallInstance = ArCoreInstallUtils.this;
} else if (installStatus == ArCoreShim.InstallStatus.INSTALLED) {
// No need to install - notify native code.
maybeNotifyNativeOnRequestInstallSupportedArCoreResult(true);
}
} catch (ArCoreShim.UnavailableDeviceNotCompatibleException e) {
sRequestInstallInstance = null;
Log.w(TAG, "ARCore installation request failed with exception: %s",
e.toString());
maybeNotifyNativeOnRequestInstallSupportedArCoreResult(false);
} catch (ArCoreShim.UnavailableUserDeclinedInstallationException e) {
maybeNotifyNativeOnRequestInstallSupportedArCoreResult(false);
}
return false;
}
@Override
public boolean onInfoBarLinkClicked() {
return false;
}
};
// TODO(ijamardo, https://crbug.com/838833): Add icon for AR info bar.
SimpleConfirmInfoBarBuilder.create(tab, listener, InfoBarIdentifier.AR_CORE_UPGRADE_ANDROID,
R.drawable.ic_error_outline_googblue_24dp, infobarText, buttonText, null, null,
true);
}
/**
* Helper used to notify native code about the result of the request to install ARCore.
*/
private void maybeNotifyNativeOnRequestInstallSupportedArCoreResult(boolean success) {
if (mNativeArCoreInstallUtils != 0) {
ArCoreInstallUtilsJni.get().onRequestInstallSupportedArCoreResult(
mNativeArCoreInstallUtils, success);
}
}
private void onArCoreRequestInstallReturned(Activity activity) {
try {
// Since |userRequestedInstall| parameter is false, the below call should
// throw if ARCore is still not installed - no need to check the result.
getArCoreShimInstance().requestInstall(activity, false);
maybeNotifyNativeOnRequestInstallSupportedArCoreResult(true);
} catch (ArCoreShim.UnavailableDeviceNotCompatibleException e) {
Log.w(TAG, "Exception thrown when trying to validate install state of ARCore: %s",
e.toString());
maybeNotifyNativeOnRequestInstallSupportedArCoreResult(false);
} catch (ArCoreShim.UnavailableUserDeclinedInstallationException e) {
maybeNotifyNativeOnRequestInstallSupportedArCoreResult(false);
}
}
/**
* This method should be called by the Activity that gets resumed.
* We are only interested in the cases where our current Activity got paused
* as a result of a call to ArCoreApk.requestInstall() method.
*/
public static void onResumeActivityWithNative(Activity activity) {
if (sRequestInstallInstance != null) {
sRequestInstallInstance.onArCoreRequestInstallReturned(activity);
sRequestInstallInstance = null;
}
}
public static void installArCoreDeviceProviderFactory() {
ArCoreInstallUtilsJni.get().installArCoreDeviceProviderFactory();
}
@NativeMethods
/* package */ interface ArConsentPromptNative {
void onRequestInstallArModuleResult(long nativeArCoreConsentPrompt, boolean success);
void onRequestInstallSupportedArCoreResult(long nativeArCoreConsentPrompt, boolean success);
void installArCoreDeviceProviderFactory();
}
}
......@@ -4,81 +4,31 @@
package org.chromium.chrome.browser.vr;
import android.app.Activity;
import android.content.Context;
import android.view.Surface;
import dalvik.system.BaseDexClassLoader;
import org.chromium.base.BundleUtils;
import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
import org.chromium.base.StrictModeContext;
import org.chromium.base.ThreadUtils;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.infobar.InfoBarIdentifier;
import org.chromium.chrome.browser.infobar.SimpleConfirmInfoBarBuilder;
import org.chromium.chrome.browser.modules.ModuleInstallUi;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.components.module_installer.ModuleInstaller;
/**
* Provides ARCore classes access to java-related app functionality.
*/
@JNINamespace("vr")
public class ArCoreJavaUtils implements ModuleInstallUi.FailureUiListener {
public class ArCoreJavaUtils {
private static final String TAG = "ArCoreJavaUtils";
private static final boolean DEBUG_LOGS = false;
private long mNativeArCoreJavaUtils;
private boolean mAppInfoInitialized;
private Tab mTab;
private ArImmersiveOverlay mArImmersiveOverlay;
// Instance that requested installation of ARCore.
// Should be non-null only if there is a pending request to install ARCore.
private static ArCoreJavaUtils sRequestInstallInstance;
// Cached ArCoreShim instance - valid only after AR module was installed and
// getArCoreShimInstance() was called.
private static ArCoreShim sArCoreInstance;
private static ArCoreShim getArCoreShimInstance() {
if (sArCoreInstance != null) return sArCoreInstance;
try {
sArCoreInstance =
(ArCoreShim) Class.forName("org.chromium.chrome.browser.vr.ArCoreShimImpl")
.newInstance();
} catch (ClassNotFoundException e) {
// shouldn't happen - we should only call this method once AR module is installed.
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
return sArCoreInstance;
}
public static void installArCoreDeviceProviderFactory() {
nativeInstallArCoreDeviceProviderFactory();
}
/**
* Gets the current application context.
*
* @return Context The application context.
*/
@CalledByNative
private static Context getApplicationContext() {
return ContextUtils.getApplicationContext();
}
@CalledByNative
private static ArCoreJavaUtils create(long nativeArCoreJavaUtils) {
ThreadUtils.assertOnUiThread();
......@@ -93,22 +43,19 @@ public class ArCoreJavaUtils implements ModuleInstallUi.FailureUiListener {
}
}
@Override
public void onRetry() {
if (mNativeArCoreJavaUtils == 0) return;
requestInstallArModule(mTab);
}
@Override
public void onCancel() {
if (mNativeArCoreJavaUtils == 0) return;
nativeOnRequestInstallArModuleResult(mNativeArCoreJavaUtils, /* success = */ false);
/**
* Gets the current application context.
*
* @return Context The application context.
*/
@CalledByNative
private static Context getApplicationContext() {
return ContextUtils.getApplicationContext();
}
private ArCoreJavaUtils(long nativeArCoreJavaUtils) {
if (DEBUG_LOGS) Log.i(TAG, "constructor, nativeArCoreJavaUtils=" + nativeArCoreJavaUtils);
mNativeArCoreJavaUtils = nativeArCoreJavaUtils;
initializeAppInfo();
}
@CalledByNative
......@@ -151,194 +98,6 @@ public class ArCoreJavaUtils implements ModuleInstallUi.FailureUiListener {
mNativeArCoreJavaUtils = 0;
}
private void initializeAppInfo() {
mAppInfoInitialized = true;
// Need to be called before trying to access the AR module.
ModuleInstaller.init();
}
private @ArCoreShim.Availability int getArCoreInstallStatus() {
return getArCoreShimInstance().checkAvailability(getApplicationContext());
}
@CalledByNative
private boolean shouldRequestInstallSupportedArCore() {
@ArCoreShim.Availability
int availability = getArCoreInstallStatus();
// Skip ARCore installation if we are certain that it is already installed.
// In all other cases, we might as well try to install it and handle installation failures.
return availability != ArCoreShim.Availability.SUPPORTED_INSTALLED;
}
@CalledByNative
private void requestInstallArModule(Tab tab) {
mTab = tab;
ModuleInstallUi ui = new ModuleInstallUi(mTab, R.string.ar_module_title, this);
ui.showInstallStartUi();
ModuleInstaller.install("ar", success -> {
assert shouldRequestInstallArModule() != success;
if (success) {
// As per documentation, it's recommended to issue a call to
// ArCoreApk.checkAvailability() early in application lifecycle & ignore the result
// so that subsequent calls can return cached result:
// https://developers.google.com/ar/develop/java/enable-arcore
// This is as early in the app lifecycle as it gets for us - just after installing
// AR module.
getArCoreInstallStatus();
}
if (mNativeArCoreJavaUtils != 0) {
if (success) {
ui.showInstallSuccessUi();
nativeOnRequestInstallArModuleResult(mNativeArCoreJavaUtils, success);
} else {
ui.showInstallFailureUi();
// early exit - user will be offered a choice to retry & install flow will
// continue from onRetry / onCancel
return;
}
}
});
}
@CalledByNative
private void requestInstallSupportedArCore(final Tab tab) {
assert shouldRequestInstallSupportedArCore();
@ArCoreShim.Availability
int arCoreAvailability = getArCoreInstallStatus();
final Activity activity = tab.getActivity();
String infobarText = null;
String buttonText = null;
switch (arCoreAvailability) {
case ArCoreShim.Availability.UNSUPPORTED_DEVICE_NOT_CAPABLE:
maybeNotifyNativeOnRequestInstallSupportedArCoreResult(false);
break;
case ArCoreShim.Availability.UNKNOWN_CHECKING:
case ArCoreShim.Availability.UNKNOWN_ERROR:
case ArCoreShim.Availability.UNKNOWN_TIMED_OUT:
case ArCoreShim.Availability.SUPPORTED_NOT_INSTALLED:
infobarText = activity.getString(R.string.ar_core_check_infobar_install_text);
buttonText = activity.getString(R.string.app_banner_install);
break;
case ArCoreShim.Availability.SUPPORTED_APK_TOO_OLD:
infobarText = activity.getString(R.string.ar_core_check_infobar_update_text);
buttonText = activity.getString(R.string.update_from_market);
break;
case ArCoreShim.Availability.SUPPORTED_INSTALLED:
assert false;
break;
}
SimpleConfirmInfoBarBuilder.Listener listener = new SimpleConfirmInfoBarBuilder.Listener() {
@Override
public void onInfoBarDismissed() {
maybeNotifyNativeOnRequestInstallSupportedArCoreResult(
!shouldRequestInstallSupportedArCore());
}
@Override
public boolean onInfoBarButtonClicked(boolean isPrimary) {
try {
assert sRequestInstallInstance == null;
@ArCoreShim.InstallStatus
int installStatus = getArCoreShimInstance().requestInstall(activity, true);
if (installStatus == ArCoreShim.InstallStatus.INSTALL_REQUESTED) {
// Install flow will resume in onArCoreRequestInstallReturned, mark that
// there is active request. Native code notification will be deferred until
// our activity gets resumed.
sRequestInstallInstance = ArCoreJavaUtils.this;
} else if (installStatus == ArCoreShim.InstallStatus.INSTALLED) {
// No need to install - notify native code.
maybeNotifyNativeOnRequestInstallSupportedArCoreResult(true);
}
} catch (ArCoreShim.UnavailableDeviceNotCompatibleException e) {
sRequestInstallInstance = null;
Log.w(TAG, "ARCore installation request failed with exception: %s",
e.toString());
maybeNotifyNativeOnRequestInstallSupportedArCoreResult(false);
} catch (ArCoreShim.UnavailableUserDeclinedInstallationException e) {
maybeNotifyNativeOnRequestInstallSupportedArCoreResult(false);
}
return false;
}
@Override
public boolean onInfoBarLinkClicked() {
return false;
}
};
// TODO(ijamardo, https://crbug.com/838833): Add icon for AR info bar.
SimpleConfirmInfoBarBuilder.create(tab, listener, InfoBarIdentifier.AR_CORE_UPGRADE_ANDROID,
R.drawable.ic_error_outline_googblue_24dp, infobarText, buttonText, null, null,
true);
}
@CalledByNative
private boolean canRequestInstallArModule() {
// We can only try to install the AR module if we are in a bundle mode.
return BundleUtils.isBundle();
}
@CalledByNative
private boolean shouldRequestInstallArModule() {
try {
// Try to find class in AR module that has not been obfuscated.
Class.forName("com.google.ar.core.ArCoreApk");
return false;
} catch (ClassNotFoundException e) {
return true;
}
}
private void onArCoreRequestInstallReturned(Activity activity) {
try {
// Since |userRequestedInstall| parameter is false, the below call should
// throw if ARCore is still not installed - no need to check the result.
getArCoreShimInstance().requestInstall(activity, false);
maybeNotifyNativeOnRequestInstallSupportedArCoreResult(true);
} catch (ArCoreShim.UnavailableDeviceNotCompatibleException e) {
Log.w(TAG, "Exception thrown when trying to validate install state of ARCore: %s",
e.toString());
maybeNotifyNativeOnRequestInstallSupportedArCoreResult(false);
} catch (ArCoreShim.UnavailableUserDeclinedInstallationException e) {
maybeNotifyNativeOnRequestInstallSupportedArCoreResult(false);
}
}
/**
* This method should be called by the Activity that gets resumed.
* We are only interested in the cases where our current Activity got paused
* as a result of a call to ArCoreApk.requestInstall() method.
*/
public static void onResumeActivityWithNative(Activity activity) {
if (sRequestInstallInstance != null) {
sRequestInstallInstance.onArCoreRequestInstallReturned(activity);
sRequestInstallInstance = null;
}
}
/**
* Helper used to notify native code about the result of the request to install ARCore.
*/
private void maybeNotifyNativeOnRequestInstallSupportedArCoreResult(boolean success) {
if (mNativeArCoreJavaUtils != 0) {
nativeOnRequestInstallSupportedArCoreResult(mNativeArCoreJavaUtils, success);
}
}
private static native void nativeInstallArCoreDeviceProviderFactory();
private native void nativeOnRequestInstallArModuleResult(
long nativeArCoreJavaUtils, boolean success);
private native void nativeOnRequestInstallSupportedArCoreResult(
long nativeArCoreJavaUtils, boolean success);
private native void nativeOnDrawingSurfaceReady(
long nativeArCoreJavaUtils, Surface surface, int rotation, int width, int height);
private native void nativeOnDrawingSurfaceTouch(
......
......@@ -19,11 +19,11 @@ public class ArDelegateImpl implements ArDelegate {
@Override
public void init() {
ArCoreJavaUtils.installArCoreDeviceProviderFactory();
ArCoreInstallUtils.installArCoreDeviceProviderFactory();
}
@Override
public void registerOnResumeActivity(Activity activity) {
ArCoreJavaUtils.onResumeActivityWithNative(activity);
ArCoreInstallUtils.onResumeActivityWithNative(activity);
}
}
......@@ -44,6 +44,7 @@ chrome_test_java_sources += tab_management_test_java_sources
if (enable_arcore) {
chrome_java_sources += [
"java/src/org/chromium/chrome/browser/vr/ArCoreInstallUtils.java",
"java/src/org/chromium/chrome/browser/vr/ArCoreJavaUtils.java",
"java/src/org/chromium/chrome/browser/vr/ArDelegateImpl.java",
"java/src/org/chromium/chrome/browser/vr/ArCoreShim.java",
......
......@@ -83,9 +83,9 @@ static_library("vr_android") {
"arcore_device/arcore_gl_thread.h",
"arcore_device/arcore_impl.cc",
"arcore_device/arcore_impl.h",
"arcore_device/arcore_install_utils.h",
"arcore_device/arcore_java_utils.cc",
"arcore_device/arcore_java_utils.h",
"arcore_device/arcore_session_utils.h",
"arcore_device/arcore_shim.cc",
"arcore_device/arcore_shim.h",
"arcore_device/type_converters.cc",
......@@ -222,6 +222,7 @@ android_library("ar_java") {
if (enable_arcore) {
generate_jni("ar_jni_headers") {
sources = [
"//chrome/android/java/src/org/chromium/chrome/browser/vr/ArCoreInstallUtils.java",
"//chrome/android/java/src/org/chromium/chrome/browser/vr/ArCoreJavaUtils.java",
]
}
......
......@@ -4,13 +4,17 @@
#include "chrome/browser/android/vr/arcore_device/arcore_consent_prompt.h"
#include <memory>
#include <utility>
#include "base/bind.h"
#include "chrome/android/features/vr/jni_headers/ArConsentDialog_jni.h"
#include "chrome/browser/android/tab_android.h"
#include "chrome/browser/android/vr/ar_jni_headers/ArCoreInstallUtils_jni.h"
#include "chrome/browser/android/vr/arcore_device/arcore_device_provider.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "device/vr/android/arcore/arcore_device_provider_factory.h"
using base::android::AttachCurrentThread;
using base::android::ScopedJavaLocalRef;
......@@ -19,7 +23,23 @@ namespace vr {
namespace {
ArcoreConsentPrompt* g_instance = nullptr;
ArCoreConsentPrompt* g_instance = nullptr;
class ArCoreDeviceProviderFactoryImpl
: public device::ArCoreDeviceProviderFactory {
public:
ArCoreDeviceProviderFactoryImpl() = default;
~ArCoreDeviceProviderFactoryImpl() override = default;
std::unique_ptr<device::VRDeviceProvider> CreateDeviceProvider() override;
private:
DISALLOW_COPY_AND_ASSIGN(ArCoreDeviceProviderFactoryImpl);
};
std::unique_ptr<device::VRDeviceProvider>
ArCoreDeviceProviderFactoryImpl::CreateDeviceProvider() {
return std::make_unique<device::ArCoreDeviceProvider>();
}
base::android::ScopedJavaLocalRef<jobject> GetTabFromRenderer(
int render_process_id,
......@@ -44,42 +64,173 @@ base::android::ScopedJavaLocalRef<jobject> GetTabFromRenderer(
} // namespace
ArcoreConsentPrompt::ArcoreConsentPrompt() = default;
ArCoreConsentPrompt::ArCoreConsentPrompt() : weak_ptr_factory_(this) {}
ArcoreConsentPrompt::~ArcoreConsentPrompt() = default;
ArCoreConsentPrompt::~ArCoreConsentPrompt() = default;
void ArcoreConsentPrompt::GetUserPermission(
void ArCoreConsentPrompt::GetUserPermission(
int render_process_id,
int render_frame_id,
base::OnceCallback<void(bool)> response_callback) {
on_user_consent_callback_ = std::move(response_callback);
render_process_id_ = render_process_id;
render_frame_id_ = render_frame_id;
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> jdelegate = Java_ArConsentDialog_showDialog(
jdelegate_ = Java_ArConsentDialog_showDialog(
env, reinterpret_cast<jlong>(this),
GetTabFromRenderer(render_process_id, render_frame_id));
if (jdelegate.is_null()) {
GetTabFromRenderer(render_process_id_, render_frame_id_));
if (jdelegate_.is_null()) {
std::move(on_user_consent_callback_).Run(false);
}
}
void ArcoreConsentPrompt::OnUserConsentResult(
void ArCoreConsentPrompt::OnUserConsentResult(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& j_caller,
jboolean is_granted) {
DCHECK(on_user_consent_callback_);
std::move(on_user_consent_callback_).Run(is_granted);
jdelegate_.Reset();
if (!on_user_consent_callback_)
return;
if (!is_granted) {
CallDeferredUserConsentCallback(false);
return;
}
RequestArModule();
}
// static
void ArcoreConsentPrompt::ShowConsentPrompt(
void ArCoreConsentPrompt::ShowConsentPrompt(
int render_process_id,
int render_frame_id,
base::OnceCallback<void(bool)> response_callback) {
if (!g_instance)
g_instance = new ArcoreConsentPrompt();
g_instance = new ArCoreConsentPrompt();
g_instance->GetUserPermission(render_process_id, render_frame_id,
std::move(response_callback));
}
bool ArCoreConsentPrompt::CanRequestInstallArModule() {
return Java_ArCoreInstallUtils_canRequestInstallArModule(
AttachCurrentThread(), java_install_utils_);
}
bool ArCoreConsentPrompt::ShouldRequestInstallArModule() {
return Java_ArCoreInstallUtils_shouldRequestInstallArModule(
AttachCurrentThread(), java_install_utils_);
}
void ArCoreConsentPrompt::RequestInstallArModule() {
Java_ArCoreInstallUtils_requestInstallArModule(
AttachCurrentThread(), java_install_utils_,
GetTabFromRenderer(render_process_id_, render_frame_id_));
}
bool ArCoreConsentPrompt::ShouldRequestInstallSupportedArCore() {
JNIEnv* env = AttachCurrentThread();
return Java_ArCoreInstallUtils_shouldRequestInstallSupportedArCore(
env, java_install_utils_);
}
void ArCoreConsentPrompt::RequestInstallSupportedArCore() {
DCHECK(ShouldRequestInstallSupportedArCore());
JNIEnv* env = AttachCurrentThread();
Java_ArCoreInstallUtils_requestInstallSupportedArCore(
env, java_install_utils_,
GetTabFromRenderer(render_process_id_, render_frame_id_));
}
void ArCoreConsentPrompt::OnRequestInstallArModuleResult(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
bool success) {
DVLOG(1) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (on_request_ar_module_result_callback_) {
std::move(on_request_ar_module_result_callback_).Run(success);
}
}
void ArCoreConsentPrompt::OnRequestInstallSupportedArCoreResult(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
bool success) {
DVLOG(1) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(on_request_arcore_install_or_update_result_callback_);
std::move(on_request_arcore_install_or_update_result_callback_).Run(success);
}
void ArCoreConsentPrompt::RequestArModule() {
DVLOG(1) << __func__;
if (ShouldRequestInstallArModule()) {
if (!CanRequestInstallArModule()) {
OnRequestArModuleResult(false);
return;
}
on_request_ar_module_result_callback_ = base::BindOnce(
&ArCoreConsentPrompt::OnRequestArModuleResult, GetWeakPtr());
RequestInstallArModule();
return;
}
OnRequestArModuleResult(true);
}
void ArCoreConsentPrompt::OnRequestArModuleResult(bool success) {
DVLOG(3) << __func__ << ": success=" << success;
if (!success) {
CallDeferredUserConsentCallback(false);
return;
}
RequestArCoreInstallOrUpdate();
}
void ArCoreConsentPrompt::RequestArCoreInstallOrUpdate() {
DVLOG(1) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(!on_request_arcore_install_or_update_result_callback_);
if (ShouldRequestInstallSupportedArCore()) {
// ARCore is not installed or requires an update. Store the callback to be
// processed later once installation/update is complete or got cancelled.
on_request_arcore_install_or_update_result_callback_ = base::BindOnce(
&ArCoreConsentPrompt::OnRequestArCoreInstallOrUpdateResult,
GetWeakPtr());
RequestInstallSupportedArCore();
return;
}
OnRequestArCoreInstallOrUpdateResult(true);
}
void ArCoreConsentPrompt::OnRequestArCoreInstallOrUpdateResult(bool success) {
DVLOG(1) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
CallDeferredUserConsentCallback(success);
}
void ArCoreConsentPrompt::CallDeferredUserConsentCallback(
bool is_permission_granted) {
if (on_user_consent_callback_)
std::move(on_user_consent_callback_).Run(is_permission_granted);
}
static void JNI_ArCoreInstallUtils_InstallArCoreDeviceProviderFactory(
JNIEnv* env) {
device::ArCoreDeviceProviderFactory::Install(
std::make_unique<ArCoreDeviceProviderFactoryImpl>());
}
} // namespace vr
......@@ -7,21 +7,24 @@
#include "base/android/jni_android.h"
#include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h"
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "chrome/browser/vr/service/arcore_consent_prompt_interface.h"
#include "chrome/browser/vr/vr_export.h"
namespace vr {
class VR_EXPORT ArcoreConsentPrompt : public ArcoreConsentPromptInterface {
class VR_EXPORT ArCoreConsentPrompt : public ArCoreConsentPromptInterface {
public:
void ShowConsentPrompt(
int render_process_id,
int render_frame_id,
base::OnceCallback<void(bool)> response_callback) override;
ArcoreConsentPrompt();
~ArcoreConsentPrompt();
ArCoreConsentPrompt();
~ArCoreConsentPrompt();
// device::VrDevicePermissionProvider:
void GetUserPermission(int render_process_id,
......@@ -32,8 +35,51 @@ class VR_EXPORT ArcoreConsentPrompt : public ArcoreConsentPromptInterface {
const base::android::JavaParamRef<jobject>& j_caller,
jboolean is_granted);
// Returns true if AR module installation is supported, false otherwise.
virtual bool CanRequestInstallArModule();
// Returns true if AR module is not installed, false otherwise.
virtual bool ShouldRequestInstallArModule();
virtual void RequestInstallArModule();
virtual bool ShouldRequestInstallSupportedArCore();
virtual void RequestInstallSupportedArCore();
// Called from Java end.
void OnRequestInstallArModuleResult(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
bool success);
void OnRequestInstallSupportedArCoreResult(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
bool success);
private:
void RequestArModule();
void OnRequestArModuleResult(bool success);
void RequestArCoreInstallOrUpdate();
void OnRequestArCoreInstallOrUpdateResult(bool success);
void CallDeferredUserConsentCallback(bool is_permission_granted);
base::WeakPtr<ArCoreConsentPrompt> GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
base::OnceCallback<void(bool)> on_user_consent_callback_;
base::OnceCallback<void(bool)> on_request_ar_module_result_callback_;
base::OnceCallback<void(bool)>
on_request_arcore_install_or_update_result_callback_;
base::android::ScopedJavaLocalRef<jobject> jdelegate_;
int render_process_id_;
int render_frame_id_;
base::android::ScopedJavaGlobalRef<jobject> java_install_utils_;
THREAD_CHECKER(thread_checker_);
base::WeakPtrFactory<ArCoreConsentPrompt> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ArCoreConsentPrompt);
};
} // namespace vr
......
......@@ -14,8 +14,8 @@
#include "chrome/browser/android/vr/arcore_device/arcore_gl.h"
#include "chrome/browser/android/vr/arcore_device/arcore_gl_thread.h"
#include "chrome/browser/android/vr/arcore_device/arcore_impl.h"
#include "chrome/browser/android/vr/arcore_device/arcore_install_utils.h"
#include "chrome/browser/android/vr/arcore_device/arcore_java_utils.h"
#include "chrome/browser/android/vr/arcore_device/arcore_session_utils.h"
#include "chrome/browser/android/vr/mailbox_to_surface_bridge.h"
#include "chrome/browser/permissions/permission_manager.h"
#include "chrome/browser/permissions/permission_result.h"
......@@ -74,13 +74,13 @@ ArCoreDevice::ArCoreDevice(
std::unique_ptr<ArCoreFactory> arcore_factory,
std::unique_ptr<ArImageTransportFactory> ar_image_transport_factory,
std::unique_ptr<vr::MailboxToSurfaceBridge> mailbox_to_surface_bridge,
std::unique_ptr<vr::ArCoreInstallUtils> arcore_install_utils)
std::unique_ptr<vr::ArCoreSessionUtils> arcore_session_utils)
: VRDeviceBase(mojom::XRDeviceId::ARCORE_DEVICE_ID),
main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
arcore_factory_(std::move(arcore_factory)),
ar_image_transport_factory_(std::move(ar_image_transport_factory)),
mailbox_bridge_(std::move(mailbox_to_surface_bridge)),
arcore_install_utils_(std::move(arcore_install_utils)),
arcore_session_utils_(std::move(arcore_session_utils)),
session_state_(std::make_unique<ArCoreDevice::SessionState>()),
weak_ptr_factory_(this) {
// Ensure display_info_ is set to avoid crash in CallDeferredSessionCallback
......@@ -97,25 +97,16 @@ ArCoreDevice::ArCoreDevice(
}
ArCoreDevice::ArCoreDevice()
: ArCoreDevice(
std::make_unique<ArCoreImplFactory>(),
std::make_unique<ArImageTransportFactory>(),
std::make_unique<vr::MailboxToSurfaceBridge>(),
std::make_unique<vr::ArCoreJavaUtils>(
base::BindRepeating(
&ArCoreDevice::OnRequestInstallArModuleResult,
base::Unretained(this)), // unretained is fine for callbacks
// since ArCoreDevice owns the
// ArCoreJavaUtils instance
base::BindRepeating(
&ArCoreDevice::OnRequestInstallSupportedArCoreResult,
base::Unretained(this)))) {}
: ArCoreDevice(std::make_unique<ArCoreImplFactory>(),
std::make_unique<ArImageTransportFactory>(),
std::make_unique<vr::MailboxToSurfaceBridge>(),
std::make_unique<vr::ArCoreJavaUtils>()) {}
ArCoreDevice::~ArCoreDevice() {
CallDeferredRequestSessionCallback(/*success=*/false);
// The GL thread must be terminated since it uses our members. For example,
// there might still be a posted Initialize() call in flight that uses
// arcore_install_utils_ and arcore_factory_. Ensure that the thread is
// arcore_session_utils_ and arcore_factory_. Ensure that the thread is
// stopped before other members get destructed. Don't call Stop() here,
// destruction calls Stop() and doing so twice is illegal (null pointer
// dereference).
......@@ -190,15 +181,6 @@ void ArCoreDevice::RequestSession(
void ArCoreDevice::RequestSessionAfterInitialization(int render_process_id,
int render_frame_id) {
session_state_->start_immersive_activity_callback_ =
base::BindOnce(&ArCoreDevice::RequestArSessionConsent, GetWeakPtr(),
render_process_id, render_frame_id);
RequestArModule(render_process_id, render_frame_id);
}
void ArCoreDevice::RequestArSessionConsent(int render_process_id,
int render_frame_id) {
auto ready_callback =
base::BindRepeating(&ArCoreDevice::OnDrawingSurfaceReady, GetWeakPtr());
auto touch_callback =
......@@ -206,7 +188,7 @@ void ArCoreDevice::RequestArSessionConsent(int render_process_id,
auto destroyed_callback =
base::BindOnce(&ArCoreDevice::OnDrawingSurfaceDestroyed, GetWeakPtr());
arcore_install_utils_->RequestArSession(
arcore_session_utils_->RequestArSession(
render_process_id, render_frame_id, std::move(ready_callback),
std::move(touch_callback), std::move(destroyed_callback));
}
......@@ -250,7 +232,7 @@ void ArCoreDevice::OnSessionEnded() {
DVLOG(1) << __func__;
// This may be a no-op in case it's destroyed already.
arcore_install_utils_->DestroyDrawingSurface();
arcore_session_utils_->DestroyDrawingSurface();
// The GL thread had initialized its context with a drawing_widget based on
// the ArImmersiveOverlay's Surface, and the one it has is no longer valid.
......@@ -276,88 +258,6 @@ void ArCoreDevice::OnSessionEnded() {
mailbox_bridge_ = nullptr;
}
void ArCoreDevice::RequestArModule(int render_process_id, int render_frame_id) {
DVLOG(1) << __func__;
if (arcore_install_utils_->ShouldRequestInstallArModule()) {
if (!arcore_install_utils_->CanRequestInstallArModule()) {
OnRequestArModuleResult(render_process_id, render_frame_id, false);
return;
}
on_request_ar_module_result_callback_ =
base::BindOnce(&ArCoreDevice::OnRequestArModuleResult, GetWeakPtr(),
render_process_id, render_frame_id);
arcore_install_utils_->RequestInstallArModule(render_process_id,
render_frame_id);
return;
}
OnRequestArModuleResult(render_process_id, render_frame_id, true);
}
void ArCoreDevice::OnRequestArModuleResult(int render_process_id,
int render_frame_id,
bool success) {
DVLOG(3) << __func__ << ": success=" << success;
if (!success) {
CallDeferredRequestSessionCallback(/*success=*/false);
return;
}
RequestArCoreInstallOrUpdate(render_process_id, render_frame_id);
}
void ArCoreDevice::RequestArCoreInstallOrUpdate(int render_process_id,
int render_frame_id) {
DVLOG(1) << __func__;
DCHECK(IsOnMainThread());
DCHECK(!on_request_arcore_install_or_update_result_callback_);
if (arcore_install_utils_->ShouldRequestInstallSupportedArCore()) {
// ARCore is not installed or requires an update. Store the callback to be
// processed later once installation/update is complete or got cancelled.
on_request_arcore_install_or_update_result_callback_ = base::BindOnce(
&ArCoreDevice::OnRequestArCoreInstallOrUpdateResult, GetWeakPtr());
arcore_install_utils_->RequestInstallSupportedArCore(render_process_id,
render_frame_id);
return;
}
OnRequestArCoreInstallOrUpdateResult(true);
}
void ArCoreDevice::OnRequestArCoreInstallOrUpdateResult(bool success) {
DVLOG(1) << __func__;
DCHECK(IsOnMainThread());
if (!success) {
CallDeferredRequestSessionCallback(/*success=*/false);
return;
}
DCHECK(session_state_->start_immersive_activity_callback_);
std::move(session_state_->start_immersive_activity_callback_).Run();
}
void ArCoreDevice::OnRequestInstallArModuleResult(bool success) {
DVLOG(1) << __func__;
DCHECK(IsOnMainThread());
if (on_request_ar_module_result_callback_) {
std::move(on_request_ar_module_result_callback_).Run(success);
}
}
void ArCoreDevice::OnRequestInstallSupportedArCoreResult(bool success) {
DVLOG(1) << __func__;
DCHECK(IsOnMainThread());
DCHECK(on_request_arcore_install_or_update_result_callback_);
std::move(on_request_arcore_install_or_update_result_callback_).Run(success);
}
void ArCoreDevice::CallDeferredRequestSessionCallback(bool success) {
DVLOG(1) << __func__ << " success=" << success;
DCHECK(IsOnMainThread());
......@@ -430,7 +330,7 @@ void ArCoreDevice::RequestArCoreGlInitialization(
DCHECK(IsOnMainThread());
DCHECK(session_state_->is_arcore_gl_thread_initialized_);
if (!arcore_install_utils_->EnsureLoaded()) {
if (!arcore_session_utils_->EnsureLoaded()) {
DLOG(ERROR) << "ARCore was not loaded properly.";
OnArCoreGlInitializationComplete(false);
return;
......@@ -445,7 +345,7 @@ void ArCoreDevice::RequestArCoreGlInitialization(
PostTaskToGlThread(base::BindOnce(
&ArCoreGl::Initialize,
session_state_->arcore_gl_thread_->GetArCoreGl()->GetWeakPtr(),
arcore_install_utils_.get(), arcore_factory_.get(), drawing_widget,
arcore_session_utils_.get(), arcore_factory_.get(), drawing_widget,
frame_size, rotation,
CreateMainThreadCallback(base::BindOnce(
&ArCoreDevice::OnArCoreGlInitializationComplete, GetWeakPtr()))));
......
......@@ -22,7 +22,7 @@
namespace vr {
class MailboxToSurfaceBridge;
class ArCoreInstallUtils;
class ArCoreSessionUtils;
} // namespace vr
namespace device {
......@@ -37,7 +37,7 @@ class ArCoreDevice : public VRDeviceBase {
std::unique_ptr<ArCoreFactory> arcore_factory,
std::unique_ptr<ArImageTransportFactory> ar_image_transport_factory,
std::unique_ptr<vr::MailboxToSurfaceBridge> mailbox_to_surface_bridge,
std::unique_ptr<vr::ArCoreInstallUtils> arcore_install_utils);
std::unique_ptr<vr::ArCoreSessionUtils> arcore_session_utils);
ArCoreDevice();
~ArCoreDevice() override;
......@@ -51,9 +51,6 @@ class ArCoreDevice : public VRDeviceBase {
}
private:
void OnRequestInstallArModuleResult(bool success);
void OnRequestInstallSupportedArCoreResult(bool success);
// VRDeviceBase implementation
void OnMailboxBridgeReady();
void OnArCoreGlThreadInitialized();
......@@ -102,7 +99,6 @@ class ArCoreDevice : public VRDeviceBase {
int rotation,
const gfx::Size& size);
void OnArCoreGlInitializationComplete(bool success);
void RequestArSessionConsent(int render_process_id, int render_frame_id);
void OnCreateSessionCallback(
mojom::XRRuntime::RequestSessionCallback deferred_callback,
......@@ -115,7 +111,7 @@ class ArCoreDevice : public VRDeviceBase {
std::unique_ptr<ArCoreFactory> arcore_factory_;
std::unique_ptr<ArImageTransportFactory> ar_image_transport_factory_;
std::unique_ptr<vr::MailboxToSurfaceBridge> mailbox_bridge_;
std::unique_ptr<vr::ArCoreInstallUtils> arcore_install_utils_;
std::unique_ptr<vr::ArCoreSessionUtils> arcore_session_utils_;
// Encapsulates data with session lifetime.
struct SessionState {
......
......@@ -11,9 +11,8 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "chrome/browser/android/vr/arcore_device/ar_image_transport.h"
#include "chrome/browser/android/vr/arcore_device/arcore_device.h"
#include "chrome/browser/android/vr/arcore_device/arcore_gl.h"
#include "chrome/browser/android/vr/arcore_device/arcore_install_utils.h"
#include "chrome/browser/android/vr/arcore_device/arcore_session_utils.h"
#include "chrome/browser/android/vr/arcore_device/fake_arcore.h"
#include "chrome/browser/android/vr/mailbox_to_surface_bridge.h"
#include "device/vr/public/mojom/vr_service.mojom.h"
......@@ -82,18 +81,10 @@ class StubMailboxToSurfaceBridge : public vr::MailboxToSurfaceBridge {
base::OnceClosure callback_;
};
class StubArCoreInstallUtils : public vr::ArCoreInstallUtils {
class StubArCoreSessionUtils : public vr::ArCoreSessionUtils {
public:
StubArCoreInstallUtils() = default;
bool CanRequestInstallArModule() override { return false; }
bool ShouldRequestInstallArModule() override { return false; }
StubArCoreSessionUtils() = default;
void RequestInstallArModule(int render_process_id,
int render_frame_id) override {}
bool ShouldRequestInstallSupportedArCore() override { return false; }
void RequestInstallSupportedArCore(int render_process_id,
int render_frame_id) override {}
void RequestArSession(
int render_process_id,
int render_frame_id,
......@@ -148,7 +139,7 @@ class ArCoreDeviceTest : public testing::Test {
}
StubMailboxToSurfaceBridge* bridge;
StubArCoreInstallUtils* install_utils;
StubArCoreSessionUtils* session_utils;
mojom::XRFrameDataProviderPtr frame_provider;
mojom::XREnvironmentIntegrationProviderAssociatedPtr environment_provider;
std::unique_ptr<base::RunLoop> run_loop;
......@@ -159,13 +150,13 @@ class ArCoreDeviceTest : public testing::Test {
std::unique_ptr<StubMailboxToSurfaceBridge> bridge_ptr =
std::make_unique<StubMailboxToSurfaceBridge>();
bridge = bridge_ptr.get();
std::unique_ptr<StubArCoreInstallUtils> install_utils_ptr =
std::make_unique<StubArCoreInstallUtils>();
install_utils = install_utils_ptr.get();
std::unique_ptr<StubArCoreSessionUtils> session_utils_ptr =
std::make_unique<StubArCoreSessionUtils>();
session_utils = session_utils_ptr.get();
device_ = std::make_unique<ArCoreDevice>(
std::make_unique<FakeArCoreFactory>(),
std::make_unique<StubArImageTransportFactory>(), std::move(bridge_ptr),
std::move(install_utils_ptr));
std::move(session_utils_ptr));
}
void CreateSession() {
......@@ -245,7 +236,7 @@ TEST_F(ArCoreDeviceTest, RequestHitTest) {
base::BindOnce(callback, &hit_results));
// Have to get frame data to trigger the hit-test calculation.
GetFrameData();
EXPECT_TRUE(hit_results.size() > 0);
EXPECT_FALSE(hit_results.empty());
}
} // namespace device
......@@ -20,7 +20,7 @@
#include "base/trace_event/traced_value.h"
#include "chrome/browser/android/vr/arcore_device/ar_image_transport.h"
#include "chrome/browser/android/vr/arcore_device/arcore_impl.h"
#include "chrome/browser/android/vr/arcore_device/arcore_install_utils.h"
#include "chrome/browser/android/vr/arcore_device/arcore_session_utils.h"
#include "chrome/browser/android/vr/web_xr_presentation_state.h"
#include "device/vr/public/mojom/vr_service.mojom.h"
#include "gpu/ipc/common/gpu_memory_buffer_impl_android_hardware_buffer.h"
......@@ -119,7 +119,7 @@ ArCoreGl::~ArCoreGl() {
CloseBindingsIfOpen();
}
void ArCoreGl::Initialize(vr::ArCoreInstallUtils* install_utils,
void ArCoreGl::Initialize(vr::ArCoreSessionUtils* session_utils,
ArCoreFactory* arcore_factory,
gfx::AcceleratedWidget drawing_widget,
const gfx::Size& frame_size,
......@@ -141,7 +141,7 @@ void ArCoreGl::Initialize(vr::ArCoreInstallUtils* install_utils,
// Get the activity context.
base::android::ScopedJavaLocalRef<jobject> application_context =
install_utils->GetApplicationContext();
session_utils->GetApplicationContext();
if (!application_context.obj()) {
DLOG(ERROR) << "Unable to retrieve the Java context/activity!";
std::move(callback).Run(false);
......
......@@ -36,7 +36,7 @@ class GLSurface;
} // namespace gl
namespace vr {
class ArCoreInstallUtils;
class ArCoreSessionUtils;
class WebXrPresentationState;
} // namespace vr
......@@ -63,7 +63,7 @@ class ArCoreGl : public mojom::XRFrameDataProvider,
explicit ArCoreGl(std::unique_ptr<ArImageTransport> ar_image_transport);
~ArCoreGl() override;
void Initialize(vr::ArCoreInstallUtils* install_utils,
void Initialize(vr::ArCoreSessionUtils* session_utils,
ArCoreFactory* arcore_factory,
gfx::AcceleratedWidget drawing_widget,
const gfx::Size& frame_size,
......
......@@ -10,11 +10,9 @@
#include "base/android/jni_string.h"
#include "chrome/browser/android/tab_android.h"
#include "chrome/browser/android/vr/ar_jni_headers/ArCoreJavaUtils_jni.h"
#include "chrome/browser/android/vr/arcore_device/arcore_device_provider.h"
#include "chrome/browser/android/vr/arcore_device/arcore_shim.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "device/vr/android/arcore/arcore_device_provider_factory.h"
using base::android::AttachCurrentThread;
using base::android::ScopedJavaLocalRef;
......@@ -23,29 +21,9 @@ namespace vr {
namespace {
class ArCoreDeviceProviderFactoryImpl
: public device::ArCoreDeviceProviderFactory {
public:
ArCoreDeviceProviderFactoryImpl() = default;
~ArCoreDeviceProviderFactoryImpl() override = default;
std::unique_ptr<device::VRDeviceProvider> CreateDeviceProvider() override;
private:
DISALLOW_COPY_AND_ASSIGN(ArCoreDeviceProviderFactoryImpl);
};
std::unique_ptr<device::VRDeviceProvider>
ArCoreDeviceProviderFactoryImpl::CreateDeviceProvider() {
return std::make_unique<device::ArCoreDeviceProvider>();
}
} // namespace
ArCoreJavaUtils::ArCoreJavaUtils(
base::RepeatingCallback<void(bool)> ar_module_installation_callback,
base::RepeatingCallback<void(bool)> ar_core_installation_callback)
: ar_module_installation_callback_(ar_module_installation_callback),
ar_core_installation_callback_(ar_core_installation_callback) {
ArCoreJavaUtils::ArCoreJavaUtils() {
JNIEnv* env = AttachCurrentThread();
if (!env)
return;
......@@ -61,46 +39,6 @@ ArCoreJavaUtils::~ArCoreJavaUtils() {
Java_ArCoreJavaUtils_onNativeDestroy(env, j_arcore_java_utils_);
}
void ArCoreJavaUtils::OnRequestInstallSupportedArCoreResult(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
bool success) {
ar_core_installation_callback_.Run(success);
}
bool ArCoreJavaUtils::CanRequestInstallArModule() {
return Java_ArCoreJavaUtils_canRequestInstallArModule(AttachCurrentThread(),
j_arcore_java_utils_);
}
bool ArCoreJavaUtils::ShouldRequestInstallArModule() {
return Java_ArCoreJavaUtils_shouldRequestInstallArModule(
AttachCurrentThread(), j_arcore_java_utils_);
}
void ArCoreJavaUtils::RequestInstallArModule(int render_process_id,
int render_frame_id) {
Java_ArCoreJavaUtils_requestInstallArModule(
AttachCurrentThread(), j_arcore_java_utils_,
getTabFromRenderer(render_process_id, render_frame_id));
}
bool ArCoreJavaUtils::ShouldRequestInstallSupportedArCore() {
JNIEnv* env = AttachCurrentThread();
return Java_ArCoreJavaUtils_shouldRequestInstallSupportedArCore(
env, j_arcore_java_utils_);
}
void ArCoreJavaUtils::RequestInstallSupportedArCore(int render_process_id,
int render_frame_id) {
DCHECK(ShouldRequestInstallSupportedArCore());
JNIEnv* env = AttachCurrentThread();
Java_ArCoreJavaUtils_requestInstallSupportedArCore(
env, j_arcore_java_utils_,
getTabFromRenderer(render_process_id, render_frame_id));
}
void ArCoreJavaUtils::RequestArSession(
int render_process_id,
int render_frame_id,
......@@ -161,13 +99,6 @@ void ArCoreJavaUtils::OnDrawingSurfaceDestroyed(
}
}
void ArCoreJavaUtils::OnRequestInstallArModuleResult(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
bool success) {
ar_module_installation_callback_.Run(success);
}
bool ArCoreJavaUtils::EnsureLoaded() {
DCHECK(vr::IsArCoreSupported());
......@@ -206,10 +137,4 @@ base::android::ScopedJavaLocalRef<jobject> ArCoreJavaUtils::getTabFromRenderer(
return j_tab_android;
}
static void JNI_ArCoreJavaUtils_InstallArCoreDeviceProviderFactory(
JNIEnv* env) {
device::ArCoreDeviceProviderFactory::Install(
std::make_unique<ArCoreDeviceProviderFactoryImpl>());
}
} // namespace vr
......@@ -11,39 +11,26 @@
#include "base/android/scoped_java_ref.h"
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/android/vr/arcore_device/arcore_install_utils.h"
#include "chrome/browser/android/vr/arcore_device/arcore_session_utils.h"
namespace vr {
class ArCoreJavaUtils : public ArCoreInstallUtils {
class ArCoreJavaUtils : public ArCoreSessionUtils {
public:
explicit ArCoreJavaUtils(
base::RepeatingCallback<void(bool)> ar_module_installation_callback,
base::RepeatingCallback<void(bool)> ar_core_installation_callback);
ArCoreJavaUtils();
~ArCoreJavaUtils() override;
bool ShouldRequestInstallArModule() override;
bool CanRequestInstallArModule() override;
void RequestInstallArModule(int render_process_id,
int render_frame_id) override;
bool ShouldRequestInstallSupportedArCore() override;
void RequestInstallSupportedArCore(int render_process_id,
int render_frame_id) override;
// ArCoreSessionUtils:
void RequestArSession(int render_process_id,
int render_frame_id,
SurfaceReadyCallback ready_callback,
SurfaceTouchCallback touch_callback,
SurfaceDestroyedCallback destroyed_callback) override;
void DestroyDrawingSurface() override;
bool EnsureLoaded() override;
base::android::ScopedJavaLocalRef<jobject> GetApplicationContext() override;
// Methods called from the Java side.
void OnRequestInstallArModuleResult(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
bool success);
void OnRequestInstallSupportedArCoreResult(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
bool success);
void OnDrawingSurfaceReady(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
......@@ -60,17 +47,11 @@ class ArCoreJavaUtils : public ArCoreInstallUtils {
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
bool EnsureLoaded() override;
base::android::ScopedJavaLocalRef<jobject> GetApplicationContext() override;
private:
base::android::ScopedJavaLocalRef<jobject> getTabFromRenderer(
int render_process_id,
int render_frame_id);
base::RepeatingCallback<void(bool)> ar_module_installation_callback_;
base::RepeatingCallback<void(bool)> ar_core_installation_callback_;
base::android::ScopedJavaGlobalRef<jobject> j_arcore_java_utils_;
SurfaceReadyCallback surface_ready_callback_;
......
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ANDROID_VR_ARCORE_DEVICE_ARCORE_INSTALL_UTILS_H_
#define CHROME_BROWSER_ANDROID_VR_ARCORE_DEVICE_ARCORE_INSTALL_UTILS_H_
#ifndef CHROME_BROWSER_ANDROID_VR_ARCORE_DEVICE_ARCORE_SESSION_UTILS_H_
#define CHROME_BROWSER_ANDROID_VR_ARCORE_DEVICE_ARCORE_SESSION_UTILS_H_
#include "base/android/scoped_java_ref.h"
#include "base/memory/weak_ptr.h"
......@@ -30,18 +30,9 @@ using SurfaceTouchCallback =
base::RepeatingCallback<void(bool touching, const gfx::PointF& location)>;
using SurfaceDestroyedCallback = base::OnceClosure;
class ArCoreInstallUtils {
class ArCoreSessionUtils {
public:
virtual ~ArCoreInstallUtils() = default;
// Returns true if AR module installation is supported, false otherwise.
virtual bool CanRequestInstallArModule() = 0;
// Returns true if AR module is not installed, false otherwise.
virtual bool ShouldRequestInstallArModule() = 0;
virtual void RequestInstallArModule(int render_process_id,
int render_frame_id) = 0;
virtual bool ShouldRequestInstallSupportedArCore() = 0;
virtual void RequestInstallSupportedArCore(int render_process_id,
int render_frame_id) = 0;
virtual ~ArCoreSessionUtils() = default;
virtual bool EnsureLoaded() = 0;
virtual base::android::ScopedJavaLocalRef<jobject>
GetApplicationContext() = 0;
......@@ -56,4 +47,4 @@ class ArCoreInstallUtils {
} // namespace vr
#endif // CHROME_BROWSER_ANDROID_VR_ARCORE_DEVICE_ARCORE_INSTALL_UTILS_H_
#endif // CHROME_BROWSER_ANDROID_VR_ARCORE_DEVICE_ARCORE_SESSION_UTILS_H_
......@@ -88,7 +88,7 @@ std::unique_ptr<VrModuleProvider> VrModuleProviderFactory::CreateModuleProvider(
static void JNI_VrModuleProvider_Init(JNIEnv* env) {
GvrConsentHelper::SetInstance(std::make_unique<vr::GvrConsentHelperImpl>());
#if BUILDFLAG(ENABLE_ARCORE)
ArcoreConsentPromptInterface::SetInstance(new ArcoreConsentPrompt());
ArCoreConsentPromptInterface::SetInstance(new ArCoreConsentPrompt());
#endif
}
......
......@@ -7,17 +7,17 @@
namespace vr {
namespace {
ArcoreConsentPromptInterface* g_arcore_consent_prompt = nullptr;
ArCoreConsentPromptInterface* g_arcore_consent_prompt = nullptr;
}
// static
void ArcoreConsentPromptInterface::SetInstance(
ArcoreConsentPromptInterface* instance) {
void ArCoreConsentPromptInterface::SetInstance(
ArCoreConsentPromptInterface* instance) {
g_arcore_consent_prompt = instance;
}
// static
ArcoreConsentPromptInterface* ArcoreConsentPromptInterface::GetInstance() {
ArCoreConsentPromptInterface* ArCoreConsentPromptInterface::GetInstance() {
return g_arcore_consent_prompt;
}
......
......@@ -12,10 +12,10 @@ namespace vr {
// TODO(crbug.com/968233): Unify consent flow.
// This class solves layering problem until the above bug gets fixed.
class VR_EXPORT ArcoreConsentPromptInterface {
class VR_EXPORT ArCoreConsentPromptInterface {
public:
static void SetInstance(ArcoreConsentPromptInterface*);
static ArcoreConsentPromptInterface* GetInstance();
static void SetInstance(ArCoreConsentPromptInterface*);
static ArCoreConsentPromptInterface* GetInstance();
virtual void ShowConsentPrompt(
int render_process_id,
......
......@@ -211,7 +211,7 @@ void XRDeviceImpl::RequestSession(
if (IsXrDeviceConsentPromptDisabledForTesting()) {
DoRequestSession(std::move(options), std::move(callback));
} else {
ArcoreConsentPromptInterface::GetInstance()->ShowConsentPrompt(
ArCoreConsentPromptInterface::GetInstance()->ShowConsentPrompt(
render_frame_host_->GetProcess()->GetID(),
render_frame_host_->GetRoutingID(),
base::BindOnce(&XRDeviceImpl::OnConsentResult,
......
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