Commit a85e1e69 authored by Michael Thiessen's avatar Michael Thiessen Committed by Commit Bot

VR: Fix Settings and Close button behaviour

This fixes the close button behaviour under Deep-Linked apps to exit VR
before launching a 2D Activity. Also fixes the Settings button to do the
same, and exits to DD home when the Settings Activity is closed.

Also drive-by fixes a bunch of StrictMode service leaks from DaydreamApi
usage that doesn't close the DaydreamApi instance.

Bug: 817811
Change-Id: I93b4544bf9bcfe08de690f466ff4a92d1fe69721
Reviewed-on: https://chromium-review.googlesource.com/953763Reviewed-by: default avatarYash Malik <ymalik@chromium.org>
Reviewed-by: default avatarBiao She <bshe@chromium.org>
Commit-Queue: Michael Thiessen <mthiesse@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541824}
parent cfdbc4c0
...@@ -87,4 +87,9 @@ public interface VrDaydreamApi { ...@@ -87,4 +87,9 @@ public interface VrDaydreamApi {
* Closes this DaydreamApi instance. * Closes this DaydreamApi instance.
*/ */
void close(); void close();
/**
* Launch the Daydream Settings Activity.
*/
void launchGvrSettings();
} }
...@@ -13,6 +13,7 @@ import android.os.StrictMode; ...@@ -13,6 +13,7 @@ import android.os.StrictMode;
import com.google.vr.ndk.base.DaydreamApi; import com.google.vr.ndk.base.DaydreamApi;
import com.google.vr.ndk.base.GvrApi; import com.google.vr.ndk.base.GvrApi;
import com.google.vr.ndk.base.GvrUiLayout;
import org.chromium.base.Log; import org.chromium.base.Log;
import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.base.WindowAndroid;
...@@ -139,6 +140,15 @@ public class VrDaydreamApiImpl implements VrDaydreamApi { ...@@ -139,6 +140,15 @@ public class VrDaydreamApiImpl implements VrDaydreamApi {
return DaydreamApi.isInVrSession(mContext); return DaydreamApi.isInVrSession(mContext);
} }
@Override
public void launchGvrSettings() {
Activity activity = WindowAndroid.activityFromContext(mContext);
if (activity == null) {
throw new IllegalStateException("Activity is null");
}
GvrUiLayout.launchOrInstallGvrApp(activity);
}
@Override @Override
public void close() { public void close() {
if (mDaydreamApi == null) return; if (mDaydreamApi == null) return;
......
...@@ -49,17 +49,22 @@ public class VrFirstRunActivity extends Activity { ...@@ -49,17 +49,22 @@ public class VrFirstRunActivity extends Activity {
// here ensures that this never happens for users running the latest version of VrCore. // here ensures that this never happens for users running the latest version of VrCore.
wrapper.setVrModeEnabled(this, true); wrapper.setVrModeEnabled(this, true);
mApi = wrapper.createVrDaydreamApi(this); mApi = wrapper.createVrDaydreamApi(this);
try {
if (!mApi.isDaydreamCurrentViewer()) { if (!mApi.isDaydreamCurrentViewer()) {
showFre(); showFre();
return; return;
} }
// Show DOFF with a timeout so that this activity has enough time to be the active VR app. // Show DOFF with a timeout so that this activity has enough time to be the active VR
// app.
new Handler().postDelayed(new Runnable() { new Handler().postDelayed(new Runnable() {
@Override @Override
public void run() { public void run() {
mApi.exitFromVr(VrShellDelegate.EXIT_VR_RESULT, new Intent()); mApi.exitFromVr(VrShellDelegate.EXIT_VR_RESULT, new Intent());
} }
}, SHOW_DOFF_TIMEOUT_MS); }, SHOW_DOFF_TIMEOUT_MS);
} finally {
mApi.close();
}
} }
@Override @Override
......
...@@ -184,6 +184,7 @@ public class VrShellDelegate ...@@ -184,6 +184,7 @@ public class VrShellDelegate
private boolean mAutopresentWebVr; private boolean mAutopresentWebVr;
// If set to true, we attempt to enter VR mode when the activity is resumed. // If set to true, we attempt to enter VR mode when the activity is resumed.
private boolean mEnterVrOnStartup; private boolean mEnterVrOnStartup;
private boolean mExitCctOnStartup;
private boolean mInternalIntentUsedToStartVr; private boolean mInternalIntentUsedToStartVr;
...@@ -196,6 +197,9 @@ public class VrShellDelegate ...@@ -196,6 +197,9 @@ public class VrShellDelegate
// Gets run when the user exits VR mode by clicking the 'x' button or system UI back button. // Gets run when the user exits VR mode by clicking the 'x' button or system UI back button.
private Runnable mCloseButtonListener; private Runnable mCloseButtonListener;
// Gets run when the user exits VR mode by clicking the Gear button.
private Runnable mSettingsButtonListener;
private static final List<VrModeObserver> sVrModeObservers = new ArrayList<>(); private static final List<VrModeObserver> sVrModeObservers = new ArrayList<>();
/** /**
...@@ -437,6 +441,7 @@ public class VrShellDelegate ...@@ -437,6 +441,7 @@ public class VrShellDelegate
&& activitySupportsVrBrowsing(activity)) { && activitySupportsVrBrowsing(activity)) {
registerDaydreamIntent(api, activity); registerDaydreamIntent(api, activity);
} }
api.close();
} }
} }
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
...@@ -456,6 +461,7 @@ public class VrShellDelegate ...@@ -456,6 +461,7 @@ public class VrShellDelegate
VrDaydreamApi api = wrapper.createVrDaydreamApi(activity); VrDaydreamApi api = wrapper.createVrDaydreamApi(activity);
if (api == null) return; if (api == null) return;
unregisterDaydreamIntent(api); unregisterDaydreamIntent(api);
api.close();
} }
public static void onMultiWindowModeChanged(boolean isInMultiWindowMode) { public static void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
...@@ -1318,6 +1324,7 @@ public class VrShellDelegate ...@@ -1318,6 +1324,7 @@ public class VrShellDelegate
protected void onResume() { protected void onResume() {
if (DEBUG_LOGS) Log.i(TAG, "onResume"); if (DEBUG_LOGS) Log.i(TAG, "onResume");
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) return; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) return;
if (maybeCloseVrCct()) return;
if (mNeedsAnimationCancel) { if (mNeedsAnimationCancel) {
// At least on some devices, like the Samsung S8+, a Window animation is run after our // At least on some devices, like the Samsung S8+, a Window animation is run after our
// Activity is shown that fades between a stale screenshot from before pausing to the // Activity is shown that fades between a stale screenshot from before pausing to the
...@@ -1460,6 +1467,7 @@ public class VrShellDelegate ...@@ -1460,6 +1467,7 @@ public class VrShellDelegate
} }
private void onStart() { private void onStart() {
if (maybeCloseVrCct()) return;
mStopped = false; mStopped = false;
if (mDonSucceeded) setWindowModeForVr(); if (mDonSucceeded) setWindowModeForVr();
if (mInVr && !mVrDaydreamApi.isInVrSession()) shutdownVr(true, false); if (mInVr && !mVrDaydreamApi.isInVrSession()) shutdownVr(true, false);
...@@ -1471,6 +1479,14 @@ public class VrShellDelegate ...@@ -1471,6 +1479,14 @@ public class VrShellDelegate
assert !mCancellingEntryAnimation; assert !mCancellingEntryAnimation;
} }
private boolean maybeCloseVrCct() {
if (!mExitCctOnStartup) return false;
mVrDaydreamApi.launchVrHomescreen();
assert mActivity instanceof CustomTabActivity;
((CustomTabActivity) mActivity).finishAndClose(false);
return true;
}
private boolean onBackPressedInternal() { private boolean onBackPressedInternal() {
if (mVrSupportLevel == VrSupportLevel.VR_NOT_AVAILABLE) return false; if (mVrSupportLevel == VrSupportLevel.VR_NOT_AVAILABLE) return false;
cancelPendingVrEntry(); cancelPendingVrEntry();
...@@ -1646,10 +1662,14 @@ public class VrShellDelegate ...@@ -1646,10 +1662,14 @@ public class VrShellDelegate
mCloseButtonListener = new Runnable() { mCloseButtonListener = new Runnable() {
@Override @Override
public void run() { public void run() {
if (!startedForAutopresentation) { // Avoid launching DD home when we shutdown VR.
shutdownVr(true /* disableVrMode */, true /* stayingInChrome */); mAutopresentWebVr = false;
return;
} shutdownVr(true /* disableVrMode */,
!startedForAutopresentation /* stayingInChrome */);
if (!startedForAutopresentation) return;
// We override the default behavior of the close button because we may stay in // We override the default behavior of the close button because we may stay in
// Chrome after exiting VR. This is not true for auto-presented content and we want // Chrome after exiting VR. This is not true for auto-presented content and we want
// to do what Daydream does for other VR apps by default (which is currently to open // to do what Daydream does for other VR apps by default (which is currently to open
...@@ -1658,12 +1678,34 @@ public class VrShellDelegate ...@@ -1658,12 +1678,34 @@ public class VrShellDelegate
homeIntent.addCategory(Intent.CATEGORY_HOME); homeIntent.addCategory(Intent.CATEGORY_HOME);
homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mActivity.startActivity(homeIntent); mActivity.startActivity(homeIntent);
return;
((CustomTabActivity) mActivity).finishAndClose(false);
} }
}; };
return mCloseButtonListener; return mCloseButtonListener;
} }
/**
* Returns the callback for the user-triggered close button to exit VR mode.
*/
/* package */ Runnable getVrSettingsButtonListener() {
if (mSettingsButtonListener != null) return mSettingsButtonListener;
final boolean startedForAutopresentation = mAutopresentWebVr;
mSettingsButtonListener = new Runnable() {
@Override
public void run() {
// Avoid launching DD home when we shutdown VR.
mAutopresentWebVr = false;
shutdownVr(true /* disableVrMode */, false /* stayingInChrome */);
if (startedForAutopresentation) mExitCctOnStartup = true;
mVrDaydreamApi.launchGvrSettings();
}
};
return mSettingsButtonListener;
}
/** /**
* Returns true if finishing auto-presentation was handled. * Returns true if finishing auto-presentation was handled.
*/ */
......
...@@ -166,6 +166,7 @@ public class VrShellImpl ...@@ -166,6 +166,7 @@ public class VrShellImpl
setPresentationView(mPresentationView); setPresentationView(mPresentationView);
getUiLayout().setCloseButtonListener(mDelegate.getVrCloseButtonListener()); getUiLayout().setCloseButtonListener(mDelegate.getVrCloseButtonListener());
getUiLayout().setSettingsButtonListener(mDelegate.getVrSettingsButtonListener());
if (mVrBrowsingEnabled) injectVrHostedUiView(); if (mVrBrowsingEnabled) injectVrHostedUiView();
......
...@@ -105,4 +105,7 @@ public class MockVrDaydreamApi implements VrDaydreamApi { ...@@ -105,4 +105,7 @@ public class MockVrDaydreamApi implements VrDaydreamApi {
public boolean isInVrSession() { public boolean isInVrSession() {
return true; return true;
} }
@Override
public void launchGvrSettings() {}
} }
...@@ -20,6 +20,7 @@ import org.chromium.chrome.browser.vr.VrMainActivity; ...@@ -20,6 +20,7 @@ import org.chromium.chrome.browser.vr.VrMainActivity;
import org.chromium.chrome.browser.vr_shell.TestFramework; import org.chromium.chrome.browser.vr_shell.TestFramework;
import org.chromium.chrome.browser.vr_shell.TestVrShellDelegate; import org.chromium.chrome.browser.vr_shell.TestVrShellDelegate;
import org.chromium.chrome.browser.vr_shell.VrClassesWrapperImpl; import org.chromium.chrome.browser.vr_shell.VrClassesWrapperImpl;
import org.chromium.chrome.browser.vr_shell.VrDaydreamApi;
import org.chromium.chrome.browser.vr_shell.VrIntentUtils; import org.chromium.chrome.browser.vr_shell.VrIntentUtils;
import org.chromium.chrome.browser.vr_shell.VrShellDelegate; import org.chromium.chrome.browser.vr_shell.VrShellDelegate;
import org.chromium.chrome.browser.vr_shell.VrTestFramework; import org.chromium.chrome.browser.vr_shell.VrTestFramework;
...@@ -215,7 +216,9 @@ public class TransitionUtils { ...@@ -215,7 +216,9 @@ public class TransitionUtils {
ThreadUtils.runOnUiThreadBlocking(new Runnable() { ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override @Override
public void run() { public void run() {
wrapper.createVrDaydreamApi(activity).launchInVr(intent); VrDaydreamApi api = wrapper.createVrDaydreamApi(activity);
api.launchInVr(intent);
api.close();
} }
}); });
} }
......
...@@ -35,6 +35,8 @@ android_aar_prebuilt("gvr_common_java") { ...@@ -35,6 +35,8 @@ android_aar_prebuilt("gvr_common_java") {
"*google/vr/cardboard/FrameMonitor.class", "*google/vr/cardboard/FrameMonitor.class",
"*google/vr/cardboard/IsEmulator.class", "*google/vr/cardboard/IsEmulator.class",
"*google/vr/cardboard/PackageUtils.class", "*google/vr/cardboard/PackageUtils.class",
"*google/vr/cardboard/StoragePermissionUtils.class",
"*google/vr/cardboard/UiUtils.class",
"*google/vr/cardboard/VrContextWrapper.class", "*google/vr/cardboard/VrContextWrapper.class",
"*google/vr/cardboard/VrCoreLibraryLoader.class", "*google/vr/cardboard/VrCoreLibraryLoader.class",
"*google/vr/cardboard/VrParamsProvider.class", "*google/vr/cardboard/VrParamsProvider.class",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment