Skip to content

Commit

Permalink
VR: Ensure Chrome launches onto the primary display for VR Standlones
Browse files Browse the repository at this point in the history
There's a platform bug with Standalone VR devices where transitioning
between the virtual and primary display causes crashes in the
framework. This means that currently (M67) Chrome crashes 100% of the
time on launch, regardless of how Chrome was launched, on Standalones.

I'm not 100% clear on how moving between the displays works on
standalones as it's complicated. Here are the things I know:
1. 2D apps by default launch to the virtual display.
2. Toggling VR mode can cause your Activity to be moved to the primary,
real, display.
3. Moving between displays is causing platform crashes due to the
display being cached in the View Root, and probably elsewhere.

The recommended workaround by the platform folks is to just make sure
Chrome is never launched onto the Virtual Display. This has some
implications. The main implication is that the Chrome window when using
the 2D-in-VR path is super tall as they have to keep text readable with
the app rendering at real display size. When we ship browsing on
standalones, you'll never see the tall window anyways, so it won't be
an issue in the future.

I would provide screenshots, but that's impossible :)

Bug: 838358
Change-Id: I618a01e9e020dec2abcc8f1e65ce7a24842c2113
Reviewed-on: https://chromium-review.googlesource.com/1036117
Reviewed-by: Ted Choc <tedchoc@chromium.org>
Reviewed-by: Yaron Friedman <yfriedman@chromium.org>
Commit-Queue: Michael Thiessen <mthiesse@chromium.org>
Cr-Commit-Position: refs/heads/master@{#555040}
  • Loading branch information
Michael Thiessen authored and Commit Bot committed May 1, 2018
1 parent 4933e6b commit 1abb759
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 3 deletions.
15 changes: 15 additions & 0 deletions base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Context;
Expand All @@ -24,6 +25,7 @@
import android.graphics.drawable.VectorDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.Process;
import android.os.StatFs;
Expand Down Expand Up @@ -709,4 +711,17 @@ public static void disableSmartSelectionTextClassifier(TextView textView) {

textView.setTextClassifier(TextClassifier.NO_OP);
}

/**
* Creates an ActivityOptions Bundle with basic options and the LaunchDisplayId set.
* @param displayId The id of the display to launch into.
* @return The created bundle, or null if unsupported.
*/
public static Bundle createLaunchDisplayIdActivityOptions(int displayId) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return null;

ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchDisplayId(displayId);
return options.toBundle();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import android.support.annotation.CallSuper;
import android.util.DisplayMetrics;
import android.util.Pair;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
Expand Down Expand Up @@ -161,6 +162,7 @@
import org.chromium.ui.base.DeviceFormFactor;
import org.chromium.ui.base.PageTransition;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.ui.display.DisplayAndroid;
import org.chromium.ui.widget.Toast;
import org.chromium.webapk.lib.client.WebApkNavigationClient;
import org.chromium.webapk.lib.client.WebApkValidator;
Expand Down Expand Up @@ -308,6 +310,21 @@ protected ActivityWindowAndroid createWindowAndroid() {
public void preInflationStartup() {
super.preInflationStartup();

if (VrShellDelegate.getVrClassesWrapper().bootsToVr()) {
// TODO(mthiesse): Remove this once b/78108624 is fixed. This is a workaround for a
// platform bug where Chrome crashes on launch for standalone devices if not launched
// onto the primary display (There's a virtual display 2D apps are default launched onto
// with different display properties). Re-launch with the same intent but to the primary
// display.
if (DisplayAndroid.getNonMultiDisplay(this).getDisplayId() != Display.DEFAULT_DISPLAY) {
finish();
startActivity(getIntent(),
ApiCompatibilityUtils.createLaunchDisplayIdActivityOptions(
Display.DEFAULT_DISPLAY));
return;
}
}

// We need to explicitly enable VR mode here so that the system doesn't kick us out of VR,
// or drop us into the 2D-in-VR rendering mode, while we prepare for VR rendering.
if (VrIntentUtils.isVrIntent(getIntent())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.view.Display;

import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.R;
Expand Down Expand Up @@ -151,7 +152,15 @@ public static Bundle getVrIntentOptions(Context context) {
// enter VR (I don't know what's canceling it). To hide the 2D UI, we resort to the black
// overlay view added in {@link startWithVrIntentPreNative}.
int animation = VrShellDelegate.USE_HIDE_ANIMATION ? R.anim.stay_hidden : 0;
return ActivityOptions.makeCustomAnimation(context, animation, 0).toBundle();
ActivityOptions options = ActivityOptions.makeCustomAnimation(context, animation, 0);
if (VrShellDelegate.getVrClassesWrapper().bootsToVr()) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
assert false;
} else {
options.setLaunchDisplayId(Display.DEFAULT_DISPLAY);
}
}
return options.toBundle();
}

/**
Expand All @@ -167,7 +176,8 @@ public static void launchInVr(Intent intent, Activity activity) {
* @return whether the intent was forwarded to the VR launcher.
*/
public static boolean maybeForwardToVrLauncher(Intent intent, Activity activity) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O) return false;
// Standalone VR devices use 2D-in-VR rendering on O+.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return false;
if (wouldUse2DInVrRenderingMode(activity) && VrShellDelegate.deviceSupportsVrLaunches()) {
Intent vrIntent = new Intent(intent);
vrIntent.setComponent(null);
Expand All @@ -190,7 +200,7 @@ public static boolean wouldUse2DInVrRenderingMode(Activity activity) {
int uiMode = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
if (uiMode != Configuration.UI_MODE_TYPE_VR_HEADSET) return false;
VrClassesWrapper wrapper = VrShellDelegate.getVrClassesWrapper();
return wrapper != null && wrapper.supports2dInVr();
return wrapper != null && (wrapper.bootsToVr() || wrapper.supports2dInVr());
}

/**
Expand Down

0 comments on commit 1abb759

Please sign in to comment.