| Index: chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
|
| index 04c5f7670bb7dede86a36c218ad3de295b252681..91dd8f0674072b14f498f19f0ebdaa7508458846 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
|
| @@ -39,6 +39,10 @@ public class VrShellDelegate {
|
| private static final String TAG = "VrShellDelegate";
|
| public static final int EXIT_VR_RESULT = 102;
|
|
|
| + public static final int ENTER_VR_NOT_NECESSARY = 0;
|
| + public static final int ENTER_VR_CANCELLED = 1;
|
| + public static final int ENTER_VR_REQUESTED = 2;
|
| +
|
| // TODO(bshe): These should be replaced by string provided by NDK. Currently, it only available
|
| // in SDK and we don't want add dependency to SDK just to get these strings.
|
| private static final String DAYDREAM_VR_EXTRA = "android.intent.extra.VR_LAUNCH";
|
| @@ -47,16 +51,12 @@ public class VrShellDelegate {
|
|
|
| private static final String VR_ACTIVITY_ALIAS =
|
| "org.chromium.chrome.browser.VRChromeTabbedActivity";
|
| - private static final String DAYDREAM_DON_TYPE = "DAYDREAM_DON_TYPE";
|
| -
|
| - private static final int DAYDREAM_DON_TYPE_VR_SHELL = 0;
|
| - private static final int DAYDREAM_DON_TYPE_WEBVR = 1;
|
| - private static final int DAYDREAM_DON_TYPE_AUTO = 2;
|
|
|
| private static final long REENTER_VR_TIMEOUT_MS = 1000;
|
|
|
| private final ChromeTabbedActivity mActivity;
|
| private final TabObserver mTabObserver;
|
| + private final Intent mEnterVRIntent;
|
|
|
| private boolean mVrAvailable;
|
| private Boolean mVrShellEnabled;
|
| @@ -79,8 +79,13 @@ public class VrShellDelegate {
|
|
|
| public VrShellDelegate(ChromeTabbedActivity activity) {
|
| mActivity = activity;
|
| - mVrAvailable = maybeFindVrClasses() && isVrCoreCompatible();
|
| - createVrDaydreamApi();
|
| + mVrAvailable = maybeFindVrClasses() && isVrCoreCompatible() && createVrDaydreamApi();
|
| + if (mVrAvailable) {
|
| + mEnterVRIntent = mVrDaydreamApi.createVrIntent(
|
| + new ComponentName(mActivity, VR_ACTIVITY_ALIAS));
|
| + } else {
|
| + mEnterVRIntent = null;
|
| + }
|
| mTabObserver = new EmptyTabObserver() {
|
| @Override
|
| public void onContentChanged(Tab tab) {
|
| @@ -104,9 +109,8 @@ public class VrShellDelegate {
|
| * class can be initialized.
|
| */
|
| public void onNativeLibraryReady() {
|
| - if (mVrAvailable) {
|
| - mNativeVrShellDelegate = nativeInit();
|
| - }
|
| + if (!mVrAvailable) return;
|
| + mNativeVrShellDelegate = nativeInit();
|
| }
|
|
|
| @SuppressWarnings("unchecked")
|
| @@ -131,26 +135,26 @@ public class VrShellDelegate {
|
| }
|
| }
|
|
|
| - public boolean enterVRFromIntent(Intent intent) {
|
| + public void enterVRFromIntent(Intent intent) {
|
| + if (!mVrAvailable) return;
|
| assert isVrIntent(intent);
|
| - int transitionType = intent.getIntExtra(DAYDREAM_DON_TYPE, DAYDREAM_DON_TYPE_VR_SHELL);
|
| - mActivity.setIntent(null);
|
| - if (!isVrShellEnabled()) assert transitionType != DAYDREAM_DON_TYPE_VR_SHELL;
|
| + if (enterVR()) {
|
| + nativeSetPresentResult(mNativeVrShellDelegate, true);
|
| + if (mRequestedWebVR) mVrShell.setWebVrModeEnabled(true);
|
| + } else {
|
| + nativeSetPresentResult(mNativeVrShellDelegate, false);
|
| + mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new Intent());
|
| + }
|
|
|
| - boolean inWebVR = transitionType == DAYDREAM_DON_TYPE_WEBVR
|
| - || (transitionType == DAYDREAM_DON_TYPE_AUTO
|
| - && (!isVrShellEnabled() || mRequestedWebVR));
|
| - Tab tab = mActivity.getActivityTab();
|
| - if (!canEnterVR(inWebVR, tab)) return false;
|
| + mRequestedWebVR = false;
|
| + }
|
|
|
| - // TODO(mthiesse): We should handle switching between webVR and VR Shell mode through
|
| - // intents.
|
| + private boolean enterVR() {
|
| if (mInVr) return true;
|
| -
|
| mVrDaydreamApi.setVrModeEnabled(true);
|
|
|
| - mTab = tab;
|
| - mTab.addObserver(mTabObserver);
|
| + Tab tab = mActivity.getActivityTab();
|
| + if (!canEnterVR(tab)) return false;
|
|
|
| mRestoreOrientation = mActivity.getRequestedOrientation();
|
| mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
| @@ -158,25 +162,27 @@ public class VrShellDelegate {
|
| mActivity.setRequestedOrientation(mRestoreOrientation);
|
| return false;
|
| }
|
| + mInVr = true;
|
| + mTab = tab;
|
| + mTab.addObserver(mTabObserver);
|
| addVrViews();
|
| setupVrModeWindowFlags();
|
| mVrShell.initializeNative(mTab, this);
|
| - if (inWebVR) mVrShell.setWebVrModeEnabled(true);
|
| // onResume needs to be called on GvrLayout after initialization to make sure DON flow work
|
| // properly.
|
| mVrShell.resume();
|
| - mInVr = true;
|
| mTab.updateFullscreenEnabledState();
|
| return true;
|
| }
|
|
|
| - private boolean canEnterVR(boolean inWebVR, Tab tab) {
|
| + private boolean canEnterVR(Tab tab) {
|
| if (!LibraryLoader.isInitialized()) {
|
| return false;
|
| }
|
| // If vr isn't in the build, or we haven't initialized yet, or vr shell is not enabled and
|
| // this is not a web vr request, then return immediately.
|
| - if (!mVrAvailable || mNativeVrShellDelegate == 0 || (!isVrShellEnabled() && !inWebVR)) {
|
| + if (!mVrAvailable || mNativeVrShellDelegate == 0
|
| + || (!isVrShellEnabled() && !mRequestedWebVR)) {
|
| return false;
|
| }
|
| // TODO(mthiesse): When we have VR UI for opening new tabs, etc., allow VR Shell to be
|
| @@ -192,28 +198,35 @@ public class VrShellDelegate {
|
| return true;
|
| }
|
|
|
| - /**
|
| - * Enters VR Shell, displaying browser UI and tab contents in VR.
|
| - *
|
| - * @param inWebVR If true should begin displaying WebVR content rather than the VrShell UI.
|
| - */
|
| @CalledByNative
|
| - public void enterVRIfNecessary(boolean inWebVR) {
|
| - if (mInVr) {
|
| - if (inWebVR) mVrShell.setWebVrModeEnabled(true);
|
| - return;
|
| + private void presentRequested(boolean inWebVR) {
|
| + switch (enterVRIfNecessary()) {
|
| + case ENTER_VR_NOT_NECESSARY:
|
| + mVrShell.setWebVrModeEnabled(true);
|
| + nativeSetPresentResult(mNativeVrShellDelegate, true);
|
| + break;
|
| + case ENTER_VR_CANCELLED:
|
| + nativeSetPresentResult(mNativeVrShellDelegate, false);
|
| + break;
|
| + case ENTER_VR_REQUESTED:
|
| + // TODO(mthiesse): There's a GVR bug where they're not calling us back with the
|
| + // intent we ask them to when we call DaydreamApi#launchInVr. As a temporary hack,
|
| + // remember locally that we want to enter webVR.
|
| + mRequestedWebVR = inWebVR;
|
| + break;
|
| }
|
| - if (!canEnterVR(inWebVR, mActivity.getActivityTab())) return;
|
| + }
|
|
|
| - // TODO(mthiesse): There's a GVR bug where they're not calling us back with the intent we
|
| - // ask them to when we call DaydreamApi#launchInVr. As a temporary hack, remember locally
|
| - // that we want to enter webVR.
|
| - mRequestedWebVR = inWebVR;
|
| - Intent intent = createDaydreamIntent(
|
| - inWebVR ? DAYDREAM_DON_TYPE_WEBVR : DAYDREAM_DON_TYPE_VR_SHELL);
|
| + /**
|
| + * Enters VR Shell if necessary, displaying browser UI and tab contents in VR.
|
| + */
|
| + public int enterVRIfNecessary() {
|
| + if (!mVrAvailable) return ENTER_VR_CANCELLED;
|
| + if (mInVr) return ENTER_VR_NOT_NECESSARY;
|
| + if (!canEnterVR(mActivity.getActivityTab())) return ENTER_VR_CANCELLED;
|
|
|
| - mVrDaydreamApi.launchInVr(
|
| - PendingIntent.getActivity(mActivity, 0, intent, PendingIntent.FLAG_ONE_SHOT));
|
| + mVrDaydreamApi.launchInVr(getPendingEnterVRIntent());
|
| + return ENTER_VR_REQUESTED;
|
| }
|
|
|
| @CalledByNative
|
| @@ -231,6 +244,9 @@ public class VrShellDelegate {
|
| * Resumes VR Shell.
|
| */
|
| public void maybeResumeVR() {
|
| + if (!mVrAvailable) return;
|
| + // TODO(mthiesse): Register the intent when on a page that supports WebVR, even if VrShell
|
| + // isn't enabled.
|
| if (isVrShellEnabled()) {
|
| registerDaydreamIntent();
|
| }
|
| @@ -260,7 +276,7 @@ public class VrShellDelegate {
|
| StrictMode.setThreadPolicy(oldPolicy);
|
| }
|
| } else if (mLastVRExit + REENTER_VR_TIMEOUT_MS > SystemClock.uptimeMillis()) {
|
| - enterVRIfNecessary(mRequestedWebVR);
|
| + enterVRIfNecessary();
|
| }
|
| }
|
|
|
| @@ -268,9 +284,8 @@ public class VrShellDelegate {
|
| * Pauses VR Shell.
|
| */
|
| public void maybePauseVR() {
|
| - if (isVrShellEnabled()) {
|
| - unregisterDaydreamIntent();
|
| - }
|
| + if (!mVrAvailable) return;
|
| + unregisterDaydreamIntent();
|
|
|
| if (mNonPresentingGvrContext != null) {
|
| mNonPresentingGvrContext.pause();
|
| @@ -287,6 +302,7 @@ public class VrShellDelegate {
|
| * @return Whether or not we exited VR.
|
| */
|
| public boolean exitVRIfNecessary(boolean returnTo2D) {
|
| + if (!mVrAvailable) return false;
|
| if (!mInVr) return false;
|
| // If WebVR is presenting instruct it to exit.
|
| nativeExitWebVRIfNecessary(mNativeVrShellDelegate);
|
| @@ -295,6 +311,7 @@ public class VrShellDelegate {
|
| }
|
|
|
| public void onExitVRResult(int resultCode) {
|
| + assert mVrAvailable;
|
| if (resultCode == Activity.RESULT_OK) {
|
| mVrDaydreamApi.setVrModeEnabled(false);
|
| } else {
|
| @@ -303,33 +320,22 @@ public class VrShellDelegate {
|
| }
|
| }
|
|
|
| - private Intent createDaydreamIntent(int transitionType) {
|
| - if (mVrDaydreamApi == null) return null;
|
| - // TODO(bshe): Ideally, this should go through ChromeLauncherActivity. To avoid polluting
|
| - // metrics, use the VR Activity alias for now.
|
| - Intent intent = mVrDaydreamApi.createVrIntent(
|
| - new ComponentName(mActivity, VR_ACTIVITY_ALIAS));
|
| - intent.putExtra(DAYDREAM_DON_TYPE, transitionType);
|
| - return intent;
|
| + private PendingIntent getPendingEnterVRIntent() {
|
| + return PendingIntent.getActivity(mActivity, 0, mEnterVRIntent, PendingIntent.FLAG_ONE_SHOT);
|
| }
|
|
|
| /**
|
| * Registers the Intent to fire after phone inserted into a headset.
|
| */
|
| private void registerDaydreamIntent() {
|
| - if (mVrDaydreamApi == null) return;
|
| - Intent intent = createDaydreamIntent(DAYDREAM_DON_TYPE_AUTO);
|
| - mVrDaydreamApi.registerDaydreamIntent(
|
| - PendingIntent.getActivity(mActivity, 0, intent, PendingIntent.FLAG_ONE_SHOT));
|
| + mVrDaydreamApi.registerDaydreamIntent(getPendingEnterVRIntent());
|
| }
|
|
|
| /**
|
| * Unregisters the Intent which registered by this context if any.
|
| */
|
| private void unregisterDaydreamIntent() {
|
| - if (mVrDaydreamApi != null) {
|
| - mVrDaydreamApi.unregisterDaydreamIntent();
|
| - }
|
| + mVrDaydreamApi.unregisterDaydreamIntent();
|
| }
|
|
|
| @CalledByNative
|
| @@ -394,22 +400,20 @@ public class VrShellDelegate {
|
| (VrCoreVersionChecker) mVrCoreVersionCheckerConstructor.newInstance();
|
| } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
|
| | InvocationTargetException | NoSuchMethodException e) {
|
| - Log.e(TAG, "Unable to instantiate VrCoreVersionChecker", e);
|
| + Log.d(TAG, "Unable to instantiate VrCoreVersionChecker", e);
|
| return false;
|
| }
|
| return mVrCoreVersionChecker.isVrCoreCompatible();
|
| }
|
|
|
| private boolean createVrDaydreamApi() {
|
| - if (!mVrAvailable) return false;
|
| -
|
| try {
|
| Constructor<?> vrPrivateApiConstructor =
|
| mVrDaydreamApiClass.getConstructor(Activity.class);
|
| mVrDaydreamApi = (VrDaydreamApi) vrPrivateApiConstructor.newInstance(mActivity);
|
| } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
|
| - | InvocationTargetException | NoSuchMethodException e) {
|
| - Log.e(TAG, "Unable to instantiate VrDaydreamApi", e);
|
| + | InvocationTargetException | NoSuchMethodException | SecurityException e) {
|
| + Log.d(TAG, "Unable to instantiate VrDaydreamApi", e);
|
| return false;
|
| }
|
| return true;
|
| @@ -508,13 +512,6 @@ public class VrShellDelegate {
|
| }
|
|
|
| /**
|
| - * @return Whether or not VR Shell is currently enabled.
|
| - */
|
| - public boolean isVrInitialized() {
|
| - return mVrDaydreamApi != null;
|
| - }
|
| -
|
| - /**
|
| * @return Pointer to the native VrShellDelegate object.
|
| */
|
| @CalledByNative
|
| @@ -524,4 +521,5 @@ public class VrShellDelegate {
|
|
|
| private native long nativeInit();
|
| private native void nativeExitWebVRIfNecessary(long nativeVrShellDelegate);
|
| + private native void nativeSetPresentResult(long nativeVrShellDelegate, boolean result);
|
| }
|
|
|