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

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

Issue 2873843002: Support autopresenting WebVr content. (Closed)
Patch Set: address more review comments Created 3 years, 7 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser.vr_shell; 5 package org.chromium.chrome.browser.vr_shell;
6 6
7 import android.app.Activity; 7 import android.app.Activity;
8 import android.app.ActivityManager; 8 import android.app.ActivityManager;
9 import android.app.PendingIntent; 9 import android.app.PendingIntent;
10 import android.content.BroadcastReceiver; 10 import android.content.BroadcastReceiver;
(...skipping 23 matching lines...) Expand all
34 import org.chromium.base.Log; 34 import org.chromium.base.Log;
35 import org.chromium.base.ThreadUtils; 35 import org.chromium.base.ThreadUtils;
36 import org.chromium.base.VisibleForTesting; 36 import org.chromium.base.VisibleForTesting;
37 import org.chromium.base.annotations.CalledByNative; 37 import org.chromium.base.annotations.CalledByNative;
38 import org.chromium.base.annotations.JNINamespace; 38 import org.chromium.base.annotations.JNINamespace;
39 import org.chromium.base.library_loader.LibraryLoader; 39 import org.chromium.base.library_loader.LibraryLoader;
40 import org.chromium.chrome.R; 40 import org.chromium.chrome.R;
41 import org.chromium.chrome.browser.ChromeActivity; 41 import org.chromium.chrome.browser.ChromeActivity;
42 import org.chromium.chrome.browser.ChromeFeatureList; 42 import org.chromium.chrome.browser.ChromeFeatureList;
43 import org.chromium.chrome.browser.ChromeTabbedActivity; 43 import org.chromium.chrome.browser.ChromeTabbedActivity;
44 import org.chromium.chrome.browser.IntentHandler;
44 import org.chromium.chrome.browser.customtabs.CustomTabActivity; 45 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
45 import org.chromium.chrome.browser.infobar.InfoBarIdentifier; 46 import org.chromium.chrome.browser.infobar.InfoBarIdentifier;
46 import org.chromium.chrome.browser.infobar.SimpleConfirmInfoBarBuilder; 47 import org.chromium.chrome.browser.infobar.SimpleConfirmInfoBarBuilder;
47 import org.chromium.chrome.browser.tab.Tab; 48 import org.chromium.chrome.browser.tab.Tab;
48 import org.chromium.chrome.browser.tabmodel.TabModelSelector; 49 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
49 import org.chromium.chrome.browser.webapps.WebappActivity; 50 import org.chromium.chrome.browser.webapps.WebappActivity;
50 51
51 import java.lang.annotation.Retention; 52 import java.lang.annotation.Retention;
52 import java.lang.annotation.RetentionPolicy; 53 import java.lang.annotation.RetentionPolicy;
53 import java.lang.ref.WeakReference; 54 import java.lang.ref.WeakReference;
(...skipping 20 matching lines...) Expand all
74 private @interface EnterVRResult {} 75 private @interface EnterVRResult {}
75 76
76 private static final int VR_NOT_AVAILABLE = 0; 77 private static final int VR_NOT_AVAILABLE = 0;
77 private static final int VR_CARDBOARD = 1; 78 private static final int VR_CARDBOARD = 1;
78 private static final int VR_DAYDREAM = 2; // Supports both Cardboard and Day dream viewer. 79 private static final int VR_DAYDREAM = 2; // Supports both Cardboard and Day dream viewer.
79 80
80 @Retention(RetentionPolicy.SOURCE) 81 @Retention(RetentionPolicy.SOURCE)
81 @IntDef({VR_NOT_AVAILABLE, VR_CARDBOARD, VR_DAYDREAM}) 82 @IntDef({VR_NOT_AVAILABLE, VR_CARDBOARD, VR_DAYDREAM})
82 private @interface VrSupportLevel {} 83 private @interface VrSupportLevel {}
83 84
85 private static final String DAYDREAM_VR_EXTRA = "android.intent.extra.VR_LAU NCH";
86
84 // Linter and formatter disagree on how the line below should be formatted. 87 // Linter and formatter disagree on how the line below should be formatted.
85 /* package */ 88 /* package */
86 static final String VR_ENTRY_RESULT_ACTION = 89 static final String VR_ENTRY_RESULT_ACTION =
87 "org.chromium.chrome.browser.vr_shell.VrEntryResult"; 90 "org.chromium.chrome.browser.vr_shell.VrEntryResult";
88 91
89 private static final long REENTER_VR_TIMEOUT_MS = 1000; 92 private static final long REENTER_VR_TIMEOUT_MS = 1000;
90 93
91 private static final int VR_SYSTEM_UI_FLAGS = View.SYSTEM_UI_FLAG_LAYOUT_STA BLE 94 private static final int VR_SYSTEM_UI_FLAGS = View.SYSTEM_UI_FLAG_LAYOUT_STA BLE
92 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_L AYOUT_FULLSCREEN 95 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_L AYOUT_FULLSCREEN
93 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCRE EN 96 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCRE EN
(...skipping 24 matching lines...) Expand all
118 // See further documentation here: https://developers.google.com/vr/daydream /guides/vr-entry 121 // See further documentation here: https://developers.google.com/vr/daydream /guides/vr-entry
119 private boolean mDonSucceeded; 122 private boolean mDonSucceeded;
120 private boolean mPaused; 123 private boolean mPaused;
121 private int mRestoreSystemUiVisibilityFlag = -1; 124 private int mRestoreSystemUiVisibilityFlag = -1;
122 private Integer mRestoreOrientation = null; 125 private Integer mRestoreOrientation = null;
123 private long mNativeVrShellDelegate; 126 private long mNativeVrShellDelegate;
124 private boolean mRequestedWebVr; 127 private boolean mRequestedWebVr;
125 private long mLastVrExit; 128 private long mLastVrExit;
126 private boolean mListeningForWebVrActivate; 129 private boolean mListeningForWebVrActivate;
127 private boolean mListeningForWebVrActivateBeforePause; 130 private boolean mListeningForWebVrActivateBeforePause;
131 // Whether or not we should autopresent WebVr. If this is set, it means that a first
132 // party app (e.g Daydream home) has asked us to autopresent WebVr content a nd we're waiting
133 // for the WebVr content to call requestPresent.
134 private boolean mAutopresentWebVr;
128 135
129 private static class VrBroadcastReceiver extends BroadcastReceiver { 136 private static class VrBroadcastReceiver extends BroadcastReceiver {
130 private final WeakReference<ChromeActivity> mTargetActivity; 137 private final WeakReference<ChromeActivity> mTargetActivity;
131 138
132 public VrBroadcastReceiver(ChromeActivity activity) { 139 public VrBroadcastReceiver(ChromeActivity activity) {
133 mTargetActivity = new WeakReference<ChromeActivity>(activity); 140 mTargetActivity = new WeakReference<ChromeActivity>(activity);
134 } 141 }
135 142
136 @Override 143 @Override
137 public void onReceive(Context context, Intent intent) { 144 public void onReceive(Context context, Intent intent) {
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 sInstance = new VrShellDelegate(activity, wrapper); 309 sInstance = new VrShellDelegate(activity, wrapper);
303 310
304 return sInstance; 311 return sInstance;
305 } 312 }
306 313
307 private static boolean activitySupportsPresentation(Activity activity) { 314 private static boolean activitySupportsPresentation(Activity activity) {
308 return activity instanceof ChromeTabbedActivity || activity instanceof C ustomTabActivity 315 return activity instanceof ChromeTabbedActivity || activity instanceof C ustomTabActivity
309 || activity instanceof WebappActivity; 316 || activity instanceof WebappActivity;
310 } 317 }
311 318
319 private static boolean activitySupportsAutopresentation(Activity activity) {
320 return activity instanceof ChromeTabbedActivity;
321 }
322
312 private static boolean activitySupportsVrBrowsing(Activity activity) { 323 private static boolean activitySupportsVrBrowsing(Activity activity) {
313 return activity instanceof ChromeTabbedActivity || activity instanceof C ustomTabActivity; 324 return activity instanceof ChromeTabbedActivity || activity instanceof C ustomTabActivity;
314 } 325 }
315 326
316 /** 327 /**
317 * @return A helper class for creating VR-specific classes that may not be a vailable at compile 328 * @return A helper class for creating VR-specific classes that may not be a vailable at compile
318 * time. 329 * time.
319 */ 330 */
320 private static VrClassesWrapper getVrClassesWrapper() { 331 private static VrClassesWrapper getVrClassesWrapper() {
321 if (sInstance != null) return sInstance.mVrClassesWrapper; 332 if (sInstance != null) return sInstance.mVrClassesWrapper;
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 mVrShell.setWebVrModeEnabled(mRequestedWebVr || tentativeWebVrMode); 516 mVrShell.setWebVrModeEnabled(mRequestedWebVr || tentativeWebVrMode);
506 517
507 // onResume needs to be called on GvrLayout after initialization to make sure DON flow work 518 // onResume needs to be called on GvrLayout after initialization to make sure DON flow work
508 // properly. 519 // properly.
509 mVrShell.resume(); 520 mVrShell.resume();
510 521
511 maybeSetPresentResult(true); 522 maybeSetPresentResult(true);
512 mVrShell.getContainer().setOnSystemUiVisibilityChangeListener(this); 523 mVrShell.getContainer().setOnSystemUiVisibilityChangeListener(this);
513 } 524 }
514 525
526 private boolean launchInVr() {
527 assert mActivity != null && mVrSupportLevel != VR_NOT_AVAILABLE;
528 return mVrDaydreamApi.launchInVr(getEnterVrPendingIntent(mActivity));
529 }
530
531 private void onAutopresentIntent() {
532 // Autopresent intents are only expected from trusted first party apps w hile
533 // we're not in vr (e.g. deep-linked from day dream home).
534 assert !mInVr;
535 mAutopresentWebVr = true;
536 }
537
538 /**
539 * This is called every time ChromeActivity gets a intent. Its currently use d to
540 * autopresent WebVr from Daydream Home.
541 */
542 public static void onNewIntent(ChromeActivity activity, Intent intent) {
543 if (intent.getBooleanExtra(DAYDREAM_VR_EXTRA, false)
544 && activitySupportsAutopresentation(activity)
545 && IntentHandler.isIntentChromeOrFirstParty(intent)
546 && !IntentHandler.wasIntentSenderChrome(intent)) {
547 VrShellDelegate instance = getInstance(activity);
548 if (instance == null) return;
549 instance.onAutopresentIntent();
550 }
551 }
552
515 @Override 553 @Override
516 public void onSystemUiVisibilityChange(int visibility) { 554 public void onSystemUiVisibilityChange(int visibility) {
517 if (mInVr && !isWindowModeCorrectForVr()) { 555 if (mInVr && !isWindowModeCorrectForVr()) {
518 setWindowModeForVr(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 556 setWindowModeForVr(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
519 } 557 }
520 } 558 }
521 559
522 private boolean isWindowModeCorrectForVr() { 560 private boolean isWindowModeCorrectForVr() {
523 int flags = mActivity.getWindow().getDecorView().getSystemUiVisibility() ; 561 int flags = mActivity.getWindow().getDecorView().getSystemUiVisibility() ;
524 int orientation = mActivity.getResources().getConfiguration().orientatio n; 562 int orientation = mActivity.getResources().getConfiguration().orientatio n;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 // For now we don't handle sad tab page. crbug.com/661609 595 // For now we don't handle sad tab page. crbug.com/661609
558 if (tab.isShowingSadTab()) { 596 if (tab.isShowingSadTab()) {
559 return false; 597 return false;
560 } 598 }
561 return true; 599 return true;
562 } 600 }
563 601
564 @CalledByNative 602 @CalledByNative
565 private void presentRequested() { 603 private void presentRequested() {
566 mRequestedWebVr = true; 604 mRequestedWebVr = true;
605 mAutopresentWebVr = false;
567 switch (enterVrInternal()) { 606 switch (enterVrInternal()) {
568 case ENTER_VR_NOT_NECESSARY: 607 case ENTER_VR_NOT_NECESSARY:
569 mVrShell.setWebVrModeEnabled(true); 608 mVrShell.setWebVrModeEnabled(true);
570 maybeSetPresentResult(true); 609 maybeSetPresentResult(true);
571 break; 610 break;
572 case ENTER_VR_CANCELLED: 611 case ENTER_VR_CANCELLED:
573 maybeSetPresentResult(false); 612 maybeSetPresentResult(false);
574 break; 613 break;
575 case ENTER_VR_REQUESTED: 614 case ENTER_VR_REQUESTED:
576 break; 615 break;
(...skipping 18 matching lines...) Expand all
595 634
596 if (mVrSupportLevel == VR_CARDBOARD || !mVrDaydreamApi.isDaydreamCurrent Viewer()) { 635 if (mVrSupportLevel == VR_CARDBOARD || !mVrDaydreamApi.isDaydreamCurrent Viewer()) {
597 // Avoid using launchInVr which would trigger DON flow regardless cu rrent viewer type 636 // Avoid using launchInVr which would trigger DON flow regardless cu rrent viewer type
598 // due to the lack of support for unexported activities. 637 // due to the lack of support for unexported activities.
599 enterVr(false); 638 enterVr(false);
600 } else { 639 } else {
601 // LANDSCAPE orientation is needed before we can safely enter VR. DO N can make sure that 640 // LANDSCAPE orientation is needed before we can safely enter VR. DO N can make sure that
602 // the device is at LANDSCAPE orientation once it is finished. So he re we use SENSOR to 641 // the device is at LANDSCAPE orientation once it is finished. So he re we use SENSOR to
603 // avoid forcing LANDSCAPE orientation in order to have a smoother t ransition. 642 // avoid forcing LANDSCAPE orientation in order to have a smoother t ransition.
604 setWindowModeForVr(ActivityInfo.SCREEN_ORIENTATION_SENSOR); 643 setWindowModeForVr(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
605 if (!mVrDaydreamApi.launchInVr(getEnterVrPendingIntent(mActivity))) { 644 if (!launchInVr()) {
606 restoreWindowMode(); 645 restoreWindowMode();
607 return ENTER_VR_CANCELLED; 646 return ENTER_VR_CANCELLED;
608 } 647 }
609 } 648 }
610 return ENTER_VR_REQUESTED; 649 return ENTER_VR_REQUESTED;
611 } 650 }
612 651
613 @CalledByNative 652 @CalledByNative
614 private boolean exitWebVRPresent() { 653 private boolean exitWebVRPresent() {
615 if (!mInVr) return false; 654 if (!mInVr) return false;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 } 764 }
726 765
727 @CalledByNative 766 @CalledByNative
728 private void setListeningForWebVrActivate(boolean listening) { 767 private void setListeningForWebVrActivate(boolean listening) {
729 // Non-Daydream devices may not have the concept of display activate. So disable 768 // Non-Daydream devices may not have the concept of display activate. So disable
730 // mListeningForWebVrActivate for them. 769 // mListeningForWebVrActivate for them.
731 if (mVrSupportLevel != VR_DAYDREAM) return; 770 if (mVrSupportLevel != VR_DAYDREAM) return;
732 mListeningForWebVrActivate = listening; 771 mListeningForWebVrActivate = listening;
733 if (listening && !mPaused) { 772 if (listening && !mPaused) {
734 registerDaydreamIntent(mVrDaydreamApi, mActivity); 773 registerDaydreamIntent(mVrDaydreamApi, mActivity);
774 if (mAutopresentWebVr) {
775 // Dispatch vrdisplayactivate so that the WebVr page can call re questPresent
776 // to start presentation.
777 // TODO(ymalik): There will be a delay between when we're asked to autopresent and
778 // when the WebVr site calls requestPresent. In this time, the u ser sees 2D Chrome
779 // UI which is suboptimal.
780 nativeDisplayActivate(mNativeVrShellDelegate);
781 }
735 } else { 782 } else {
736 unregisterDaydreamIntent(mVrDaydreamApi); 783 unregisterDaydreamIntent(mVrDaydreamApi);
737 } 784 }
738 } 785 }
739 786
740 /** 787 /**
741 * Exits VR Shell, performing all necessary cleanup. 788 * Exits VR Shell, performing all necessary cleanup.
742 */ 789 */
743 /* package */ void shutdownVr(boolean isPausing, boolean showTransition) { 790 /* package */ void shutdownVr(boolean isPausing, boolean showTransition) {
744 if (!mInVr) return; 791 if (!mInVr) return;
745 mInVr = false; 792 mInVr = false;
746 mRequestedWebVr = false; 793 mRequestedWebVr = false;
794 mAutopresentWebVr = false;
747 // Transition screen is not available for Cardboard only (non-Daydream) devices. 795 // Transition screen is not available for Cardboard only (non-Daydream) devices.
748 // TODO(bshe): Fix this once b/33490788 is fixed. 796 // TODO(bshe): Fix this once b/33490788 is fixed.
749 boolean transition = mVrSupportLevel == VR_DAYDREAM && showTransition; 797 boolean transition = mVrSupportLevel == VR_DAYDREAM && showTransition;
750 if (!isPausing) { 798 if (!isPausing) {
751 if (!transition || !mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new In tent())) { 799 if (!transition || !mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new In tent())) {
752 mVrClassesWrapper.setVrModeEnabled(mActivity, false); 800 mVrClassesWrapper.setVrModeEnabled(mActivity, false);
753 } 801 }
754 } else { 802 } else {
755 mVrClassesWrapper.setVrModeEnabled(mActivity, false); 803 mVrClassesWrapper.setVrModeEnabled(mActivity, false);
756 mLastVrExit = SystemClock.uptimeMillis(); 804 mLastVrExit = SystemClock.uptimeMillis();
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 private native long nativeInit(); 962 private native long nativeInit();
915 private static native void nativeOnLibraryAvailable(); 963 private static native void nativeOnLibraryAvailable();
916 private native void nativeSetPresentResult(long nativeVrShellDelegate, boole an result); 964 private native void nativeSetPresentResult(long nativeVrShellDelegate, boole an result);
917 private native void nativeDisplayActivate(long nativeVrShellDelegate); 965 private native void nativeDisplayActivate(long nativeVrShellDelegate);
918 private native void nativeUpdateVSyncInterval(long nativeVrShellDelegate, lo ng timebaseNanos, 966 private native void nativeUpdateVSyncInterval(long nativeVrShellDelegate, lo ng timebaseNanos,
919 double intervalSeconds); 967 double intervalSeconds);
920 private native void nativeOnPause(long nativeVrShellDelegate); 968 private native void nativeOnPause(long nativeVrShellDelegate);
921 private native void nativeOnResume(long nativeVrShellDelegate); 969 private native void nativeOnResume(long nativeVrShellDelegate);
922 private native void nativeDestroy(long nativeVrShellDelegate); 970 private native void nativeDestroy(long nativeVrShellDelegate);
923 } 971 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698