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); |
} |