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

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

Issue 2699643003: Show an infobar when VR services need to be installed or updated. (Closed)
Patch Set: update text resources, fix naming mismatches Created 3 years, 10 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.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.os.Build; 15 import android.os.Build;
15 import android.os.Handler; 16 import android.os.Handler;
16 import android.os.StrictMode; 17 import android.os.StrictMode;
17 import android.os.SystemClock; 18 import android.os.SystemClock;
18 import android.support.annotation.IntDef; 19 import android.support.annotation.IntDef;
19 import android.view.Choreographer; 20 import android.view.Choreographer;
20 import android.view.Choreographer.FrameCallback; 21 import android.view.Choreographer.FrameCallback;
21 import android.view.Display; 22 import android.view.Display;
22 import android.view.View; 23 import android.view.View;
23 import android.view.ViewGroup; 24 import android.view.ViewGroup;
24 import android.view.ViewGroup.LayoutParams; 25 import android.view.ViewGroup.LayoutParams;
25 import android.view.WindowManager; 26 import android.view.WindowManager;
26 import android.widget.FrameLayout; 27 import android.widget.FrameLayout;
27 28
28 import org.chromium.base.Log; 29 import org.chromium.base.Log;
30 import org.chromium.base.PackageUtils;
29 import org.chromium.base.VisibleForTesting; 31 import org.chromium.base.VisibleForTesting;
30 import org.chromium.base.annotations.CalledByNative; 32 import org.chromium.base.annotations.CalledByNative;
31 import org.chromium.base.annotations.JNINamespace; 33 import org.chromium.base.annotations.JNINamespace;
32 import org.chromium.base.library_loader.LibraryLoader; 34 import org.chromium.base.library_loader.LibraryLoader;
35
36 import org.chromium.chrome.R;
33 import org.chromium.chrome.browser.ChromeActivity; 37 import org.chromium.chrome.browser.ChromeActivity;
34 import org.chromium.chrome.browser.ChromeFeatureList; 38 import org.chromium.chrome.browser.ChromeFeatureList;
35 import org.chromium.chrome.browser.ChromeTabbedActivity; 39 import org.chromium.chrome.browser.ChromeTabbedActivity;
40 import org.chromium.chrome.browser.infobar.InfoBarIdentifier;
41 import org.chromium.chrome.browser.infobar.SimpleConfirmInfoBarBuilder;
36 import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; 42 import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
37 import org.chromium.chrome.browser.tab.Tab; 43 import org.chromium.chrome.browser.tab.Tab;
38 import org.chromium.chrome.browser.tabmodel.TabModel; 44 import org.chromium.chrome.browser.tabmodel.TabModel;
39 import org.chromium.chrome.browser.tabmodel.TabModelUtils; 45 import org.chromium.chrome.browser.tabmodel.TabModelUtils;
40 46
41 import java.lang.annotation.Retention; 47 import java.lang.annotation.Retention;
42 import java.lang.annotation.RetentionPolicy; 48 import java.lang.annotation.RetentionPolicy;
43 import java.lang.reflect.Constructor; 49 import java.lang.reflect.Constructor;
44 import java.lang.reflect.InvocationTargetException; 50 import java.lang.reflect.InvocationTargetException;
45 51
(...skipping 26 matching lines...) Expand all
72 // TODO(bshe): These should be replaced by string provided by NDK. Currently , it only available 78 // TODO(bshe): These should be replaced by string provided by NDK. Currently , it only available
73 // in SDK and we don't want add dependency to SDK just to get these strings. 79 // in SDK and we don't want add dependency to SDK just to get these strings.
74 private static final String DAYDREAM_CATEGORY = "com.google.intent.category. DAYDREAM"; 80 private static final String DAYDREAM_CATEGORY = "com.google.intent.category. DAYDREAM";
75 private static final String CARDBOARD_CATEGORY = "com.google.intent.category .CARDBOARD"; 81 private static final String CARDBOARD_CATEGORY = "com.google.intent.category .CARDBOARD";
76 82
77 private static final String MIN_SDK_VERSION_PARAM_NAME = "min_sdk_version"; 83 private static final String MIN_SDK_VERSION_PARAM_NAME = "min_sdk_version";
78 84
79 private static final String VR_ACTIVITY_ALIAS = 85 private static final String VR_ACTIVITY_ALIAS =
80 "org.chromium.chrome.browser.VRChromeTabbedActivity"; 86 "org.chromium.chrome.browser.VRChromeTabbedActivity";
81 87
88 private static final String VR_CORE_PACKAGE_ID = "com.google.vr.vrcore";
89 private static final int VR_CORE_MIN_VERSION = 160723800;
90
82 private static final long REENTER_VR_TIMEOUT_MS = 1000; 91 private static final long REENTER_VR_TIMEOUT_MS = 1000;
83 92
84 private final ChromeTabbedActivity mActivity; 93 private final ChromeTabbedActivity mActivity;
85 private Intent mEnterVRIntent; 94 private Intent mEnterVRIntent;
86 95
87 @VrSupportLevel 96 @VrSupportLevel
88 private int mVrSupportLevel; 97 private int mVrSupportLevel;
89 98
90 private final VrClassesWrapper mVrClassesWrapper; 99 private final VrClassesWrapper mVrClassesWrapper;
91 private VrShell mVrShell; 100 private VrShell mVrShell;
92 private NonPresentingGvrContext mNonPresentingGvrContext; 101 private NonPresentingGvrContext mNonPresentingGvrContext;
93 private VrDaydreamApi mVrDaydreamApi; 102 private VrDaydreamApi mVrDaydreamApi;
94 private VrCoreVersionChecker mVrCoreVersionChecker; 103 private VrCoreVersionChecker mVrCoreVersionChecker;
95 104
96 private boolean mInVr; 105 private boolean mInVr;
97 private boolean mEnteringVr; 106 private boolean mEnteringVr;
98 private boolean mPaused; 107 private boolean mPaused;
99 private int mRestoreSystemUiVisibilityFlag = -1; 108 private int mRestoreSystemUiVisibilityFlag = -1;
100 private Integer mRestoreOrientation = null; 109 private Integer mRestoreOrientation = null;
101 private long mNativeVrShellDelegate; 110 private long mNativeVrShellDelegate;
102 private boolean mRequestedWebVR; 111 private boolean mRequestedWebVR;
103 private long mLastVRExit; 112 private long mLastVRExit;
104 private boolean mListeningForWebVrActivate; 113 private boolean mListeningForWebVrActivate;
105 private boolean mListeningForWebVrActivateBeforePause; 114 private boolean mListeningForWebVrActivateBeforePause;
106 115
107 public VrShellDelegate(ChromeTabbedActivity activity) { 116 public VrShellDelegate(ChromeTabbedActivity activity) {
108 mActivity = activity; 117 mActivity = activity;
109 mVrClassesWrapper = createVrClassesWrapper(); 118 mVrClassesWrapper = createVrClassesWrapper();
110 updateVrSupportLevel();
111 } 119 }
112 120
113 /** 121 /**
114 * Updates mVrSupportLevel to the correct value. isVrCoreCompatible might re turn different value 122 * Updates mVrSupportLevel to the correct value. isVrCoreCompatible might re turn different value
115 * at runtime. 123 * at runtime.
116 */ 124 */
117 // TODO(bshe): Find a place to call this function again, i.e. page refresh o r onResume. 125 // TODO(bshe): Find a place to call this function again, i.e. page refresh o r onResume.
118 // TODO(mthiesse): Clean this function up, lots of duplicated code. 126 // TODO(mthiesse): Clean this function up, lots of duplicated code.
119 private void updateVrSupportLevel() { 127 private void updateVrSupportLevel() {
120 if (mVrClassesWrapper == null || !isVrCoreCompatible()) { 128 if (mVrClassesWrapper == null || !isVrCoreCompatible()) {
121 mVrSupportLevel = VR_NOT_AVAILABLE; 129 mVrSupportLevel = VR_NOT_AVAILABLE;
122 mEnterVRIntent = null; 130 mEnterVRIntent = null;
123 return; 131 return;
124 } 132 }
125 133
126 if (mVrDaydreamApi == null) { 134 if (mVrDaydreamApi == null) {
127 mVrDaydreamApi = mVrClassesWrapper.createVrDaydreamApi(); 135 mVrDaydreamApi = mVrClassesWrapper.createVrDaydreamApi();
128 } 136 }
129 137
130 // Check cardboard support for non-daydream devices. 138 // Check cardboard support for non-daydream devices.
131 if (!mVrDaydreamApi.isDaydreamReadyDevice()) { 139 if (!mVrDaydreamApi.isDaydreamReadyDevice()) {
132 // Native libraries may not be ready in which case skip for now and check later. 140 // Supported Build version is determined by the webvr cardboard supp ort feature.
133 if (LibraryLoader.isInitialized()) { 141 // Default is KITKAT unless specified via server side finch config.
134 // Supported Build version is determined by the webvr cardboard support feature. 142 if (Build.VERSION.SDK_INT < ChromeFeatureList.getFieldTrialParamByFe atureAsInt(
135 // Default is KITKAT unless specified via server side finch conf ig. 143 ChromeFeatureList.WEBVR_CARDBOAR D_SUPPORT,
136 if (Build.VERSION.SDK_INT 144 MIN_SDK_VERSION_PARAM_NAME,
137 < ChromeFeatureList.getFieldTrialParamByFeatureAsInt( 145 Build.VERSION_CODES.KITKAT)) {
138 ChromeFeatureList.WEBVR_CARDBOARD_SUPPORT, 146 mVrSupportLevel = VR_NOT_AVAILABLE;
139 MIN_SDK_VERSION_PARAM_NAME, 147 mEnterVRIntent = null;
140 Build.VERSION_CODES.KITKAT)) { 148 return;
141 mVrSupportLevel = VR_NOT_AVAILABLE;
142 mEnterVRIntent = null;
143 return;
144 }
145 } 149 }
146 } 150 }
147 151
148 if (mEnterVRIntent == null) { 152 if (mEnterVRIntent == null) {
149 mEnterVRIntent = 153 mEnterVRIntent =
150 mVrDaydreamApi.createVrIntent(new ComponentName(mActivity, V R_ACTIVITY_ALIAS)); 154 mVrDaydreamApi.createVrIntent(new ComponentName(mActivity, V R_ACTIVITY_ALIAS));
151 } 155 }
152 mVrSupportLevel = mVrDaydreamApi.isDaydreamReadyDevice() ? VR_DAYDREAM : VR_CARDBOARD; 156 mVrSupportLevel = mVrDaydreamApi.isDaydreamReadyDevice() ? VR_DAYDREAM : VR_CARDBOARD;
153 } 157 }
154 158
159 private boolean verifyOrUpdateVrServices(Tab tab) {
160 if (!LibraryLoader.isInitialized()) {
161 return false;
162 }
163 int vrCoreVersion = PackageUtils.getPackageVersion(mActivity, VR_CORE_PA CKAGE_ID);
164 if (vrCoreVersion < VR_CORE_MIN_VERSION) {
165 // Assume upgrade as most common case.
166 String infobarText =
167 mActivity.getString(R.string.vr_services_check_infobar_updat e_text);
168 String buttonText =
169 mActivity.getString(R.string.vr_services_check_infobar_updat e_button);
170 if (vrCoreVersion == -1) {
171 // VrCore not installed, make sure it's supported before showing the user a prompt.
172 if (Build.VERSION.SDK_INT < ChromeFeatureList.getFieldTrialParam ByFeatureAsInt(
173 ChromeFeatureList.WEBVR_CARD BOARD_SUPPORT,
174 MIN_SDK_VERSION_PARAM_NAME,
175 Build.VERSION_CODES.KITKAT)) {
176 return false;
177 }
178 // Supported, but not installed. Ask user to install instead of upgrade.
179 infobarText = mActivity.getString(R.string.vr_services_check_inf obar_install_text);
180 buttonText = mActivity.getString(R.string.vr_services_check_info bar_install_button);
181 }
182 SimpleConfirmInfoBarBuilder.create(tab,
183 new SimpleConfirmInfoBarBuilder.Listener() {
184 @Override
185 public void onInfoBarDismissed() {}
186
187 @Override
188 public boolean onInfoBarButtonClicked(boolean isPrimary) {
189 mActivity.startActivity(new Intent(Intent.ACTION_VIE W,
190 Uri.parse("market://details?id=" + VR_CORE_P ACKAGE_ID)));
191 return false;
192 }
193 },
194 InfoBarIdentifier.VR_SERVICES_UPGRADE_ANDROID, R.drawable.vr _services,
195 infobarText, buttonText, null, true);
196 return false;
197 }
198 return true;
199 }
200
155 /** 201 /**
156 * Should be called once the native library is loaded so that the native por tion of this class 202 * Should be called once the native library is loaded so that the native por tion of this class
157 * can be initialized. 203 * can be initialized.
158 */ 204 */
159 public void onNativeLibraryReady() { 205 public void onNativeLibraryReady() {
160 // Libraries may not have been loaded when we first set the support leve l, so check again.
161 updateVrSupportLevel(); 206 updateVrSupportLevel();
162 if (mVrSupportLevel == VR_NOT_AVAILABLE) return; 207 if (mVrSupportLevel == VR_NOT_AVAILABLE) return;
163 mNativeVrShellDelegate = nativeInit(); 208 mNativeVrShellDelegate = nativeInit();
164 Choreographer choreographer = Choreographer.getInstance(); 209 Choreographer choreographer = Choreographer.getInstance();
165 choreographer.postFrameCallback(new FrameCallback() { 210 choreographer.postFrameCallback(new FrameCallback() {
166 @Override 211 @Override
167 public void doFrame(long frameTimeNanos) { 212 public void doFrame(long frameTimeNanos) {
168 Display display = ((WindowManager) mActivity.getSystemService( 213 Display display = ((WindowManager) mActivity.getSystemService(
169 Context.WINDOW_SERVICE)).getDefaultDisplay(); 214 Context.WINDOW_SERVICE)).getDefaultDisplay();
170 nativeUpdateVSyncInterval(mNativeVrShellDelegate, frameTimeNanos , 215 nativeUpdateVSyncInterval(mNativeVrShellDelegate, frameTimeNanos ,
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 default: 374 default:
330 Log.e(TAG, "Unexpected enum."); 375 Log.e(TAG, "Unexpected enum.");
331 } 376 }
332 } 377 }
333 378
334 /** 379 /**
335 * Enters VR Shell if necessary, displaying browser UI and tab contents in V R. 380 * Enters VR Shell if necessary, displaying browser UI and tab contents in V R.
336 */ 381 */
337 @EnterVRResult 382 @EnterVRResult
338 public int enterVRIfNecessary() { 383 public int enterVRIfNecessary() {
384 // TODO(amp): Move the UpdateVrService check to where it can check after a WebVR API call.
385 if (!verifyOrUpdateVrServices(mActivity.getActivityTab())) return ENTER_ VR_CANCELLED;
339 if (mVrSupportLevel == VR_NOT_AVAILABLE) return ENTER_VR_CANCELLED; 386 if (mVrSupportLevel == VR_NOT_AVAILABLE) return ENTER_VR_CANCELLED;
340 if (mInVr) return ENTER_VR_NOT_NECESSARY; 387 if (mInVr) return ENTER_VR_NOT_NECESSARY;
341 if (!canEnterVR(mActivity.getActivityTab())) return ENTER_VR_CANCELLED; 388 if (!canEnterVR(mActivity.getActivityTab())) return ENTER_VR_CANCELLED;
342 389
343 if (mVrSupportLevel == VR_CARDBOARD || !mVrDaydreamApi.isDaydreamCurrent Viewer()) { 390 if (mVrSupportLevel == VR_CARDBOARD || !mVrDaydreamApi.isDaydreamCurrent Viewer()) {
344 // Avoid using launchInVr which would trigger DON flow regardless cu rrent viewer type 391 // Avoid using launchInVr which would trigger DON flow regardless cu rrent viewer type
345 // due to the lack of support for unexported activities. 392 // due to the lack of support for unexported activities.
346 enterVR(); 393 enterVR();
347 } else { 394 } else {
348 if (!mVrDaydreamApi.launchInVr(getPendingEnterVRIntent())) return EN TER_VR_CANCELLED; 395 if (!mVrDaydreamApi.launchInVr(getPendingEnterVRIntent())) return EN TER_VR_CANCELLED;
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 } 691 }
645 692
646 private native long nativeInit(); 693 private native long nativeInit();
647 private native void nativeSetPresentResult(long nativeVrShellDelegate, boole an result); 694 private native void nativeSetPresentResult(long nativeVrShellDelegate, boole an result);
648 private native void nativeDisplayActivate(long nativeVrShellDelegate); 695 private native void nativeDisplayActivate(long nativeVrShellDelegate);
649 private native void nativeUpdateVSyncInterval(long nativeVrShellDelegate, lo ng timebaseNanos, 696 private native void nativeUpdateVSyncInterval(long nativeVrShellDelegate, lo ng timebaseNanos,
650 double intervalSeconds); 697 double intervalSeconds);
651 private native void nativeOnPause(long nativeVrShellDelegate); 698 private native void nativeOnPause(long nativeVrShellDelegate);
652 private native void nativeOnResume(long nativeVrShellDelegate); 699 private native void nativeOnResume(long nativeVrShellDelegate);
653 } 700 }
OLDNEW
« no previous file with comments | « chrome/android/java/res/drawable-xxxhdpi/vr_services.png ('k') | chrome/android/java/strings/android_chrome_strings.grd » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698