Commit 5161e612 authored by Biao She's avatar Biao She Committed by Commit Bot

Disable GvrDevice if VR is not available

Previously, we create a GvrDevice even if VrShellDelegate thinks VR is not
available. This GvrDevice may works for magic window but can't present as Vr
presentation depend on VrShellDelegate. However, the returned GvrDevice marks
itself as a device which set canPresent to true. This leads to confusion.

This CL gate GvrDevice creation on the same criteria as VrShellDelegate.

Bug: 790770
Change-Id: I686eda152418b71ad5c5344aed593903db2b70f7
Reviewed-on: https://chromium-review.googlesource.com/809227Reviewed-by: default avatarMichael Thiessen <mthiesse@chromium.org>
Reviewed-by: default avataragrieve <agrieve@chromium.org>
Commit-Queue: Biao She <bshe@chromium.org>
Cr-Commit-Position: refs/heads/master@{#522182}
parent 9c50a0c5
...@@ -357,6 +357,7 @@ java_cpp_enum("chrome_android_java_enums_srcjar") { ...@@ -357,6 +357,7 @@ java_cpp_enum("chrome_android_java_enums_srcjar") {
java_cpp_enum("chrome_vr_android_java_enums_srcjar") { java_cpp_enum("chrome_vr_android_java_enums_srcjar") {
sources = [ sources = [
"//chrome/browser/android/vr_shell/vr_core_info.h", "//chrome/browser/android/vr_shell/vr_core_info.h",
"//chrome/browser/android/vr_shell/vr_shell_delegate.h",
"//chrome/browser/vr/ui_unsupported_mode.h", "//chrome/browser/vr/ui_unsupported_mode.h",
] ]
} }
......
...@@ -86,7 +86,7 @@ public class VrIntentUtils { ...@@ -86,7 +86,7 @@ public class VrIntentUtils {
int supportLevel = int supportLevel =
VrShellDelegate.getVrSupportLevel(wrapper.createVrDaydreamApi(context), VrShellDelegate.getVrSupportLevel(wrapper.createVrDaydreamApi(context),
wrapper.createVrCoreVersionChecker(), null); wrapper.createVrCoreVersionChecker(), null);
return supportLevel == VrShellDelegate.VR_DAYDREAM; return supportLevel == VrSupportLevel.VR_DAYDREAM;
} }
}; };
} }
......
...@@ -93,15 +93,6 @@ public class VrShellDelegate ...@@ -93,15 +93,6 @@ public class VrShellDelegate
@IntDef({ENTER_VR_NOT_NECESSARY, ENTER_VR_CANCELLED, ENTER_VR_REQUESTED, ENTER_VR_SUCCEEDED}) @IntDef({ENTER_VR_NOT_NECESSARY, ENTER_VR_CANCELLED, ENTER_VR_REQUESTED, ENTER_VR_SUCCEEDED})
private @interface EnterVRResult {} private @interface EnterVRResult {}
private static final int VR_NOT_AVAILABLE = 0;
private static final int VR_CARDBOARD = 1;
/* package */
static final int VR_DAYDREAM = 2; // Supports both Cardboard and Daydream viewer.
@Retention(RetentionPolicy.SOURCE)
@IntDef({VR_NOT_AVAILABLE, VR_CARDBOARD, VR_DAYDREAM})
private @interface VrSupportLevel {}
// Linter and formatter disagree on how the line below should be formatted. // Linter and formatter disagree on how the line below should be formatted.
/* package */ /* package */
static final String VR_ENTRY_RESULT_ACTION = static final String VR_ENTRY_RESULT_ACTION =
...@@ -126,8 +117,7 @@ public class VrShellDelegate ...@@ -126,8 +117,7 @@ public class VrShellDelegate
private ChromeActivity mActivity; private ChromeActivity mActivity;
@VrSupportLevel private @VrSupportLevel int mVrSupportLevel;
private int mVrSupportLevel;
private int mCachedVrCorePackageVersion; private int mCachedVrCorePackageVersion;
// How often to prompt the user to enter VR feedback. // How often to prompt the user to enter VR feedback.
...@@ -322,12 +312,12 @@ public class VrShellDelegate ...@@ -322,12 +312,12 @@ public class VrShellDelegate
// support those devices. // support those devices.
if (versionChecker == null || daydreamApi == null || daydreamApi.bootsToVr() if (versionChecker == null || daydreamApi == null || daydreamApi.bootsToVr()
|| !isVrCoreCompatible(versionChecker, tabToShowInfobarIn)) { || !isVrCoreCompatible(versionChecker, tabToShowInfobarIn)) {
return VR_NOT_AVAILABLE; return VrSupportLevel.VR_NOT_AVAILABLE;
} }
if (daydreamApi.isDaydreamReadyDevice()) return VR_DAYDREAM; if (daydreamApi.isDaydreamReadyDevice()) return VrSupportLevel.VR_DAYDREAM;
return VR_CARDBOARD; return VrSupportLevel.VR_CARDBOARD;
} }
/** /**
...@@ -567,7 +557,7 @@ public class VrShellDelegate ...@@ -567,7 +557,7 @@ public class VrShellDelegate
/* package */ static boolean isVrShellEnabled(int vrSupportLevel) { /* package */ static boolean isVrShellEnabled(int vrSupportLevel) {
// Only enable ChromeVR (VrShell) on Daydream devices as it currently needs a Daydream // Only enable ChromeVR (VrShell) on Daydream devices as it currently needs a Daydream
// controller. // controller.
if (vrSupportLevel != VR_DAYDREAM) return false; if (vrSupportLevel != VrSupportLevel.VR_DAYDREAM) return false;
if (deviceChangesDensityInVr()) return false; if (deviceChangesDensityInVr()) return false;
return ChromeFeatureList.isEnabled(ChromeFeatureList.VR_BROWSING); return ChromeFeatureList.isEnabled(ChromeFeatureList.VR_BROWSING);
} }
...@@ -577,7 +567,7 @@ public class VrShellDelegate ...@@ -577,7 +567,7 @@ public class VrShellDelegate
// used or created by VR browsing will be broken. // used or created by VR browsing will be broken.
if (sInstance != null) { if (sInstance != null) {
if (sInstance.mExpectedDensityChange != 0) return true; if (sInstance.mExpectedDensityChange != 0) return true;
if (sInstance.mVrSupportLevel != VR_DAYDREAM) return false; if (sInstance.mVrSupportLevel != VrSupportLevel.VR_DAYDREAM) return false;
} }
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false;
...@@ -688,7 +678,7 @@ public class VrShellDelegate ...@@ -688,7 +678,7 @@ public class VrShellDelegate
private void maybeUpdateVrSupportLevel() { private void maybeUpdateVrSupportLevel() {
// If we're on Daydream support level, Chrome will get restarted by Android in response to // If we're on Daydream support level, Chrome will get restarted by Android in response to
// VrCore being updated/downgraded, so we don't need to check. // VrCore being updated/downgraded, so we don't need to check.
if (mVrSupportLevel == VR_DAYDREAM) return; if (mVrSupportLevel == VrSupportLevel.VR_DAYDREAM) return;
if (mVrClassesWrapper == null) return; if (mVrClassesWrapper == null) return;
int version = getVrCorePackageVersion(); int version = getVrCorePackageVersion();
// If VrCore package hasn't changed, no need to update. // If VrCore package hasn't changed, no need to update.
...@@ -708,7 +698,7 @@ public class VrShellDelegate ...@@ -708,7 +698,7 @@ public class VrShellDelegate
// TODO(bshe): Find a place to call this function again, i.e. page refresh or onResume. // TODO(bshe): Find a place to call this function again, i.e. page refresh or onResume.
private void updateVrSupportLevel(Integer vrCorePackageVersion) { private void updateVrSupportLevel(Integer vrCorePackageVersion) {
if (mVrClassesWrapper == null) { if (mVrClassesWrapper == null) {
mVrSupportLevel = VR_NOT_AVAILABLE; mVrSupportLevel = VrSupportLevel.VR_NOT_AVAILABLE;
return; return;
} }
if (vrCorePackageVersion == null) vrCorePackageVersion = getVrCorePackageVersion(); if (vrCorePackageVersion == null) vrCorePackageVersion = getVrCorePackageVersion();
...@@ -726,6 +716,7 @@ public class VrShellDelegate ...@@ -726,6 +716,7 @@ public class VrShellDelegate
mVrSupportLevel = supportLevel; mVrSupportLevel = supportLevel;
} }
@CalledByNative
@VrSupportLevel @VrSupportLevel
/* package */ int getVrSupportLevel() { /* package */ int getVrSupportLevel() {
return mVrSupportLevel; return mVrSupportLevel;
...@@ -741,7 +732,7 @@ public class VrShellDelegate ...@@ -741,7 +732,7 @@ public class VrShellDelegate
* Returns whether the device has support for Daydream. * Returns whether the device has support for Daydream.
*/ */
/* package */ boolean hasDaydreamSupport() { /* package */ boolean hasDaydreamSupport() {
return mVrSupportLevel == VR_DAYDREAM; return mVrSupportLevel == VrSupportLevel.VR_DAYDREAM;
} }
private void maybeSetPresentResult(boolean result, boolean donCompleted) { private void maybeSetPresentResult(boolean result, boolean donCompleted) {
...@@ -932,7 +923,7 @@ public class VrShellDelegate ...@@ -932,7 +923,7 @@ public class VrShellDelegate
if (VrIntentUtils.getHandlerInstance().isTrustedDaydreamIntent(intent)) { if (VrIntentUtils.getHandlerInstance().isTrustedDaydreamIntent(intent)) {
if (DEBUG_LOGS) Log.i(TAG, "onNewIntentWithNative: autopresent"); if (DEBUG_LOGS) Log.i(TAG, "onNewIntentWithNative: autopresent");
assert activitySupportsAutopresentation(activity); assert activitySupportsAutopresentation(activity);
assert instance.getVrSupportLevel() == VR_DAYDREAM; assert instance.getVrSupportLevel() == VrSupportLevel.VR_DAYDREAM;
instance.mAutopresentWebVr = true; instance.mAutopresentWebVr = true;
if (!ChromeFeatureList.isEnabled(ChromeFeatureList.WEBVR_AUTOPRESENT_FROM_INTENT)) { if (!ChromeFeatureList.isEnabled(ChromeFeatureList.WEBVR_AUTOPRESENT_FROM_INTENT)) {
instance.onEnterVrUnsupported(); instance.onEnterVrUnsupported();
...@@ -1066,7 +1057,8 @@ public class VrShellDelegate ...@@ -1066,7 +1057,8 @@ public class VrShellDelegate
/* package */ boolean canEnterVr(Tab tab, boolean justCompletedDon) { /* package */ boolean canEnterVr(Tab tab, boolean justCompletedDon) {
if (!LibraryLoader.isInitialized()) return false; if (!LibraryLoader.isInitialized()) return false;
if (mVrSupportLevel == VR_NOT_AVAILABLE || mNativeVrShellDelegate == 0) return false; if (mVrSupportLevel == VrSupportLevel.VR_NOT_AVAILABLE || mNativeVrShellDelegate == 0)
return false;
// If vr shell is not enabled and this is not a web vr request, then return false. // If vr shell is not enabled and this is not a web vr request, then return false.
boolean presenting = mRequestedWebVr || mListeningForWebVrActivate boolean presenting = mRequestedWebVr || mListeningForWebVrActivate
...@@ -1114,9 +1106,9 @@ public class VrShellDelegate ...@@ -1114,9 +1106,9 @@ public class VrShellDelegate
// Update VR support level as it can change at runtime // Update VR support level as it can change at runtime
maybeUpdateVrSupportLevel(); maybeUpdateVrSupportLevel();
if (mVrSupportLevel == VR_NOT_AVAILABLE) return ENTER_VR_CANCELLED; if (mVrSupportLevel == VrSupportLevel.VR_NOT_AVAILABLE) return ENTER_VR_CANCELLED;
if (!canEnterVr(mActivity.getActivityTab(), false)) return ENTER_VR_CANCELLED; if (!canEnterVr(mActivity.getActivityTab(), false)) return ENTER_VR_CANCELLED;
if (mVrSupportLevel == VR_DAYDREAM && isDaydreamCurrentViewer()) { if (mVrSupportLevel == VrSupportLevel.VR_DAYDREAM && isDaydreamCurrentViewer()) {
// TODO(mthiesse): This is a workaround for b/66486878 (see also crbug.com/767594). // TODO(mthiesse): This is a workaround for b/66486878 (see also crbug.com/767594).
// We have to trigger the DON flow before setting VR mode enabled to prevent the DON // We have to trigger the DON flow before setting VR mode enabled to prevent the DON
// flow from failing on the S8/S8+. // flow from failing on the S8/S8+.
...@@ -1220,7 +1212,7 @@ public class VrShellDelegate ...@@ -1220,7 +1212,7 @@ public class VrShellDelegate
StrictMode.setThreadPolicy(oldPolicy); StrictMode.setThreadPolicy(oldPolicy);
} }
if (mVrSupportLevel != VR_DAYDREAM) return; if (mVrSupportLevel != VrSupportLevel.VR_DAYDREAM) return;
if (isVrShellEnabled(mVrSupportLevel) && activitySupportsVrBrowsing(mActivity)) { if (isVrShellEnabled(mVrSupportLevel) && activitySupportsVrBrowsing(mActivity)) {
// Perform slow initialization asynchronously. // Perform slow initialization asynchronously.
new Handler().post(new Runnable() { new Handler().post(new Runnable() {
...@@ -1309,7 +1301,7 @@ public class VrShellDelegate ...@@ -1309,7 +1301,7 @@ public class VrShellDelegate
if (mCancellingEntryAnimation) return; if (mCancellingEntryAnimation) return;
mExpectPauseOrDonSucceeded.removeCallbacksAndMessages(null); mExpectPauseOrDonSucceeded.removeCallbacksAndMessages(null);
unregisterDaydreamIntent(mVrDaydreamApi); unregisterDaydreamIntent(mVrDaydreamApi);
if (mVrSupportLevel == VR_NOT_AVAILABLE) return; if (mVrSupportLevel == VrSupportLevel.VR_NOT_AVAILABLE) return;
// TODO(ymalik): We should be able to remove this if we handle it for multi-window in // TODO(ymalik): We should be able to remove this if we handle it for multi-window in
// {@link onMultiWindowModeChanged} since we're calling it in onStop. // {@link onMultiWindowModeChanged} since we're calling it in onStop.
...@@ -1342,7 +1334,7 @@ public class VrShellDelegate ...@@ -1342,7 +1334,7 @@ public class VrShellDelegate
} }
private boolean onBackPressedInternal() { private boolean onBackPressedInternal() {
if (mVrSupportLevel == VR_NOT_AVAILABLE) return false; if (mVrSupportLevel == VrSupportLevel.VR_NOT_AVAILABLE) return false;
cancelPendingVrEntry(); cancelPendingVrEntry();
if (!mInVr) return false; if (!mInVr) return false;
// Back button should be handled the same way as the close button. // Back button should be handled the same way as the close button.
...@@ -1365,7 +1357,7 @@ public class VrShellDelegate ...@@ -1365,7 +1357,7 @@ public class VrShellDelegate
} }
private void onExitVrResult(boolean success) { private void onExitVrResult(boolean success) {
assert mVrSupportLevel != VR_NOT_AVAILABLE; assert mVrSupportLevel != VrSupportLevel.VR_NOT_AVAILABLE;
// We may have manually handled the exit early by swapping to another Chrome activity that // We may have manually handled the exit early by swapping to another Chrome activity that
// supports VR while in the DOFF activity. If that happens we want to exit early when the // supports VR while in the DOFF activity. If that happens we want to exit early when the
...@@ -1400,7 +1392,7 @@ public class VrShellDelegate ...@@ -1400,7 +1392,7 @@ public class VrShellDelegate
if (DEBUG_LOGS) Log.i(TAG, "WebVR page listening for vrdisplayactivate: " + listening); if (DEBUG_LOGS) Log.i(TAG, "WebVR page listening for vrdisplayactivate: " + listening);
// Non-Daydream devices may not have the concept of display activate. So disable // Non-Daydream devices may not have the concept of display activate. So disable
// mListeningForWebVrActivate for them. // mListeningForWebVrActivate for them.
if (mVrSupportLevel != VR_DAYDREAM) return; if (mVrSupportLevel != VrSupportLevel.VR_DAYDREAM) return;
mListeningForWebVrActivate = listening; mListeningForWebVrActivate = listening;
if (mPaused) return; if (mPaused) return;
if (listening) { if (listening) {
......
...@@ -181,12 +181,20 @@ void VrShellDelegate::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { ...@@ -181,12 +181,20 @@ void VrShellDelegate::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
delete this; delete this;
} }
bool VrShellDelegate::ShouldDisableGvrDevice() {
JNIEnv* env = AttachCurrentThread();
int vr_support_level =
Java_VrShellDelegate_getVrSupportLevel(env, j_vr_shell_delegate_);
return static_cast<VrSupportLevel>(vr_support_level) ==
VrSupportLevel::kVrNotAvailable;
}
void VrShellDelegate::SetDeviceId(unsigned int device_id) { void VrShellDelegate::SetDeviceId(unsigned int device_id) {
device_id_ = device_id; device_id_ = device_id;
if (vr_shell_) { if (vr_shell_) {
device::VRDevice* device = GetDevice(); device::VRDevice* device = GetDevice();
// See comment in VrShellDelegate::SetDelegate. This handles the case where // See comment in VrShellDelegate::SetDelegate. This handles the case where
// VrShell is created before the device/ code is initialized (like when // VrShell is created before the device code is initialized (like when
// entering VR browsing on a non-webVR page). // entering VR browsing on a non-webVR page).
if (device) if (device)
device->SetMagicWindowEnabled(false); device->SetMagicWindowEnabled(false);
......
...@@ -25,6 +25,13 @@ class VRDevice; ...@@ -25,6 +25,13 @@ class VRDevice;
namespace vr_shell { namespace vr_shell {
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.vr_shell
enum class VrSupportLevel : int {
kVrNotAvailable = 0,
kVrCardboard = 1,
kVrDaydream = 2, // Supports both Cardboard and Daydream viewer.
};
class VrShell; class VrShell;
class VrShellDelegate : public device::GvrDelegateProvider { class VrShellDelegate : public device::GvrDelegateProvider {
...@@ -59,6 +66,7 @@ class VrShellDelegate : public device::GvrDelegateProvider { ...@@ -59,6 +66,7 @@ class VrShellDelegate : public device::GvrDelegateProvider {
private: private:
// device::GvrDelegateProvider implementation. // device::GvrDelegateProvider implementation.
bool ShouldDisableGvrDevice() override;
void SetDeviceId(unsigned int device_id) override; void SetDeviceId(unsigned int device_id) override;
void RequestWebVRPresent(device::mojom::VRSubmitFrameClientPtr submit_client, void RequestWebVRPresent(device::mojom::VRSubmitFrameClientPtr submit_client,
device::mojom::VRPresentationProviderRequest request, device::mojom::VRPresentationProviderRequest request,
......
...@@ -17,6 +17,7 @@ namespace device { ...@@ -17,6 +17,7 @@ namespace device {
class DEVICE_VR_EXPORT GvrDelegateProvider { class DEVICE_VR_EXPORT GvrDelegateProvider {
public: public:
GvrDelegateProvider() = default; GvrDelegateProvider() = default;
virtual bool ShouldDisableGvrDevice() = 0;
virtual void SetDeviceId(unsigned int device_id) = 0; virtual void SetDeviceId(unsigned int device_id) = 0;
virtual void RequestWebVRPresent(mojom::VRSubmitFrameClientPtr submit_client, virtual void RequestWebVRPresent(mojom::VRSubmitFrameClientPtr submit_client,
mojom::VRPresentationProviderRequest request, mojom::VRPresentationProviderRequest request,
......
...@@ -125,7 +125,9 @@ std::unique_ptr<GvrDevice> GvrDevice::Create() { ...@@ -125,7 +125,9 @@ std::unique_ptr<GvrDevice> GvrDevice::Create() {
} }
GvrDevice::GvrDevice() : weak_ptr_factory_(this) { GvrDevice::GvrDevice() : weak_ptr_factory_(this) {
GetGvrDelegateProvider(); GvrDelegateProvider* delegate_provider = GetGvrDelegateProvider();
if (delegate_provider->ShouldDisableGvrDevice())
return;
JNIEnv* env = base::android::AttachCurrentThread(); JNIEnv* env = base::android::AttachCurrentThread();
non_presenting_context_.Reset( non_presenting_context_.Reset(
Java_NonPresentingGvrContext_create(env, reinterpret_cast<jlong>(this))); Java_NonPresentingGvrContext_create(env, reinterpret_cast<jlong>(this)));
......
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