Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2991)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java

Issue 2727873002: Implement lazy initialization for VrShellDelegate (Closed)
Patch Set: Fix FindBugs errors - neat! Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 9b2453af06c64873eef5cc97c17a0cc1c22064c0..8e3a6b3baead5999469e0e736a035f05c86fc1d3 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
@@ -26,12 +26,12 @@ import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.FrameLayout;
+import org.chromium.base.ApplicationStatus;
import org.chromium.base.Log;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.library_loader.LibraryLoader;
-
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.ChromeFeatureList;
@@ -43,6 +43,7 @@ import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
+import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModelUtils;
import java.lang.annotation.Retention;
@@ -90,8 +91,9 @@ public class VrShellDelegate {
private static final long REENTER_VR_TIMEOUT_MS = 1000;
- private final ChromeTabbedActivity mActivity;
- private Intent mEnterVRIntent;
+ private static VrShellDelegate sInstance;
+
+ private final ChromeActivity mActivity;
@VrSupportLevel
private int mVrSupportLevel;
@@ -101,6 +103,7 @@ public class VrShellDelegate {
private NonPresentingGvrContext mNonPresentingGvrContext;
private VrDaydreamApi mVrDaydreamApi;
private VrCoreVersionChecker mVrCoreVersionChecker;
+ private TabModelSelector mTabModelSelector;
private boolean mInVr;
private boolean mEnteringVr;
@@ -113,78 +116,152 @@ public class VrShellDelegate {
private boolean mListeningForWebVrActivate;
private boolean mListeningForWebVrActivateBeforePause;
- public VrShellDelegate(ChromeTabbedActivity activity) {
- mActivity = activity;
- mVrClassesWrapper = createVrClassesWrapper();
+ /**
+ * Called when the native library is first available.
+ */
+ public static void onNativeLibraryAvailable() {
+ nativeOnLibraryAvailable();
}
/**
- * Updates mVrSupportLevel to the correct value. isVrCoreCompatible might return different value
- * at runtime.
+ * @return A helper class for creating VR-specific classes that may not be available at compile
+ * time.
*/
- // TODO(bshe): Find a place to call this function again, i.e. page refresh or onResume.
- // TODO(mthiesse): Clean this function up, lots of duplicated code.
- private void updateVrSupportLevel() {
- if (mVrClassesWrapper == null || !isVrCoreCompatible()) {
- mVrSupportLevel = VR_NOT_AVAILABLE;
- mEnterVRIntent = null;
+ @VisibleForTesting
+ public static VrClassesWrapper getVrClassesWrapper() {
+ if (sInstance != null) return sInstance.mVrClassesWrapper;
+ return createVrClassesWrapper();
+ }
+
+ @VisibleForTesting
+ public static VrShellDelegate getInstanceForTesting() {
+ return getInstance();
+ }
+
+ /**
+ * Pauses VR Shell, if it needs to be paused.
+ */
+ public static void maybePauseVR(ChromeActivity activity) {
+ maybeUnregisterDaydreamIntent(activity);
+ if (sInstance == null) return;
+ if (sInstance.mActivity != activity) {
+ assert !sInstance.mInVr;
return;
}
+ sInstance.pauseVR();
+ }
- if (mVrDaydreamApi == null) {
- mVrDaydreamApi = mVrClassesWrapper.createVrDaydreamApi();
- }
-
- // Check cardboard support for non-daydream devices.
- if (!mVrDaydreamApi.isDaydreamReadyDevice()) {
- // Supported Build version is determined by the webvr cardboard support feature.
- // Default is KITKAT unless specified via server side finch config.
- if (Build.VERSION.SDK_INT < ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
- ChromeFeatureList.WEBVR_CARDBOARD_SUPPORT,
- MIN_SDK_VERSION_PARAM_NAME,
- Build.VERSION_CODES.KITKAT)) {
- mVrSupportLevel = VR_NOT_AVAILABLE;
- mEnterVRIntent = null;
- return;
- }
+ /**
+ * Resumes VR Shell, if it needs to be resumed.
+ */
+ public static void maybeResumeVR(ChromeActivity activity) {
+ maybeRegisterDaydreamIntent(activity);
+ if (sInstance == null) return;
+ if (sInstance.mActivity != activity) {
+ assert !sInstance.mInVr;
+ return;
}
+ sInstance.resumeVR();
+ }
+
+ /**
+ * Whether or not we are currently in VR.
+ */
+ public static boolean isInVR() {
+ if (sInstance == null) return false;
+ return sInstance.mInVr;
+ }
+
+ /**
+ * See {@link ChromeActivity#handleBackPressed}
+ * Only handles the back press while in VR.
+ */
+ public static boolean onBackPressed() {
+ if (sInstance == null) return false;
+ return sInstance.onBackPressedInternal();
+ }
- if (mEnterVRIntent == null) {
- mEnterVRIntent =
- mVrDaydreamApi.createVrIntent(new ComponentName(mActivity, VR_ACTIVITY_ALIAS));
+ /**
+ * Enters VR on the current tab if possible.
+ */
+ public static void enterVRIfNecessary() {
+ boolean created_delegate = sInstance == null;
+ VrShellDelegate instance = getInstance();
+ if (instance == null) return;
+ if (instance.enterVRInternal() == ENTER_VR_CANCELLED && created_delegate) {
+ instance.destroy();
}
- mVrSupportLevel = mVrDaydreamApi.isDaydreamReadyDevice() ? VR_DAYDREAM : VR_CARDBOARD;
}
/**
- * Should be called once the native library is loaded so that the native portion of this class
- * can be initialized.
+ * Handles a VR intent, entering VR in the process.
*/
- public void onNativeLibraryReady() {
- updateVrSupportLevel();
- if (mVrSupportLevel == VR_NOT_AVAILABLE) return;
- mNativeVrShellDelegate = nativeInit();
- Choreographer choreographer = Choreographer.getInstance();
- choreographer.postFrameCallback(new FrameCallback() {
- @Override
- public void doFrame(long frameTimeNanos) {
- Display display = ((WindowManager) mActivity.getSystemService(
- Context.WINDOW_SERVICE)).getDefaultDisplay();
- nativeUpdateVSyncInterval(mNativeVrShellDelegate, frameTimeNanos,
- 1.0d / display.getRefreshRate());
- }
- });
+ public static void enterVRFromIntent(Intent intent) {
+ assert isDaydreamVrIntent(intent);
+ boolean created_delegate = sInstance == null;
+ VrShellDelegate instance = getInstance();
+ if (instance == null) return;
+ if (!instance.enterVRFromIntent() && created_delegate) instance.destroy();
+ }
+
+ /**
+ * Whether or not the intent is a Daydream VR Intent.
+ */
+ public static boolean isDaydreamVrIntent(Intent intent) {
+ if (intent == null || intent.getCategories() == null) return false;
+ return intent.getCategories().contains(DAYDREAM_CATEGORY);
+ }
+
+ /**
+ * Handles the result of the exit VR flow (DOFF).
+ */
+ public static void onExitVRResult(int resultCode) {
+ if (sInstance == null) return;
+ sInstance.onExitVRResult(resultCode == Activity.RESULT_OK);
+ }
+
+ public static int getVrSupportLevel(VrDaydreamApi daydreamApi,
+ VrCoreVersionChecker versionChecker, Tab tabToShowInfobarIn) {
+ if (versionChecker == null || daydreamApi == null
+ || !isVrCoreCompatible(versionChecker, tabToShowInfobarIn)) {
+ return VR_NOT_AVAILABLE;
+ }
+
+ if (daydreamApi.isDaydreamReadyDevice()) return VR_DAYDREAM;
+
+ // Check cardboard support for non-daydream devices. Supported Build version is determined
+ // by the webvr cardboard support feature. Default is KITKAT unless specified via server
+ // side finch config.
+ if (Build.VERSION.SDK_INT < ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
+ ChromeFeatureList.WEBVR_CARDBOARD_SUPPORT,
+ MIN_SDK_VERSION_PARAM_NAME,
+ Build.VERSION_CODES.KITKAT)) {
+ return VR_NOT_AVAILABLE;
+ }
+
+ return VR_CARDBOARD;
+ }
+
+ @CalledByNative
+ private static VrShellDelegate getInstance() {
+ Activity activity = ApplicationStatus.getLastTrackedFocusedActivity();
+ if (sInstance != null && activity instanceof ChromeTabbedActivity) return sInstance;
+ if (!LibraryLoader.isInitialized()) return null;
+ // Note that we only support ChromeTabbedActivity for now.
+ if (activity == null || !(activity instanceof ChromeTabbedActivity)) return null;
+ sInstance = new VrShellDelegate((ChromeActivity) activity);
+
+ return sInstance;
}
@SuppressWarnings("unchecked")
- private VrClassesWrapper createVrClassesWrapper() {
+ private static VrClassesWrapper createVrClassesWrapper() {
try {
Class<? extends VrClassesWrapper> vrClassesBuilderClass =
(Class<? extends VrClassesWrapper>) Class.forName(
"org.chromium.chrome.browser.vr_shell.VrClassesWrapperImpl");
- Constructor<?> vrClassesBuilderConstructor =
- vrClassesBuilderClass.getConstructor(ChromeActivity.class);
- return (VrClassesWrapper) vrClassesBuilderConstructor.newInstance(mActivity);
+ Constructor<?> vrClassesBuilderConstructor = vrClassesBuilderClass.getConstructor();
+ return (VrClassesWrapper) vrClassesBuilderConstructor.newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException | NoSuchMethodException e) {
if (!(e instanceof ClassNotFoundException)) {
@@ -194,33 +271,123 @@ public class VrShellDelegate {
}
}
+ private static PendingIntent getEnterVRPendingIntent(
+ VrDaydreamApi dayreamApi, Activity activity) {
+ return PendingIntent.getActivity(activity, 0,
+ dayreamApi.createVrIntent(new ComponentName(activity, VR_ACTIVITY_ALIAS)),
+ PendingIntent.FLAG_ONE_SHOT);
+ }
+
+ private static void maybeRegisterDaydreamIntent(Activity activity) {
+ if (sInstance != null) return; // Will be handled in onResume.
+ if (!(activity instanceof ChromeTabbedActivity)) return;
+ VrClassesWrapper wrapper = createVrClassesWrapper();
+ if (wrapper == null) return;
+ VrDaydreamApi api = wrapper.createVrDaydreamApi(activity);
+ if (api == null) return;
+ int vrSupportLevel = getVrSupportLevel(api, wrapper.createVrCoreVersionChecker(), null);
+ if (isVrShellEnabled(vrSupportLevel)) registerDaydreamIntent(api, activity);
+ }
+
+ private static void maybeUnregisterDaydreamIntent(Activity activity) {
+ if (sInstance != null) return; // Will be handled in onPause.
+ if (!(activity instanceof ChromeTabbedActivity)) return;
+ VrClassesWrapper wrapper = createVrClassesWrapper();
+ if (wrapper == null) return;
+ VrDaydreamApi api = wrapper.createVrDaydreamApi(activity);
+ if (api == null) return;
+ unregisterDaydreamIntent(api);
+ }
+
+ /**
+ * Registers the Intent to fire after phone inserted into a headset.
+ */
+ private static void registerDaydreamIntent(VrDaydreamApi dayreamApi, Activity activity) {
+ dayreamApi.registerDaydreamIntent(getEnterVRPendingIntent(dayreamApi, activity));
+ }
+
+ /**
+ * Unregisters the Intent which registered by this context if any.
+ */
+ private static void unregisterDaydreamIntent(VrDaydreamApi dayreamApi) {
+ dayreamApi.unregisterDaydreamIntent();
+ }
+
+ /**
+ * @return Whether or not VR Shell is currently enabled.
+ */
+ private static boolean isVrShellEnabled(int vrSupportLevel) {
+ // Only enable ChromeVR (VrShell) on Daydream devices as it currently needs a Daydream
+ // controller.
+ if (vrSupportLevel != VR_DAYDREAM) return false;
+ return ChromeFeatureList.isEnabled(ChromeFeatureList.VR_SHELL);
+ }
+
+ private VrShellDelegate(ChromeActivity activity) {
+ mActivity = activity;
+ mVrClassesWrapper = createVrClassesWrapper();
+ updateVrSupportLevel();
+ mNativeVrShellDelegate = nativeInit();
+ Choreographer choreographer = Choreographer.getInstance();
+ choreographer.postFrameCallback(new FrameCallback() {
+ @Override
+ public void doFrame(long frameTimeNanos) {
+ Display display =
+ ((WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE))
+ .getDefaultDisplay();
+ nativeUpdateVSyncInterval(
+ mNativeVrShellDelegate, frameTimeNanos, 1.0d / display.getRefreshRate());
+ }
+ });
+ }
+
+ /**
+ * Updates mVrSupportLevel to the correct value. isVrCoreCompatible might return different value
+ * at runtime.
+ */
+ // TODO(bshe): Find a place to call this function again, i.e. page refresh or onResume.
+ private void updateVrSupportLevel() {
+ if (mVrClassesWrapper == null) {
+ mVrSupportLevel = VR_NOT_AVAILABLE;
+ return;
+ }
+ if (mVrCoreVersionChecker == null) {
+ mVrCoreVersionChecker = mVrClassesWrapper.createVrCoreVersionChecker();
+ }
+ if (mVrDaydreamApi == null) {
+ mVrDaydreamApi = mVrClassesWrapper.createVrDaydreamApi(mActivity);
+ }
+ mVrSupportLevel = getVrSupportLevel(
+ mVrDaydreamApi, mVrCoreVersionChecker, mActivity.getActivityTab());
+ }
+
/**
* Handle a VR intent, entering VR in the process unless we're unable to.
*/
- public void enterVRFromIntent(Intent intent) {
+ private boolean enterVRFromIntent() {
// Vr Intent is only used on Daydream devices.
- if (mVrSupportLevel != VR_DAYDREAM) return;
- assert isDaydreamVrIntent(intent);
+ if (mVrSupportLevel != VR_DAYDREAM) return false;
if (mListeningForWebVrActivateBeforePause && !mRequestedWebVR) {
nativeDisplayActivate(mNativeVrShellDelegate);
- return;
+ return false;
}
// Normally, if the active page doesn't have a vrdisplayactivate listener, and WebVR was not
// presenting and VrShell was not enabled, we shouldn't enter VR and Daydream Homescreen
// should show after DON flow. But due to a failure in unregisterDaydreamIntent, we still
// try to enterVR. Here we detect this case and force switch to Daydream Homescreen.
- if (!mListeningForWebVrActivateBeforePause && !mRequestedWebVR && !isVrShellEnabled()) {
+ if (!mListeningForWebVrActivateBeforePause && !mRequestedWebVR
+ && !isVrShellEnabled(mVrSupportLevel)) {
mVrDaydreamApi.launchVrHomescreen();
- return;
+ return false;
}
if (mInVr) {
setEnterVRResult(true);
- return;
+ return false;
}
if (!canEnterVR(mActivity.getActivityTab())) {
setEnterVRResult(false);
- return;
+ return false;
}
if (mPaused) {
// We can't enter VR before the application resumes, or we encounter bizarre crashes
@@ -230,6 +397,7 @@ public class VrShellDelegate {
} else {
enterVR();
}
+ return true;
}
private void prepareToEnterVR() {
@@ -261,7 +429,7 @@ public class VrShellDelegate {
setEnterVRResult(false);
return;
}
- mVrClassesWrapper.setVrModeEnabled(true);
+ mVrClassesWrapper.setVrModeEnabled(mActivity, true);
mInVr = true;
addVrViews();
@@ -276,7 +444,7 @@ public class VrShellDelegate {
private void setEnterVRResult(boolean success) {
if (mRequestedWebVR) nativeSetPresentResult(mNativeVrShellDelegate, success);
if (!success && !mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new Intent())) {
- mVrClassesWrapper.setVrModeEnabled(false);
+ mVrClassesWrapper.setVrModeEnabled(mActivity, false);
}
mRequestedWebVR = false;
}
@@ -285,10 +453,10 @@ public class VrShellDelegate {
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 (mVrSupportLevel == VR_NOT_AVAILABLE || mNativeVrShellDelegate == 0
- || (!isVrShellEnabled() && !(mRequestedWebVR || mListeningForWebVrActivate))) {
+ if (mVrSupportLevel == 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 (!isVrShellEnabled(mVrSupportLevel)
+ && !(mRequestedWebVR || mListeningForWebVrActivate)) {
return false;
}
// TODO(mthiesse): When we have VR UI for opening new tabs, etc., allow VR Shell to be
@@ -313,7 +481,7 @@ public class VrShellDelegate {
// ask them to when we call DaydreamApi#launchInVr. As a temporary hack, remember locally
// that we want to enter webVR.
mRequestedWebVR = true;
- switch (enterVRIfNecessary()) {
+ switch (enterVRInternal()) {
case ENTER_VR_NOT_NECESSARY:
mVrShell.setWebVrModeEnabled(true);
nativeSetPresentResult(mNativeVrShellDelegate, true);
@@ -338,7 +506,7 @@ public class VrShellDelegate {
* Enters VR Shell if necessary, displaying browser UI and tab contents in VR.
*/
@EnterVRResult
- public int enterVRIfNecessary() {
+ private int enterVRInternal() {
// Update VR support level as it can change at runtime
updateVrSupportLevel();
if (mVrSupportLevel == VR_NOT_AVAILABLE) return ENTER_VR_CANCELLED;
@@ -350,7 +518,9 @@ public class VrShellDelegate {
// due to the lack of support for unexported activities.
enterVR();
} else {
- if (!mVrDaydreamApi.launchInVr(getPendingEnterVRIntent())) return ENTER_VR_CANCELLED;
+ if (!mVrDaydreamApi.launchInVr(getEnterVRPendingIntent(mVrDaydreamApi, mActivity))) {
+ return ENTER_VR_CANCELLED;
+ }
}
return ENTER_VR_REQUESTED;
}
@@ -367,20 +537,18 @@ public class VrShellDelegate {
// TODO(bajones): Once VR Shell can be invoked outside of WebVR this
// should no longer exit the shell outright. Need a way to determine
// how VrShell was created.
- shutdownVR(false /* isPausing */, !isVrShellEnabled() /* showTransition */);
+ shutdownVR(
+ false /* isPausing */, !isVrShellEnabled(mVrSupportLevel) /* showTransition */);
}
return true;
}
- /**
- * Resumes VR Shell.
- */
- public void maybeResumeVR() {
+ private void resumeVR() {
mPaused = false;
if (mVrSupportLevel == VR_NOT_AVAILABLE) return;
if (mVrSupportLevel == VR_DAYDREAM
- && (isVrShellEnabled() || mListeningForWebVrActivateBeforePause)) {
- registerDaydreamIntent();
+ && (isVrShellEnabled(mVrSupportLevel) || mListeningForWebVrActivateBeforePause)) {
+ registerDaydreamIntent(mVrDaydreamApi, mActivity);
}
if (mEnteringVr) {
@@ -411,19 +579,16 @@ public class VrShellDelegate {
}
} else if (mVrSupportLevel == VR_DAYDREAM && mVrDaydreamApi.isDaydreamCurrentViewer()
&& mLastVRExit + REENTER_VR_TIMEOUT_MS > SystemClock.uptimeMillis()) {
- enterVRIfNecessary();
+ enterVRInternal();
}
}
- /**
- * Pauses VR Shell.
- */
- public void maybePauseVR() {
+ private void pauseVR() {
mPaused = true;
if (mVrSupportLevel == VR_NOT_AVAILABLE) return;
if (mVrSupportLevel == VR_DAYDREAM) {
- unregisterDaydreamIntent();
+ unregisterDaydreamIntent(mVrDaydreamApi);
// When the active web page has a vrdisplayactivate event handler,
// mListeningForWebVrActivate should be set to true, which means a vrdisplayactive event
@@ -442,56 +607,31 @@ public class VrShellDelegate {
shutdownVR(true /* isPausing */, false /* showTransition */);
}
- /**
- * See {@link ChromeActivity#handleBackPressed}
- */
- public boolean onBackPressed() {
+ private boolean onBackPressedInternal() {
if (mVrSupportLevel == VR_NOT_AVAILABLE) return false;
if (!mInVr) return false;
shutdownVR(false /* isPausing */, false /* showTransition */);
return true;
}
- public void onExitVRResult(int resultCode) {
+ private void onExitVRResult(boolean success) {
assert mVrSupportLevel != VR_NOT_AVAILABLE;
- if (resultCode == Activity.RESULT_OK) {
- mVrClassesWrapper.setVrModeEnabled(false);
- } else {
- // For now, we don't handle re-entering VR when exit fails, so keep trying to exit.
- if (!mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new Intent())) {
- mVrClassesWrapper.setVrModeEnabled(false);
- }
- }
- }
-
- 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() {
- mVrDaydreamApi.registerDaydreamIntent(getPendingEnterVRIntent());
- }
-
- /**
- * Unregisters the Intent which registered by this context if any.
- */
- private void unregisterDaydreamIntent() {
- mVrDaydreamApi.unregisterDaydreamIntent();
+ // For now, we don't handle re-entering VR when exit fails, so keep trying to exit.
+ if (!success && sInstance.mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new Intent())) return;
+ sInstance.mVrClassesWrapper.setVrModeEnabled(sInstance.mActivity, false);
}
@CalledByNative
private long createNonPresentingNativeContext() {
if (mVrClassesWrapper == null) return 0;
- mNonPresentingGvrContext = mVrClassesWrapper.createNonPresentingGvrContext();
+ mNonPresentingGvrContext = mVrClassesWrapper.createNonPresentingGvrContext(mActivity);
if (mNonPresentingGvrContext == null) return 0;
return mNonPresentingGvrContext.getNativeGvrContext();
}
@CalledByNative
private void shutdownNonPresentingNativeContext() {
+ if (mNonPresentingGvrContext == null) return;
mNonPresentingGvrContext.shutdown();
mNonPresentingGvrContext = null;
}
@@ -503,9 +643,9 @@ public class VrShellDelegate {
if (mVrSupportLevel != VR_DAYDREAM) return;
mListeningForWebVrActivate = listening;
if (listening) {
- registerDaydreamIntent();
+ registerDaydreamIntent(mVrDaydreamApi, mActivity);
} else {
- unregisterDaydreamIntent();
+ unregisterDaydreamIntent(mVrDaydreamApi);
}
}
@@ -519,10 +659,10 @@ public class VrShellDelegate {
boolean transition = mVrSupportLevel == VR_DAYDREAM && showTransition;
if (!isPausing) {
if (!transition || !mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new Intent())) {
- mVrClassesWrapper.setVrModeEnabled(false);
+ mVrClassesWrapper.setVrModeEnabled(mActivity, false);
}
} else {
- mVrClassesWrapper.setVrModeEnabled(false);
+ mVrClassesWrapper.setVrModeEnabled(mActivity, false);
mLastVRExit = SystemClock.uptimeMillis();
}
if (mRestoreOrientation != null) mActivity.setRequestedOrientation(mRestoreOrientation);
@@ -534,17 +674,13 @@ public class VrShellDelegate {
mActivity.getFullscreenManager().setPositionsForTabToNonFullscreen();
}
- private boolean isVrCoreCompatible() {
- assert mVrClassesWrapper != null;
- if (mVrCoreVersionChecker == null) {
- mVrCoreVersionChecker = mVrClassesWrapper.createVrCoreVersionChecker();
- }
-
+ private static boolean isVrCoreCompatible(
+ VrCoreVersionChecker versionChecker, Tab tabToShowInfobarIn) {
return verifyOrUpdateVrServices(
- mVrCoreVersionChecker.getVrCoreCompatibility(), mActivity.getActivityTab());
+ versionChecker.getVrCoreCompatibility(), tabToShowInfobarIn);
}
- private boolean verifyOrUpdateVrServices(int vrCoreCompatibility, Tab tab) {
+ private static boolean verifyOrUpdateVrServices(int vrCoreCompatibility, Tab tab) {
if (vrCoreCompatibility == VrCoreVersionChecker.VR_READY) {
return true;
}
@@ -558,16 +694,16 @@ public class VrShellDelegate {
Build.VERSION_CODES.KITKAT)) {
return false;
}
-
+ final Activity activity = tab.getActivity();
String infobarText;
String buttonText;
if (vrCoreCompatibility == VrCoreVersionChecker.VR_NOT_AVAILABLE) {
// Supported, but not installed. Ask user to install instead of upgrade.
- infobarText = mActivity.getString(R.string.vr_services_check_infobar_install_text);
- buttonText = mActivity.getString(R.string.vr_services_check_infobar_install_button);
+ infobarText = activity.getString(R.string.vr_services_check_infobar_install_text);
+ buttonText = activity.getString(R.string.vr_services_check_infobar_install_button);
} else if (vrCoreCompatibility == VrCoreVersionChecker.VR_OUT_OF_DATE) {
- infobarText = mActivity.getString(R.string.vr_services_check_infobar_update_text);
- buttonText = mActivity.getString(R.string.vr_services_check_infobar_update_button);
+ infobarText = activity.getString(R.string.vr_services_check_infobar_update_text);
+ buttonText = activity.getString(R.string.vr_services_check_infobar_update_button);
} else {
Log.e(TAG, "Unknown VrCore compatibility: " + vrCoreCompatibility);
return false;
@@ -580,7 +716,7 @@ public class VrShellDelegate {
@Override
public boolean onInfoBarButtonClicked(boolean isPrimary) {
- mActivity.startActivity(new Intent(Intent.ACTION_VIEW,
+ activity.startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("market://details?id=" + VR_CORE_PACKAGE_ID)));
return false;
}
@@ -592,7 +728,9 @@ public class VrShellDelegate {
private boolean createVrShell() {
if (mVrClassesWrapper == null) return false;
- mVrShell = mVrClassesWrapper.createVrShell(this, mActivity.getCompositorViewHolder());
+ mTabModelSelector = mActivity.getCompositorViewHolder().detachForVR();
+ if (mTabModelSelector == null) return false;
+ mVrShell = mVrClassesWrapper.createVrShell(mActivity, this, mTabModelSelector);
return mVrShell != null;
}
@@ -602,11 +740,11 @@ public class VrShellDelegate {
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
decor.addView(mVrShell.getContainer(), params);
- mActivity.setUIVisibilityForVR(View.GONE);
+ mActivity.onEnterVR();
}
private void removeVrViews() {
- mActivity.setUIVisibilityForVR(View.VISIBLE);
+ mActivity.onExitVR();
FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView();
decor.removeView(mVrShell.getContainer());
}
@@ -635,39 +773,15 @@ public class VrShellDelegate {
/**
* Clean up VrShell, and associated native objects.
*/
- public void destroyVrShell() {
+ private void destroyVrShell() {
if (mVrShell != null) {
mVrShell.teardown();
mVrShell = null;
+ mActivity.getCompositorViewHolder().onExitVR(mTabModelSelector);
}
}
/**
- * Whether or not the intent is a Daydream VR Intent.
- */
- public boolean isDaydreamVrIntent(Intent intent) {
- if (intent == null || intent.getCategories() == null) return false;
- return intent.getCategories().contains(DAYDREAM_CATEGORY);
- }
-
- /**
- * Whether or not we are currently in VR.
- */
- public boolean isInVR() {
- return mInVr;
- }
-
- /**
- * @return Whether or not VR Shell is currently enabled.
- */
- private boolean isVrShellEnabled() {
- // Only enable ChromeVR (VrShell) on Daydream devices as it currently needs a Daydream
- // controller.
- if (mVrSupportLevel != VR_DAYDREAM) return false;
- return ChromeFeatureList.isEnabled(ChromeFeatureList.VR_SHELL);
- }
-
- /**
* @param api The VrDaydreamApi object this delegate will use instead of the default one
*/
@VisibleForTesting
@@ -702,11 +816,19 @@ public class VrShellDelegate {
UrlConstants.NTP_URL, TabLaunchType.FROM_CHROME_UI);
}
+ private void destroy() {
+ if (sInstance == null) return;
+ if (mNativeVrShellDelegate != 0) nativeDestroy(mNativeVrShellDelegate);
+ sInstance = null;
+ }
+
private native long nativeInit();
+ private static native void nativeOnLibraryAvailable();
private native void nativeSetPresentResult(long nativeVrShellDelegate, boolean result);
private native void nativeDisplayActivate(long nativeVrShellDelegate);
private native void nativeUpdateVSyncInterval(long nativeVrShellDelegate, long timebaseNanos,
double intervalSeconds);
private native void nativeOnPause(long nativeVrShellDelegate);
private native void nativeOnResume(long nativeVrShellDelegate);
+ private native void nativeDestroy(long nativeVrShellDelegate);
}

Powered by Google App Engine
This is Rietveld 408576698