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 1ef57a6810282461ee145b1486639530045d5a9f..14e581a7f4df3e5d4bb4bc3439cc39ac157e6d85 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 |
@@ -40,6 +40,10 @@ public class VrShellDelegate { |
// Pseudo-random number to avoid request id collisions. |
public static final int EXIT_VR_RESULT = 721251; |
+ public static final int ENTER_VR_NOT_NECESSARY = 0; |
Ted C
2016/11/16 22:20:51
For these, take a look at IntDef's as a way of mak
|
+ 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"; |
@@ -48,16 +52,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; |
@@ -80,8 +80,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) { |
@@ -105,9 +110,8 @@ public class VrShellDelegate { |
* class can be initialized. |
*/ |
public void onNativeLibraryReady() { |
- if (mVrAvailable) { |
- mNativeVrShellDelegate = nativeInit(); |
- } |
+ if (!mVrAvailable) return; |
+ mNativeVrShellDelegate = nativeInit(); |
} |
@SuppressWarnings("unchecked") |
@@ -135,27 +139,26 @@ public class VrShellDelegate { |
/** |
* Handle a VR intent, entering VR in the process. |
*/ |
- 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); |
- 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); |
@@ -163,25 +166,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 |
@@ -197,28 +202,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 |
@@ -236,6 +248,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(); |
} |
@@ -265,7 +280,7 @@ public class VrShellDelegate { |
StrictMode.setThreadPolicy(oldPolicy); |
} |
} else if (mLastVRExit + REENTER_VR_TIMEOUT_MS > SystemClock.uptimeMillis()) { |
- enterVRIfNecessary(mRequestedWebVR); |
+ enterVRIfNecessary(); |
} |
} |
@@ -273,9 +288,8 @@ public class VrShellDelegate { |
* Pauses VR Shell. |
*/ |
public void maybePauseVR() { |
- if (isVrShellEnabled()) { |
- unregisterDaydreamIntent(); |
- } |
+ if (!mVrAvailable) return; |
+ unregisterDaydreamIntent(); |
if (mNonPresentingGvrContext != null) { |
mNonPresentingGvrContext.pause(); |
@@ -292,6 +306,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); |
@@ -300,6 +315,7 @@ public class VrShellDelegate { |
} |
public void onExitVRResult(int resultCode) { |
+ assert mVrAvailable; |
if (resultCode == Activity.RESULT_OK) { |
mVrDaydreamApi.setVrModeEnabled(false); |
} else { |
@@ -308,33 +324,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 |
@@ -366,6 +371,7 @@ public class VrShellDelegate { |
*/ |
private void shutdownVR(boolean returnTo2D) { |
if (!mInVr) return; |
+ mRequestedWebVR = false; |
if (returnTo2D) { |
mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new Intent()); |
} else { |
@@ -399,22 +405,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; |
@@ -513,13 +517,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 |
@@ -529,4 +526,5 @@ public class VrShellDelegate { |
private native long nativeInit(); |
private native void nativeExitWebVRIfNecessary(long nativeVrShellDelegate); |
+ private native void nativeSetPresentResult(long nativeVrShellDelegate, boolean result); |
} |