OLD | NEW |
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.PendingIntent; | 8 import android.app.PendingIntent; |
9 import android.content.ComponentName; | 9 import android.content.ComponentName; |
10 import android.content.Context; | 10 import android.content.Context; |
11 import android.content.Intent; | 11 import android.content.Intent; |
12 import android.content.pm.ActivityInfo; | 12 import android.content.pm.ActivityInfo; |
13 import android.content.res.Configuration; | 13 import android.content.res.Configuration; |
14 import android.net.Uri; | 14 import android.net.Uri; |
15 import android.os.Build; | |
16 import android.os.Handler; | 15 import android.os.Handler; |
17 import android.os.StrictMode; | 16 import android.os.StrictMode; |
18 import android.os.SystemClock; | 17 import android.os.SystemClock; |
19 import android.support.annotation.IntDef; | 18 import android.support.annotation.IntDef; |
20 import android.view.Choreographer; | 19 import android.view.Choreographer; |
21 import android.view.Choreographer.FrameCallback; | 20 import android.view.Choreographer.FrameCallback; |
22 import android.view.Display; | 21 import android.view.Display; |
23 import android.view.View; | 22 import android.view.View; |
24 import android.view.ViewGroup; | 23 import android.view.ViewGroup; |
25 import android.view.ViewGroup.LayoutParams; | 24 import android.view.ViewGroup.LayoutParams; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 | 74 |
76 @Retention(RetentionPolicy.SOURCE) | 75 @Retention(RetentionPolicy.SOURCE) |
77 @IntDef({VR_NOT_AVAILABLE, VR_CARDBOARD, VR_DAYDREAM}) | 76 @IntDef({VR_NOT_AVAILABLE, VR_CARDBOARD, VR_DAYDREAM}) |
78 public @interface VrSupportLevel {} | 77 public @interface VrSupportLevel {} |
79 | 78 |
80 // TODO(bshe): These should be replaced by string provided by NDK. Currently
, it only available | 79 // TODO(bshe): These should be replaced by string provided by NDK. Currently
, it only available |
81 // in SDK and we don't want add dependency to SDK just to get these strings. | 80 // in SDK and we don't want add dependency to SDK just to get these strings. |
82 private static final String DAYDREAM_CATEGORY = "com.google.intent.category.
DAYDREAM"; | 81 private static final String DAYDREAM_CATEGORY = "com.google.intent.category.
DAYDREAM"; |
83 private static final String CARDBOARD_CATEGORY = "com.google.intent.category
.CARDBOARD"; | 82 private static final String CARDBOARD_CATEGORY = "com.google.intent.category
.CARDBOARD"; |
84 | 83 |
85 private static final String MIN_SDK_VERSION_PARAM_NAME = "min_sdk_version"; | |
86 | |
87 private static final String VR_ACTIVITY_ALIAS = | 84 private static final String VR_ACTIVITY_ALIAS = |
88 "org.chromium.chrome.browser.VRChromeTabbedActivity"; | 85 "org.chromium.chrome.browser.VRChromeTabbedActivity"; |
89 | 86 |
90 private static final String VR_CORE_PACKAGE_ID = "com.google.vr.vrcore"; | 87 private static final String VR_CORE_PACKAGE_ID = "com.google.vr.vrcore"; |
91 | 88 |
92 private static final long REENTER_VR_TIMEOUT_MS = 1000; | 89 private static final long REENTER_VR_TIMEOUT_MS = 1000; |
93 | 90 |
94 private static VrShellDelegate sInstance; | 91 private static VrShellDelegate sInstance; |
95 | 92 |
96 private final ChromeActivity mActivity; | 93 private final ChromeActivity mActivity; |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 | 219 |
223 public static int getVrSupportLevel(VrDaydreamApi daydreamApi, | 220 public static int getVrSupportLevel(VrDaydreamApi daydreamApi, |
224 VrCoreVersionChecker versionChecker, Tab tabToShowInfobarIn) { | 221 VrCoreVersionChecker versionChecker, Tab tabToShowInfobarIn) { |
225 if (versionChecker == null || daydreamApi == null | 222 if (versionChecker == null || daydreamApi == null |
226 || !isVrCoreCompatible(versionChecker, tabToShowInfobarIn)) { | 223 || !isVrCoreCompatible(versionChecker, tabToShowInfobarIn)) { |
227 return VR_NOT_AVAILABLE; | 224 return VR_NOT_AVAILABLE; |
228 } | 225 } |
229 | 226 |
230 if (daydreamApi.isDaydreamReadyDevice()) return VR_DAYDREAM; | 227 if (daydreamApi.isDaydreamReadyDevice()) return VR_DAYDREAM; |
231 | 228 |
232 // Check cardboard support for non-daydream devices. Supported Build ver
sion is determined | |
233 // by the webvr cardboard support feature. Default is KITKAT unless spec
ified via server | |
234 // side finch config. | |
235 if (Build.VERSION.SDK_INT < ChromeFeatureList.getFieldTrialParamByFeatur
eAsInt( | |
236 ChromeFeatureList.WEBVR_CARDBOARD_SU
PPORT, | |
237 MIN_SDK_VERSION_PARAM_NAME, | |
238 Build.VERSION_CODES.KITKAT)) { | |
239 return VR_NOT_AVAILABLE; | |
240 } | |
241 | |
242 return VR_CARDBOARD; | 229 return VR_CARDBOARD; |
243 } | 230 } |
244 | 231 |
245 @CalledByNative | 232 @CalledByNative |
246 private static VrShellDelegate getInstance() { | 233 private static VrShellDelegate getInstance() { |
247 Activity activity = ApplicationStatus.getLastTrackedFocusedActivity(); | 234 Activity activity = ApplicationStatus.getLastTrackedFocusedActivity(); |
248 if (sInstance != null && activity instanceof ChromeTabbedActivity) retur
n sInstance; | 235 if (sInstance != null && activity instanceof ChromeTabbedActivity) retur
n sInstance; |
249 if (!LibraryLoader.isInitialized()) return null; | 236 if (!LibraryLoader.isInitialized()) return null; |
250 // Note that we only support ChromeTabbedActivity for now. | 237 // Note that we only support ChromeTabbedActivity for now. |
251 if (activity == null || !(activity instanceof ChromeTabbedActivity)) ret
urn null; | 238 if (activity == null || !(activity instanceof ChromeTabbedActivity)) ret
urn null; |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 private void onExitVRResult(boolean success) { | 604 private void onExitVRResult(boolean success) { |
618 assert mVrSupportLevel != VR_NOT_AVAILABLE; | 605 assert mVrSupportLevel != VR_NOT_AVAILABLE; |
619 // For now, we don't handle re-entering VR when exit fails, so keep tryi
ng to exit. | 606 // For now, we don't handle re-entering VR when exit fails, so keep tryi
ng to exit. |
620 if (!success && sInstance.mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new
Intent())) return; | 607 if (!success && sInstance.mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new
Intent())) return; |
621 sInstance.mVrClassesWrapper.setVrModeEnabled(sInstance.mActivity, false)
; | 608 sInstance.mVrClassesWrapper.setVrModeEnabled(sInstance.mActivity, false)
; |
622 } | 609 } |
623 | 610 |
624 @CalledByNative | 611 @CalledByNative |
625 private long createNonPresentingNativeContext() { | 612 private long createNonPresentingNativeContext() { |
626 if (mVrClassesWrapper == null) return 0; | 613 if (mVrClassesWrapper == null) return 0; |
| 614 // Update VR support level as it can change at runtime |
| 615 updateVrSupportLevel(); |
| 616 if (mVrSupportLevel == VR_NOT_AVAILABLE) return 0; |
627 mNonPresentingGvrContext = mVrClassesWrapper.createNonPresentingGvrConte
xt(mActivity); | 617 mNonPresentingGvrContext = mVrClassesWrapper.createNonPresentingGvrConte
xt(mActivity); |
628 if (mNonPresentingGvrContext == null) return 0; | 618 if (mNonPresentingGvrContext == null) return 0; |
629 return mNonPresentingGvrContext.getNativeGvrContext(); | 619 return mNonPresentingGvrContext.getNativeGvrContext(); |
630 } | 620 } |
631 | 621 |
632 @CalledByNative | 622 @CalledByNative |
633 private void shutdownNonPresentingNativeContext() { | 623 private void shutdownNonPresentingNativeContext() { |
634 if (mNonPresentingGvrContext == null) return; | 624 if (mNonPresentingGvrContext == null) return; |
635 mNonPresentingGvrContext.shutdown(); | 625 mNonPresentingGvrContext.shutdown(); |
636 mNonPresentingGvrContext = null; | 626 mNonPresentingGvrContext = null; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 mRestoreOrientation = null; | 659 mRestoreOrientation = null; |
670 mVrShell.pause(); | 660 mVrShell.pause(); |
671 removeVrViews(); | 661 removeVrViews(); |
672 clearVrModeWindowFlags(); | 662 clearVrModeWindowFlags(); |
673 destroyVrShell(); | 663 destroyVrShell(); |
674 mActivity.getFullscreenManager().setPositionsForTabToNonFullscreen(); | 664 mActivity.getFullscreenManager().setPositionsForTabToNonFullscreen(); |
675 } | 665 } |
676 | 666 |
677 private static boolean isVrCoreCompatible( | 667 private static boolean isVrCoreCompatible( |
678 VrCoreVersionChecker versionChecker, Tab tabToShowInfobarIn) { | 668 VrCoreVersionChecker versionChecker, Tab tabToShowInfobarIn) { |
679 return verifyOrUpdateVrServices( | 669 int vrCoreCompatibility = versionChecker.getVrCoreCompatibility(); |
680 versionChecker.getVrCoreCompatibility(), tabToShowInfobarIn); | 670 |
| 671 if (vrCoreCompatibility == VrCoreVersionChecker.VR_NOT_AVAILABLE |
| 672 || vrCoreCompatibility == VrCoreVersionChecker.VR_OUT_OF_DATE) { |
| 673 promptToUpdateVrServices(vrCoreCompatibility, tabToShowInfobarIn); |
| 674 } |
| 675 |
| 676 return vrCoreCompatibility == VrCoreVersionChecker.VR_READY; |
681 } | 677 } |
682 | 678 |
683 private static boolean verifyOrUpdateVrServices(int vrCoreCompatibility, Tab
tab) { | 679 private static void promptToUpdateVrServices(int vrCoreCompatibility, Tab ta
b) { |
684 if (vrCoreCompatibility == VrCoreVersionChecker.VR_READY) { | |
685 return true; | |
686 } | |
687 if (tab == null) { | 680 if (tab == null) { |
688 return false; | 681 return; |
689 } | |
690 // Make sure OS is supported before showing the user a prompt. | |
691 if (Build.VERSION.SDK_INT < ChromeFeatureList.getFieldTrialParamByFeatur
eAsInt( | |
692 ChromeFeatureList.WEBVR_CARDBOARD_SU
PPORT, | |
693 MIN_SDK_VERSION_PARAM_NAME, | |
694 Build.VERSION_CODES.KITKAT)) { | |
695 return false; | |
696 } | 682 } |
697 final Activity activity = tab.getActivity(); | 683 final Activity activity = tab.getActivity(); |
698 String infobarText; | 684 String infobarText; |
699 String buttonText; | 685 String buttonText; |
700 if (vrCoreCompatibility == VrCoreVersionChecker.VR_NOT_AVAILABLE) { | 686 if (vrCoreCompatibility == VrCoreVersionChecker.VR_NOT_AVAILABLE) { |
701 // Supported, but not installed. Ask user to install instead of upgr
ade. | 687 // Supported, but not installed. Ask user to install instead of upgr
ade. |
702 infobarText = activity.getString(R.string.vr_services_check_infobar_
install_text); | 688 infobarText = activity.getString(R.string.vr_services_check_infobar_
install_text); |
703 buttonText = activity.getString(R.string.vr_services_check_infobar_i
nstall_button); | 689 buttonText = activity.getString(R.string.vr_services_check_infobar_i
nstall_button); |
704 } else if (vrCoreCompatibility == VrCoreVersionChecker.VR_OUT_OF_DATE) { | 690 } else if (vrCoreCompatibility == VrCoreVersionChecker.VR_OUT_OF_DATE) { |
705 infobarText = activity.getString(R.string.vr_services_check_infobar_
update_text); | 691 infobarText = activity.getString(R.string.vr_services_check_infobar_
update_text); |
706 buttonText = activity.getString(R.string.vr_services_check_infobar_u
pdate_button); | 692 buttonText = activity.getString(R.string.vr_services_check_infobar_u
pdate_button); |
707 } else { | 693 } else { |
708 Log.e(TAG, "Unknown VrCore compatibility: " + vrCoreCompatibility); | 694 Log.e(TAG, "Unknown VrCore compatibility: " + vrCoreCompatibility); |
709 return false; | 695 return; |
710 } | 696 } |
711 | 697 |
712 SimpleConfirmInfoBarBuilder.create(tab, | 698 SimpleConfirmInfoBarBuilder.create(tab, |
713 new SimpleConfirmInfoBarBuilder.Listener() { | 699 new SimpleConfirmInfoBarBuilder.Listener() { |
714 @Override | 700 @Override |
715 public void onInfoBarDismissed() {} | 701 public void onInfoBarDismissed() {} |
716 | 702 |
717 @Override | 703 @Override |
718 public boolean onInfoBarButtonClicked(boolean isPrimary) { | 704 public boolean onInfoBarButtonClicked(boolean isPrimary) { |
719 activity.startActivity(new Intent(Intent.ACTION_VIEW, | 705 activity.startActivity(new Intent(Intent.ACTION_VIEW, |
720 Uri.parse("market://details?id=" + VR_CORE_PACKA
GE_ID))); | 706 Uri.parse("market://details?id=" + VR_CORE_PACKA
GE_ID))); |
721 return false; | 707 return false; |
722 } | 708 } |
723 }, | 709 }, |
724 InfoBarIdentifier.VR_SERVICES_UPGRADE_ANDROID, R.drawable.vr_ser
vices, infobarText, | 710 InfoBarIdentifier.VR_SERVICES_UPGRADE_ANDROID, R.drawable.vr_ser
vices, infobarText, |
725 buttonText, null, true); | 711 buttonText, null, true); |
726 return false; | |
727 } | 712 } |
728 | 713 |
729 private boolean createVrShell() { | 714 private boolean createVrShell() { |
730 if (mVrClassesWrapper == null) return false; | 715 if (mVrClassesWrapper == null) return false; |
731 mTabModelSelector = mActivity.getCompositorViewHolder().detachForVR(); | 716 mTabModelSelector = mActivity.getCompositorViewHolder().detachForVR(); |
732 if (mTabModelSelector == null) return false; | 717 if (mTabModelSelector == null) return false; |
733 mVrShell = mVrClassesWrapper.createVrShell(mActivity, this, mTabModelSel
ector); | 718 mVrShell = mVrClassesWrapper.createVrShell(mActivity, this, mTabModelSel
ector); |
734 return mVrShell != null; | 719 return mVrShell != null; |
735 } | 720 } |
736 | 721 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 private native long nativeInit(); | 810 private native long nativeInit(); |
826 private static native void nativeOnLibraryAvailable(); | 811 private static native void nativeOnLibraryAvailable(); |
827 private native void nativeSetPresentResult(long nativeVrShellDelegate, boole
an result); | 812 private native void nativeSetPresentResult(long nativeVrShellDelegate, boole
an result); |
828 private native void nativeDisplayActivate(long nativeVrShellDelegate); | 813 private native void nativeDisplayActivate(long nativeVrShellDelegate); |
829 private native void nativeUpdateVSyncInterval(long nativeVrShellDelegate, lo
ng timebaseNanos, | 814 private native void nativeUpdateVSyncInterval(long nativeVrShellDelegate, lo
ng timebaseNanos, |
830 double intervalSeconds); | 815 double intervalSeconds); |
831 private native void nativeOnPause(long nativeVrShellDelegate); | 816 private native void nativeOnPause(long nativeVrShellDelegate); |
832 private native void nativeOnResume(long nativeVrShellDelegate); | 817 private native void nativeOnResume(long nativeVrShellDelegate); |
833 private native void nativeDestroy(long nativeVrShellDelegate); | 818 private native void nativeDestroy(long nativeVrShellDelegate); |
834 } | 819 } |
OLD | NEW |