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

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: rebase 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 24 matching lines...) Expand all
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.base.metrics.RecordUserAction; 40 import org.chromium.base.metrics.RecordUserAction;
41 import org.chromium.chrome.R; 41 import org.chromium.chrome.R;
42 import org.chromium.chrome.browser.ChromeActivity; 42 import org.chromium.chrome.browser.ChromeActivity;
43 import org.chromium.chrome.browser.ChromeFeatureList; 43 import org.chromium.chrome.browser.ChromeFeatureList;
44 import org.chromium.chrome.browser.ChromeTabbedActivity; 44 import org.chromium.chrome.browser.ChromeTabbedActivity;
45 import org.chromium.chrome.browser.IntentHandler;
45 import org.chromium.chrome.browser.customtabs.CustomTabActivity; 46 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
46 import org.chromium.chrome.browser.infobar.InfoBarIdentifier; 47 import org.chromium.chrome.browser.infobar.InfoBarIdentifier;
47 import org.chromium.chrome.browser.infobar.SimpleConfirmInfoBarBuilder; 48 import org.chromium.chrome.browser.infobar.SimpleConfirmInfoBarBuilder;
48 import org.chromium.chrome.browser.tab.Tab; 49 import org.chromium.chrome.browser.tab.Tab;
49 import org.chromium.chrome.browser.tabmodel.TabModelSelector; 50 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
51 import org.chromium.chrome.browser.util.IntentUtils;
50 import org.chromium.chrome.browser.webapps.WebappActivity; 52 import org.chromium.chrome.browser.webapps.WebappActivity;
51 53
52 import java.lang.annotation.Retention; 54 import java.lang.annotation.Retention;
53 import java.lang.annotation.RetentionPolicy; 55 import java.lang.annotation.RetentionPolicy;
54 import java.lang.ref.WeakReference; 56 import java.lang.ref.WeakReference;
55 import java.lang.reflect.Constructor; 57 import java.lang.reflect.Constructor;
56 import java.lang.reflect.InvocationTargetException; 58 import java.lang.reflect.InvocationTargetException;
57 59
58 /** 60 /**
59 * Manages interactions with the VR Shell. 61 * Manages interactions with the VR Shell.
(...skipping 15 matching lines...) Expand all
75 private @interface EnterVRResult {} 77 private @interface EnterVRResult {}
76 78
77 private static final int VR_NOT_AVAILABLE = 0; 79 private static final int VR_NOT_AVAILABLE = 0;
78 private static final int VR_CARDBOARD = 1; 80 private static final int VR_CARDBOARD = 1;
79 private static final int VR_DAYDREAM = 2; // Supports both Cardboard and Day dream viewer. 81 private static final int VR_DAYDREAM = 2; // Supports both Cardboard and Day dream viewer.
80 82
81 @Retention(RetentionPolicy.SOURCE) 83 @Retention(RetentionPolicy.SOURCE)
82 @IntDef({VR_NOT_AVAILABLE, VR_CARDBOARD, VR_DAYDREAM}) 84 @IntDef({VR_NOT_AVAILABLE, VR_CARDBOARD, VR_DAYDREAM})
83 private @interface VrSupportLevel {} 85 private @interface VrSupportLevel {}
84 86
87 private static final String DAYDREAM_VR_EXTRA = "android.intent.extra.VR_LAU NCH";
88 private static final String DAYDREAM_HOME_PACKAGE = "com.google.android.vr.h ome";
89
85 // Linter and formatter disagree on how the line below should be formatted. 90 // Linter and formatter disagree on how the line below should be formatted.
86 /* package */ 91 /* package */
87 static final String VR_ENTRY_RESULT_ACTION = 92 static final String VR_ENTRY_RESULT_ACTION =
88 "org.chromium.chrome.browser.vr_shell.VrEntryResult"; 93 "org.chromium.chrome.browser.vr_shell.VrEntryResult";
89 94
90 private static final long REENTER_VR_TIMEOUT_MS = 1000; 95 private static final long REENTER_VR_TIMEOUT_MS = 1000;
91 96
92 private static final int VR_SYSTEM_UI_FLAGS = View.SYSTEM_UI_FLAG_LAYOUT_STA BLE 97 private static final int VR_SYSTEM_UI_FLAGS = View.SYSTEM_UI_FLAG_LAYOUT_STA BLE
93 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_L AYOUT_FULLSCREEN 98 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_L AYOUT_FULLSCREEN
94 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCRE EN 99 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCRE EN
(...skipping 29 matching lines...) Expand all
124 private boolean mShowingDaydreamDoff; 129 private boolean mShowingDaydreamDoff;
125 private boolean mExitingCct; 130 private boolean mExitingCct;
126 private boolean mPaused; 131 private boolean mPaused;
127 private int mRestoreSystemUiVisibilityFlag = -1; 132 private int mRestoreSystemUiVisibilityFlag = -1;
128 private Integer mRestoreOrientation = null; 133 private Integer mRestoreOrientation = null;
129 private long mNativeVrShellDelegate; 134 private long mNativeVrShellDelegate;
130 private boolean mRequestedWebVr; 135 private boolean mRequestedWebVr;
131 private long mLastVrExit; 136 private long mLastVrExit;
132 private boolean mListeningForWebVrActivate; 137 private boolean mListeningForWebVrActivate;
133 private boolean mListeningForWebVrActivateBeforePause; 138 private boolean mListeningForWebVrActivateBeforePause;
139 // Whether or not we should autopresent WebVr. If this is set, it means that a first
140 // party app has asked us to autopresent WebVr content and we're waiting for the WebVr
141 // content to call requestPresent.
142 private boolean mAutopresentWebVr;
134 143
135 private static final class VrBroadcastReceiver extends BroadcastReceiver { 144 private static final class VrBroadcastReceiver extends BroadcastReceiver {
136 private final WeakReference<ChromeActivity> mTargetActivity; 145 private final WeakReference<ChromeActivity> mTargetActivity;
137 146
138 public VrBroadcastReceiver(ChromeActivity activity) { 147 public VrBroadcastReceiver(ChromeActivity activity) {
139 mTargetActivity = new WeakReference<ChromeActivity>(activity); 148 mTargetActivity = new WeakReference<ChromeActivity>(activity);
140 } 149 }
141 150
142 @Override 151 @Override
143 public void onReceive(Context context, Intent intent) { 152 public void onReceive(Context context, Intent intent) {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 sInstance = new VrShellDelegate(activity, wrapper); 319 sInstance = new VrShellDelegate(activity, wrapper);
311 320
312 return sInstance; 321 return sInstance;
313 } 322 }
314 323
315 private static boolean activitySupportsPresentation(Activity activity) { 324 private static boolean activitySupportsPresentation(Activity activity) {
316 return activity instanceof ChromeTabbedActivity || activity instanceof C ustomTabActivity 325 return activity instanceof ChromeTabbedActivity || activity instanceof C ustomTabActivity
317 || activity instanceof WebappActivity; 326 || activity instanceof WebappActivity;
318 } 327 }
319 328
329 private static boolean activitySupportsAutopresentation(Activity activity) {
330 return activity instanceof ChromeTabbedActivity;
331 }
332
320 private static boolean activitySupportsVrBrowsing(Activity activity) { 333 private static boolean activitySupportsVrBrowsing(Activity activity) {
321 if (activity instanceof ChromeTabbedActivity) return true; 334 if (activity instanceof ChromeTabbedActivity) return true;
322 if (activity instanceof CustomTabActivity) { 335 if (activity instanceof CustomTabActivity) {
323 return ChromeFeatureList.isEnabled(ChromeFeatureList.VR_CUSTOM_TAB_B ROWSING); 336 return ChromeFeatureList.isEnabled(ChromeFeatureList.VR_CUSTOM_TAB_B ROWSING);
324 } 337 }
325 return false; 338 return false;
326 } 339 }
327 340
328 /** 341 /**
329 * @return A helper class for creating VR-specific classes that may not be a vailable at compile 342 * @return A helper class for creating VR-specific classes that may not be a vailable at compile
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 mVrShell.setWebVrModeEnabled(mRequestedWebVr || tentativeWebVrMode); 567 mVrShell.setWebVrModeEnabled(mRequestedWebVr || tentativeWebVrMode);
555 568
556 // onResume needs to be called on GvrLayout after initialization to make sure DON flow work 569 // onResume needs to be called on GvrLayout after initialization to make sure DON flow work
557 // properly. 570 // properly.
558 mVrShell.resume(); 571 mVrShell.resume();
559 572
560 maybeSetPresentResult(true); 573 maybeSetPresentResult(true);
561 mVrShell.getContainer().setOnSystemUiVisibilityChangeListener(this); 574 mVrShell.getContainer().setOnSystemUiVisibilityChangeListener(this);
562 } 575 }
563 576
577 private boolean launchInVr() {
578 assert mActivity != null && mVrSupportLevel != VR_NOT_AVAILABLE;
579 return mVrDaydreamApi.launchInVr(getEnterVrPendingIntent(mActivity));
580 }
581
582 private void onAutopresentIntent() {
583 // Autopresent intents are only expected from trusted first party apps w hile
584 // we're not in vr.
585 assert !mInVr;
586 mAutopresentWebVr = true;
587 }
588
589 /**
590 * This is called every time ChromeActivity gets a new intent.
591 */
592 public static void onNewIntent(Intent intent) {
593 if (IntentUtils.safeGetBooleanExtra(intent, DAYDREAM_VR_EXTRA, false)
594 && ChromeFeatureList.isEnabled(ChromeFeatureList.WEBVR_AUTOPRESE NT)
595 && activitySupportsAutopresentation(
596 ApplicationStatus.getLastTrackedFocusedActivity())
597 && IntentHandler.isIntentFromTrustedApp(intent, DAYDREAM_HOME_PA CKAGE)) {
598 VrShellDelegate instance = getInstance();
599 if (instance == null) return;
600 instance.onAutopresentIntent();
601 }
602 }
603
564 @Override 604 @Override
565 public void onSystemUiVisibilityChange(int visibility) { 605 public void onSystemUiVisibilityChange(int visibility) {
566 if (mInVr && !isWindowModeCorrectForVr()) { 606 if (mInVr && !isWindowModeCorrectForVr()) {
567 setWindowModeForVr(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 607 setWindowModeForVr(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
568 } 608 }
569 } 609 }
570 610
571 private boolean isWindowModeCorrectForVr() { 611 private boolean isWindowModeCorrectForVr() {
572 int flags = mActivity.getWindow().getDecorView().getSystemUiVisibility() ; 612 int flags = mActivity.getWindow().getDecorView().getSystemUiVisibility() ;
573 int orientation = mActivity.getResources().getConfiguration().orientatio n; 613 int orientation = mActivity.getResources().getConfiguration().orientatio n;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 // For now we don't handle sad tab page. crbug.com/661609 648 // For now we don't handle sad tab page. crbug.com/661609
609 if (tab.isShowingSadTab()) { 649 if (tab.isShowingSadTab()) {
610 return false; 650 return false;
611 } 651 }
612 return true; 652 return true;
613 } 653 }
614 654
615 @CalledByNative 655 @CalledByNative
616 private void presentRequested() { 656 private void presentRequested() {
617 mRequestedWebVr = true; 657 mRequestedWebVr = true;
658 mAutopresentWebVr = false;
618 switch (enterVrInternal()) { 659 switch (enterVrInternal()) {
619 case ENTER_VR_NOT_NECESSARY: 660 case ENTER_VR_NOT_NECESSARY:
620 mVrShell.setWebVrModeEnabled(true); 661 mVrShell.setWebVrModeEnabled(true);
621 maybeSetPresentResult(true); 662 maybeSetPresentResult(true);
622 break; 663 break;
623 case ENTER_VR_CANCELLED: 664 case ENTER_VR_CANCELLED:
624 maybeSetPresentResult(false); 665 maybeSetPresentResult(false);
625 break; 666 break;
626 case ENTER_VR_REQUESTED: 667 case ENTER_VR_REQUESTED:
627 break; 668 break;
(...skipping 18 matching lines...) Expand all
646 687
647 if (mVrSupportLevel == VR_CARDBOARD || !mVrDaydreamApi.isDaydreamCurrent Viewer()) { 688 if (mVrSupportLevel == VR_CARDBOARD || !mVrDaydreamApi.isDaydreamCurrent Viewer()) {
648 // Avoid using launchInVr which would trigger DON flow regardless cu rrent viewer type 689 // Avoid using launchInVr which would trigger DON flow regardless cu rrent viewer type
649 // due to the lack of support for unexported activities. 690 // due to the lack of support for unexported activities.
650 enterVr(false); 691 enterVr(false);
651 } else { 692 } else {
652 // LANDSCAPE orientation is needed before we can safely enter VR. DO N can make sure that 693 // LANDSCAPE orientation is needed before we can safely enter VR. DO N can make sure that
653 // the device is at LANDSCAPE orientation once it is finished. So he re we use SENSOR to 694 // the device is at LANDSCAPE orientation once it is finished. So he re we use SENSOR to
654 // avoid forcing LANDSCAPE orientation in order to have a smoother t ransition. 695 // avoid forcing LANDSCAPE orientation in order to have a smoother t ransition.
655 setWindowModeForVr(ActivityInfo.SCREEN_ORIENTATION_SENSOR); 696 setWindowModeForVr(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
656 if (!mVrDaydreamApi.launchInVr(getEnterVrPendingIntent(mActivity))) { 697 if (!launchInVr()) {
657 restoreWindowMode(); 698 restoreWindowMode();
658 return ENTER_VR_CANCELLED; 699 return ENTER_VR_CANCELLED;
659 } 700 }
660 } 701 }
661 return ENTER_VR_REQUESTED; 702 return ENTER_VR_REQUESTED;
662 } 703 }
663 704
664 @CalledByNative 705 @CalledByNative
665 private boolean exitWebVRPresent() { 706 private boolean exitWebVRPresent() {
666 if (!mInVr) return false; 707 if (!mInVr) return false;
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 } 837 }
797 838
798 @CalledByNative 839 @CalledByNative
799 private void setListeningForWebVrActivate(boolean listening) { 840 private void setListeningForWebVrActivate(boolean listening) {
800 // Non-Daydream devices may not have the concept of display activate. So disable 841 // Non-Daydream devices may not have the concept of display activate. So disable
801 // mListeningForWebVrActivate for them. 842 // mListeningForWebVrActivate for them.
802 if (mVrSupportLevel != VR_DAYDREAM) return; 843 if (mVrSupportLevel != VR_DAYDREAM) return;
803 mListeningForWebVrActivate = listening; 844 mListeningForWebVrActivate = listening;
804 if (listening && !mPaused) { 845 if (listening && !mPaused) {
805 registerDaydreamIntent(mVrDaydreamApi, mActivity); 846 registerDaydreamIntent(mVrDaydreamApi, mActivity);
847 if (mAutopresentWebVr) {
848 // Dispatch vrdisplayactivate so that the WebVr page can call re questPresent
849 // to start presentation.
850 // TODO(ymalik): There will be a delay between when we're asked to autopresent and
851 // when the WebVr site calls requestPresent. In this time, the u ser sees 2D Chrome
852 // UI which is suboptimal.
853 nativeDisplayActivate(mNativeVrShellDelegate);
854 }
806 } else { 855 } else {
807 unregisterDaydreamIntent(mVrDaydreamApi); 856 unregisterDaydreamIntent(mVrDaydreamApi);
808 } 857 }
809 } 858 }
810 859
811 /** 860 /**
812 * Exits VR Shell, performing all necessary cleanup. 861 * Exits VR Shell, performing all necessary cleanup.
813 */ 862 */
814 /* package */ void shutdownVr(boolean setVrMode, boolean canReenter) { 863 /* package */ void shutdownVr(boolean setVrMode, boolean canReenter) {
815 if (!mInVr) return; 864 if (!mInVr) return;
816 if (mShowingDaydreamDoff) { 865 if (mShowingDaydreamDoff) {
817 onExitVrResult(true); 866 onExitVrResult(true);
818 return; 867 return;
819 } 868 }
820 mInVr = false; 869 mInVr = false;
821 mRequestedWebVr = false; 870 mRequestedWebVr = false;
871 mAutopresentWebVr = false;
822 mLastVrExit = canReenter ? SystemClock.uptimeMillis() : 0; 872 mLastVrExit = canReenter ? SystemClock.uptimeMillis() : 0;
823 873
824 // The user has exited VR. 874 // The user has exited VR.
825 RecordUserAction.record("VR.DOFF"); 875 RecordUserAction.record("VR.DOFF");
826 876
827 restoreWindowMode(); 877 restoreWindowMode();
828 mVrShell.pause(); 878 mVrShell.pause();
829 removeVrViews(); 879 removeVrViews();
830 destroyVrShell(); 880 destroyVrShell();
831 mActivity.getFullscreenManager().setPositionsForTabToNonFullscreen(); 881 mActivity.getFullscreenManager().setPositionsForTabToNonFullscreen();
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 private static native void nativeOnLibraryAvailable(); 1059 private static native void nativeOnLibraryAvailable();
1010 private native void nativeSetPresentResult(long nativeVrShellDelegate, boole an result); 1060 private native void nativeSetPresentResult(long nativeVrShellDelegate, boole an result);
1011 private native void nativeDisplayActivate(long nativeVrShellDelegate); 1061 private native void nativeDisplayActivate(long nativeVrShellDelegate);
1012 private native void nativeUpdateVSyncInterval(long nativeVrShellDelegate, lo ng timebaseNanos, 1062 private native void nativeUpdateVSyncInterval(long nativeVrShellDelegate, lo ng timebaseNanos,
1013 double intervalSeconds); 1063 double intervalSeconds);
1014 private native void nativeOnPause(long nativeVrShellDelegate); 1064 private native void nativeOnPause(long nativeVrShellDelegate);
1015 private native void nativeOnResume(long nativeVrShellDelegate); 1065 private native void nativeOnResume(long nativeVrShellDelegate);
1016 private native void nativeUpdateNonPresentingContext(long nativeVrShellDeleg ate, long context); 1066 private native void nativeUpdateNonPresentingContext(long nativeVrShellDeleg ate, long context);
1017 private native void nativeDestroy(long nativeVrShellDelegate); 1067 private native void nativeDestroy(long nativeVrShellDelegate);
1018 } 1068 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698