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

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

Issue 2727873002: Implement lazy initialization for VrShellDelegate (Closed)
Patch Set: Fix support for DON flow from headset insertion. Created 3 years, 9 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.net.Uri;
15 import android.os.Build; 15 import android.os.Build;
16 import android.os.Handler; 16 import android.os.Handler;
17 import android.os.StrictMode; 17 import android.os.StrictMode;
18 import android.os.SystemClock; 18 import android.os.SystemClock;
19 import android.support.annotation.IntDef; 19 import android.support.annotation.IntDef;
20 import android.view.Choreographer; 20 import android.view.Choreographer;
21 import android.view.Choreographer.FrameCallback; 21 import android.view.Choreographer.FrameCallback;
22 import android.view.Display; 22 import android.view.Display;
23 import android.view.View; 23 import android.view.View;
24 import android.view.ViewGroup; 24 import android.view.ViewGroup;
25 import android.view.ViewGroup.LayoutParams; 25 import android.view.ViewGroup.LayoutParams;
26 import android.view.WindowManager; 26 import android.view.WindowManager;
27 import android.widget.FrameLayout; 27 import android.widget.FrameLayout;
28 28
29 import org.chromium.base.ApplicationStatus;
29 import org.chromium.base.Log; 30 import org.chromium.base.Log;
30 import org.chromium.base.VisibleForTesting; 31 import org.chromium.base.VisibleForTesting;
31 import org.chromium.base.annotations.CalledByNative; 32 import org.chromium.base.annotations.CalledByNative;
32 import org.chromium.base.annotations.JNINamespace; 33 import org.chromium.base.annotations.JNINamespace;
33 import org.chromium.base.library_loader.LibraryLoader; 34 import org.chromium.base.library_loader.LibraryLoader;
34
35 import org.chromium.chrome.R; 35 import org.chromium.chrome.R;
36 import org.chromium.chrome.browser.ChromeActivity; 36 import org.chromium.chrome.browser.ChromeActivity;
37 import org.chromium.chrome.browser.ChromeFeatureList; 37 import org.chromium.chrome.browser.ChromeFeatureList;
38 import org.chromium.chrome.browser.ChromeTabbedActivity; 38 import org.chromium.chrome.browser.ChromeTabbedActivity;
39 import org.chromium.chrome.browser.infobar.InfoBarIdentifier; 39 import org.chromium.chrome.browser.infobar.InfoBarIdentifier;
40 import org.chromium.chrome.browser.infobar.SimpleConfirmInfoBarBuilder; 40 import org.chromium.chrome.browser.infobar.SimpleConfirmInfoBarBuilder;
41 import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; 41 import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
42 import org.chromium.chrome.browser.tab.Tab; 42 import org.chromium.chrome.browser.tab.Tab;
43 import org.chromium.chrome.browser.tabmodel.TabModel; 43 import org.chromium.chrome.browser.tabmodel.TabModel;
44 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
44 import org.chromium.chrome.browser.tabmodel.TabModelUtils; 45 import org.chromium.chrome.browser.tabmodel.TabModelUtils;
45 46
46 import java.lang.annotation.Retention; 47 import java.lang.annotation.Retention;
47 import java.lang.annotation.RetentionPolicy; 48 import java.lang.annotation.RetentionPolicy;
48 import java.lang.reflect.Constructor; 49 import java.lang.reflect.Constructor;
49 import java.lang.reflect.InvocationTargetException; 50 import java.lang.reflect.InvocationTargetException;
50 51
51 /** 52 /**
52 * Manages interactions with the VR Shell. 53 * Manages interactions with the VR Shell.
53 */ 54 */
(...skipping 27 matching lines...) Expand all
81 82
82 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";
83 84
84 private static final String VR_ACTIVITY_ALIAS = 85 private static final String VR_ACTIVITY_ALIAS =
85 "org.chromium.chrome.browser.VRChromeTabbedActivity"; 86 "org.chromium.chrome.browser.VRChromeTabbedActivity";
86 87
87 private static final String VR_CORE_PACKAGE_ID = "com.google.vr.vrcore"; 88 private static final String VR_CORE_PACKAGE_ID = "com.google.vr.vrcore";
88 89
89 private static final long REENTER_VR_TIMEOUT_MS = 1000; 90 private static final long REENTER_VR_TIMEOUT_MS = 1000;
90 91
91 private final ChromeTabbedActivity mActivity; 92 private static VrShellDelegate sInstance;
92 private Intent mEnterVRIntent; 93
94 private final ChromeActivity mActivity;
93 95
94 @VrSupportLevel 96 @VrSupportLevel
95 private int mVrSupportLevel; 97 private int mVrSupportLevel;
96 98
97 private final VrClassesWrapper mVrClassesWrapper; 99 private final VrClassesWrapper mVrClassesWrapper;
98 private VrShell mVrShell; 100 private VrShell mVrShell;
99 private NonPresentingGvrContext mNonPresentingGvrContext; 101 private NonPresentingGvrContext mNonPresentingGvrContext;
100 private VrDaydreamApi mVrDaydreamApi; 102 private VrDaydreamApi mVrDaydreamApi;
101 private VrCoreVersionChecker mVrCoreVersionChecker; 103 private VrCoreVersionChecker mVrCoreVersionChecker;
104 private TabModelSelector mTabModelSelector;
102 105
103 private boolean mInVr; 106 private boolean mInVr;
104 private boolean mEnteringVr; 107 private boolean mEnteringVr;
105 private boolean mPaused; 108 private boolean mPaused;
106 private int mRestoreSystemUiVisibilityFlag = -1; 109 private int mRestoreSystemUiVisibilityFlag = -1;
107 private Integer mRestoreOrientation = null; 110 private Integer mRestoreOrientation = null;
108 private long mNativeVrShellDelegate; 111 private long mNativeVrShellDelegate;
109 private boolean mRequestedWebVR; 112 private boolean mRequestedWebVR;
110 private long mLastVRExit; 113 private long mLastVRExit;
111 private boolean mListeningForWebVrActivate; 114 private boolean mListeningForWebVrActivate;
112 private boolean mListeningForWebVrActivateBeforePause; 115 private boolean mListeningForWebVrActivateBeforePause;
113 116
114 public VrShellDelegate(ChromeTabbedActivity activity) { 117 /**
115 mActivity = activity; 118 * Called when the native library is first available.
116 mVrClassesWrapper = createVrClassesWrapper(); 119 */
120 public static void onNativeLibraryAvailable() {
121 nativeOnLibraryAvailable();
117 } 122 }
118 123
119 /** 124 /**
120 * Updates mVrSupportLevel to the correct value. isVrCoreCompatible might re turn different value 125 * @return A helper class for creating VR-specific classes that may not be a vailable at compile
121 * at runtime. 126 * time.
122 */ 127 */
123 // TODO(bshe): Find a place to call this function again, i.e. page refresh o r onResume. 128 @VisibleForTesting
124 // TODO(mthiesse): Clean this function up, lots of duplicated code. 129 public static VrClassesWrapper getVrClassesWrapper() {
125 private void updateVrSupportLevel() { 130 if (sInstance != null) return sInstance.mVrClassesWrapper;
126 if (mVrClassesWrapper == null || !isVrCoreCompatible()) { 131 return createVrClassesWrapper();
127 mVrSupportLevel = VR_NOT_AVAILABLE;
128 mEnterVRIntent = null;
129 return;
130 }
131
132 if (mVrDaydreamApi == null) {
133 mVrDaydreamApi = mVrClassesWrapper.createVrDaydreamApi();
134 }
135
136 // Check cardboard support for non-daydream devices.
137 if (!mVrDaydreamApi.isDaydreamReadyDevice()) {
138 // Supported Build version is determined by the webvr cardboard supp ort feature.
139 // Default is KITKAT unless specified via server side finch config.
140 if (Build.VERSION.SDK_INT < ChromeFeatureList.getFieldTrialParamByFe atureAsInt(
141 ChromeFeatureList.WEBVR_CARDBOAR D_SUPPORT,
142 MIN_SDK_VERSION_PARAM_NAME,
143 Build.VERSION_CODES.KITKAT)) {
144 mVrSupportLevel = VR_NOT_AVAILABLE;
145 mEnterVRIntent = null;
146 return;
147 }
148 }
149
150 if (mEnterVRIntent == null) {
151 mEnterVRIntent =
152 mVrDaydreamApi.createVrIntent(new ComponentName(mActivity, V R_ACTIVITY_ALIAS));
153 }
154 mVrSupportLevel = mVrDaydreamApi.isDaydreamReadyDevice() ? VR_DAYDREAM : VR_CARDBOARD;
155 } 132 }
156 133
157 /** 134 /**
158 * Should be called once the native library is loaded so that the native por tion of this class 135 * Pauses VR Shell, if it needs to be paused.
159 * can be initialized.
160 */ 136 */
161 public void onNativeLibraryReady() { 137 public static void maybePauseVR(ChromeActivity activity) {
162 updateVrSupportLevel(); 138 maybeUnregisterDaydreamIntent(activity);
163 if (mVrSupportLevel == VR_NOT_AVAILABLE) return; 139 if (sInstance == null) return;
164 mNativeVrShellDelegate = nativeInit(); 140 if (sInstance.mActivity != activity) {
165 Choreographer choreographer = Choreographer.getInstance(); 141 assert !sInstance.mInVr;
166 choreographer.postFrameCallback(new FrameCallback() { 142 return;
167 @Override 143 }
168 public void doFrame(long frameTimeNanos) { 144 sInstance.pauseVR();
169 Display display = ((WindowManager) mActivity.getSystemService( 145 }
170 Context.WINDOW_SERVICE)).getDefaultDisplay(); 146
171 nativeUpdateVSyncInterval(mNativeVrShellDelegate, frameTimeNanos , 147 /**
172 1.0d / display.getRefreshRate()); 148 * Resumes VR Shell, if it needs to be resumed.
173 } 149 */
174 }); 150 public static void maybeResumeVR(ChromeActivity activity) {
151 maybeRegisterDaydreamIntent(activity);
152 if (sInstance == null) return;
153 if (sInstance.mActivity != activity) {
154 assert !sInstance.mInVr;
155 return;
156 }
157 sInstance.resumeVR();
158 }
159
160 /**
161 * Whether or not we are currently in VR.
162 */
163 public static boolean isInVR() {
164 if (sInstance == null) return false;
165 return sInstance.mInVr;
166 }
167
168 /**
169 * See {@link ChromeActivity#handleBackPressed}
170 * Only handles the back press while in VR.
171 */
172 public static boolean onBackPressed() {
173 if (sInstance == null) return false;
174 return sInstance.onBackPressedInternal();
175 }
176
177 /**
178 * Enters VR on the current tab if possible.
179 */
180 public static void enterVRIfNecessary() {
181 boolean created_delegate = sInstance == null;
182 VrShellDelegate instance = getInstance();
183 if (instance == null) return;
184 if (instance.enterVRInternal() == ENTER_VR_CANCELLED && created_delegate ) {
185 instance.destroy();
186 }
187 }
188
189 /**
190 * Handles a VR intent, entering VR in the process.
191 */
192 public static void enterVRFromIntent(Intent intent) {
193 assert isDaydreamVrIntent(intent);
194 boolean created_delegate = sInstance == null;
195 VrShellDelegate instance = getInstance();
196 if (instance == null) return;
197 if (!instance.enterVRFromIntent() && created_delegate) instance.destroy( );
198 }
199
200 /**
201 * Whether or not the intent is a Daydream VR Intent.
202 */
203 public static boolean isDaydreamVrIntent(Intent intent) {
204 if (intent == null || intent.getCategories() == null) return false;
205 return intent.getCategories().contains(DAYDREAM_CATEGORY);
206 }
207
208 /**
209 * Handles the result of the exit VR flow (DOFF).
210 */
211 public static void onExitVRResult(int resultCode) {
212 if (sInstance == null) return;
213 sInstance.onExitVRResult(resultCode == Activity.RESULT_OK);
214 }
215
216 public static int getVrSupportLevel(VrDaydreamApi daydreamApi,
217 VrCoreVersionChecker versionChecker, Tab tabToShowInfobarIn) {
218 if (!isVrCoreCompatible(versionChecker, tabToShowInfobarIn) || daydreamA pi == null
219 || versionChecker == null) {
220 return VR_NOT_AVAILABLE;
221 }
222
223 if (daydreamApi.isDaydreamReadyDevice()) return VR_DAYDREAM;
224
225 // Check cardboard support for non-daydream devices. Supported Build ver sion is determined
226 // by the webvr cardboard support feature. Default is KITKAT unless spec ified via server
227 // side finch config.
228 if (Build.VERSION.SDK_INT < ChromeFeatureList.getFieldTrialParamByFeatur eAsInt(
229 ChromeFeatureList.WEBVR_CARDBOARD_SU PPORT,
230 MIN_SDK_VERSION_PARAM_NAME,
231 Build.VERSION_CODES.KITKAT)) {
232 return VR_NOT_AVAILABLE;
233 }
234
235 return VR_CARDBOARD;
236 }
237
238 @CalledByNative
239 private static VrShellDelegate getInstance() {
240 if (sInstance != null) return sInstance;
241 if (!LibraryLoader.isInitialized()) return null;
242 Activity activity = ApplicationStatus.getLastTrackedFocusedActivity();
243 // Note that we only support ChromeTabbedActivity for now.
244 if (activity == null || !(activity instanceof ChromeTabbedActivity)) ret urn null;
245 sInstance = new VrShellDelegate((ChromeActivity) activity);
246
247 return sInstance;
175 } 248 }
176 249
177 @SuppressWarnings("unchecked") 250 @SuppressWarnings("unchecked")
178 private VrClassesWrapper createVrClassesWrapper() { 251 private static VrClassesWrapper createVrClassesWrapper() {
179 try { 252 try {
180 Class<? extends VrClassesWrapper> vrClassesBuilderClass = 253 Class<? extends VrClassesWrapper> vrClassesBuilderClass =
181 (Class<? extends VrClassesWrapper>) Class.forName( 254 (Class<? extends VrClassesWrapper>) Class.forName(
182 "org.chromium.chrome.browser.vr_shell.VrClassesWrapp erImpl"); 255 "org.chromium.chrome.browser.vr_shell.VrClassesWrapp erImpl");
183 Constructor<?> vrClassesBuilderConstructor = 256 Constructor<?> vrClassesBuilderConstructor = vrClassesBuilderClass.g etConstructor();
184 vrClassesBuilderClass.getConstructor(ChromeActivity.class); 257 return (VrClassesWrapper) vrClassesBuilderConstructor.newInstance();
185 return (VrClassesWrapper) vrClassesBuilderConstructor.newInstance(mA ctivity);
186 } catch (ClassNotFoundException | InstantiationException | IllegalAccess Exception 258 } catch (ClassNotFoundException | InstantiationException | IllegalAccess Exception
187 | IllegalArgumentException | InvocationTargetException | NoSuchM ethodException e) { 259 | IllegalArgumentException | InvocationTargetException | NoSuchM ethodException e) {
188 if (!(e instanceof ClassNotFoundException)) { 260 if (!(e instanceof ClassNotFoundException)) {
189 Log.e(TAG, "Unable to instantiate VrClassesWrapper", e); 261 Log.e(TAG, "Unable to instantiate VrClassesWrapper", e);
190 } 262 }
191 return null; 263 return null;
192 } 264 }
193 } 265 }
194 266
267 private static PendingIntent getEnterVRPendingIntent(
268 VrDaydreamApi dayreamApi, Activity activity) {
269 return PendingIntent.getActivity(activity, 0,
270 dayreamApi.createVrIntent(new ComponentName(activity, VR_ACTIVIT Y_ALIAS)),
271 PendingIntent.FLAG_ONE_SHOT);
272 }
273
274 private static void maybeRegisterDaydreamIntent(Activity activity) {
275 if (sInstance != null) return; // Will be handled in onResume.
276 if (!(activity instanceof ChromeTabbedActivity)) return;
277 VrClassesWrapper wrapper = createVrClassesWrapper();
278 if (wrapper == null) return;
279 VrDaydreamApi api = wrapper.createVrDaydreamApi(activity);
280 if (api == null) return;
281 int vrSupportLevel = getVrSupportLevel(api, wrapper.createVrCoreVersionC hecker(), null);
282 if (isVrShellEnabled(vrSupportLevel)) registerDaydreamIntent(api, activi ty);
283 }
284
285 private static void maybeUnregisterDaydreamIntent(Activity activity) {
286 if (sInstance != null) return; // Will be handled in onPause.
287 if (!(activity instanceof ChromeTabbedActivity)) return;
288 VrClassesWrapper wrapper = createVrClassesWrapper();
289 if (wrapper == null) return;
290 VrDaydreamApi api = wrapper.createVrDaydreamApi(activity);
291 if (api == null) return;
292 unregisterDaydreamIntent(api);
293 }
294
295 /**
296 * Registers the Intent to fire after phone inserted into a headset.
297 */
298 private static void registerDaydreamIntent(VrDaydreamApi dayreamApi, Activit y activity) {
299 dayreamApi.registerDaydreamIntent(getEnterVRPendingIntent(dayreamApi, ac tivity));
300 }
301
302 /**
303 * Unregisters the Intent which registered by this context if any.
304 */
305 private static void unregisterDaydreamIntent(VrDaydreamApi dayreamApi) {
306 dayreamApi.unregisterDaydreamIntent();
307 }
308
309 /**
310 * @return Whether or not VR Shell is currently enabled.
311 */
312 private static boolean isVrShellEnabled(int vrSupportLevel) {
313 // Only enable ChromeVR (VrShell) on Daydream devices as it currently ne eds a Daydream
314 // controller.
315 if (vrSupportLevel != VR_DAYDREAM) return false;
316 return ChromeFeatureList.isEnabled(ChromeFeatureList.VR_SHELL);
317 }
318
319 private VrShellDelegate(ChromeActivity activity) {
320 mActivity = activity;
321 mVrClassesWrapper = createVrClassesWrapper();
322 updateVrSupportLevel();
323 if (mVrSupportLevel == VR_NOT_AVAILABLE) return;
amp 2017/03/02 18:11:54 If VR is not available, we still contruct a VrShel
mthiesse 2017/03/02 20:01:58 Oops, meant to remove the early return. The native
324 mNativeVrShellDelegate = nativeInit();
325 Choreographer choreographer = Choreographer.getInstance();
326 choreographer.postFrameCallback(new FrameCallback() {
327 @Override
328 public void doFrame(long frameTimeNanos) {
329 Display display =
330 ((WindowManager) mActivity.getSystemService(Context.WIND OW_SERVICE))
331 .getDefaultDisplay();
332 nativeUpdateVSyncInterval(
333 mNativeVrShellDelegate, frameTimeNanos, 1.0d / display.g etRefreshRate());
334 }
335 });
336 }
337
338 /**
339 * Updates mVrSupportLevel to the correct value. isVrCoreCompatible might re turn different value
340 * at runtime.
341 */
342 // TODO(bshe): Find a place to call this function again, i.e. page refresh o r onResume.
343 private void updateVrSupportLevel() {
344 if (mVrClassesWrapper == null) {
345 mVrSupportLevel = VR_NOT_AVAILABLE;
346 return;
347 }
348 if (mVrCoreVersionChecker == null) {
349 mVrCoreVersionChecker = mVrClassesWrapper.createVrCoreVersionChecker ();
350 }
351 if (mVrDaydreamApi == null) {
352 mVrDaydreamApi = mVrClassesWrapper.createVrDaydreamApi(mActivity);
353 }
354 mVrSupportLevel = getVrSupportLevel(
355 mVrDaydreamApi, mVrCoreVersionChecker, mActivity.getActivityTab( ));
356 }
357
195 /** 358 /**
196 * Handle a VR intent, entering VR in the process unless we're unable to. 359 * Handle a VR intent, entering VR in the process unless we're unable to.
197 */ 360 */
198 public void enterVRFromIntent(Intent intent) { 361 private boolean enterVRFromIntent() {
199 // Vr Intent is only used on Daydream devices. 362 // Vr Intent is only used on Daydream devices.
200 if (mVrSupportLevel != VR_DAYDREAM) return; 363 if (mVrSupportLevel != VR_DAYDREAM) return false;
201 assert isDaydreamVrIntent(intent);
202 if (mListeningForWebVrActivateBeforePause && !mRequestedWebVR) { 364 if (mListeningForWebVrActivateBeforePause && !mRequestedWebVR) {
203 nativeDisplayActivate(mNativeVrShellDelegate); 365 nativeDisplayActivate(mNativeVrShellDelegate);
204 return; 366 return false;
205 } 367 }
206 // Normally, if the active page doesn't have a vrdisplayactivate listene r, and WebVR was not 368 // Normally, if the active page doesn't have a vrdisplayactivate listene r, and WebVR was not
207 // presenting and VrShell was not enabled, we shouldn't enter VR and Day dream Homescreen 369 // presenting and VrShell was not enabled, we shouldn't enter VR and Day dream Homescreen
208 // should show after DON flow. But due to a failure in unregisterDaydrea mIntent, we still 370 // should show after DON flow. But due to a failure in unregisterDaydrea mIntent, we still
209 // try to enterVR. Here we detect this case and force switch to Daydream Homescreen. 371 // try to enterVR. Here we detect this case and force switch to Daydream Homescreen.
210 if (!mListeningForWebVrActivateBeforePause && !mRequestedWebVR && !isVrS hellEnabled()) { 372 if (!mListeningForWebVrActivateBeforePause && !mRequestedWebVR
373 && !isVrShellEnabled(mVrSupportLevel)) {
211 mVrDaydreamApi.launchVrHomescreen(); 374 mVrDaydreamApi.launchVrHomescreen();
212 return; 375 return false;
213 } 376 }
214 377
215 if (mInVr) { 378 if (mInVr) {
216 setEnterVRResult(true); 379 setEnterVRResult(true);
217 return; 380 return false;
218 } 381 }
219 if (!canEnterVR(mActivity.getActivityTab())) { 382 if (!canEnterVR(mActivity.getActivityTab())) {
220 setEnterVRResult(false); 383 setEnterVRResult(false);
221 return; 384 return false;
222 } 385 }
223 if (mPaused) { 386 if (mPaused) {
224 // We can't enter VR before the application resumes, or we encounter bizarre crashes 387 // We can't enter VR before the application resumes, or we encounter bizarre crashes
225 // related to gpu surfaces. Set this flag to enter VR on the next re sume. 388 // related to gpu surfaces. Set this flag to enter VR on the next re sume.
226 prepareToEnterVR(); 389 prepareToEnterVR();
227 mEnteringVr = true; 390 mEnteringVr = true;
228 } else { 391 } else {
229 enterVR(); 392 enterVR();
230 } 393 }
394 return true;
231 } 395 }
232 396
233 private void prepareToEnterVR() { 397 private void prepareToEnterVR() {
234 if (mRestoreOrientation == null) { 398 if (mRestoreOrientation == null) {
235 mRestoreOrientation = mActivity.getRequestedOrientation(); 399 mRestoreOrientation = mActivity.getRequestedOrientation();
236 } 400 }
237 mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSC APE); 401 mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSC APE);
238 setupVrModeWindowFlags(); 402 setupVrModeWindowFlags();
239 } 403 }
240 404
(...skipping 11 matching lines...) Expand all
252 return; 416 return;
253 } 417 }
254 mEnteringVr = false; 418 mEnteringVr = false;
255 if (!createVrShell()) { 419 if (!createVrShell()) {
256 if (mRestoreOrientation != null) mActivity.setRequestedOrientation(m RestoreOrientation); 420 if (mRestoreOrientation != null) mActivity.setRequestedOrientation(m RestoreOrientation);
257 mRestoreOrientation = null; 421 mRestoreOrientation = null;
258 clearVrModeWindowFlags(); 422 clearVrModeWindowFlags();
259 setEnterVRResult(false); 423 setEnterVRResult(false);
260 return; 424 return;
261 } 425 }
262 mVrClassesWrapper.setVrModeEnabled(true); 426 mVrClassesWrapper.setVrModeEnabled(mActivity, true);
263 mInVr = true; 427 mInVr = true;
264 428
265 addVrViews(); 429 addVrViews();
266 mVrShell.initializeNative(mActivity.getActivityTab(), mRequestedWebVR); 430 mVrShell.initializeNative(mActivity.getActivityTab(), mRequestedWebVR);
267 // onResume needs to be called on GvrLayout after initialization to make sure DON flow work 431 // onResume needs to be called on GvrLayout after initialization to make sure DON flow work
268 // properly. 432 // properly.
269 mVrShell.resume(); 433 mVrShell.resume();
270 434
271 setEnterVRResult(true); 435 setEnterVRResult(true);
272 } 436 }
273 437
274 private void setEnterVRResult(boolean success) { 438 private void setEnterVRResult(boolean success) {
275 if (mRequestedWebVR) nativeSetPresentResult(mNativeVrShellDelegate, succ ess); 439 if (mRequestedWebVR) nativeSetPresentResult(mNativeVrShellDelegate, succ ess);
276 if (!success && !mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new Intent()) ) { 440 if (!success && !mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new Intent()) ) {
277 mVrClassesWrapper.setVrModeEnabled(false); 441 mVrClassesWrapper.setVrModeEnabled(mActivity, false);
278 } 442 }
279 mRequestedWebVR = false; 443 mRequestedWebVR = false;
280 } 444 }
281 445
282 /* package */ boolean canEnterVR(Tab tab) { 446 /* package */ boolean canEnterVR(Tab tab) {
283 if (!LibraryLoader.isInitialized()) { 447 if (!LibraryLoader.isInitialized()) {
284 return false; 448 return false;
285 } 449 }
286 // If vr isn't in the build, or we haven't initialized yet, or vr shell is not enabled and 450 if (mVrSupportLevel == VR_NOT_AVAILABLE || mNativeVrShellDelegate == 0) return false;
287 // this is not a web vr request, then return immediately. 451 // If vr shell is not enabled and this is not a web vr request, then ret urn false.
288 if (mVrSupportLevel == VR_NOT_AVAILABLE || mNativeVrShellDelegate == 0 452 if (!isVrShellEnabled(mVrSupportLevel)
289 || (!isVrShellEnabled() && !(mRequestedWebVR || mListeningForWeb VrActivate))) { 453 && !(mRequestedWebVR || mListeningForWebVrActivate)) {
290 return false; 454 return false;
291 } 455 }
292 // TODO(mthiesse): When we have VR UI for opening new tabs, etc., allow VR Shell to be 456 // TODO(mthiesse): When we have VR UI for opening new tabs, etc., allow VR Shell to be
293 // entered without any current tabs. 457 // entered without any current tabs.
294 if (tab == null) { 458 if (tab == null) {
295 return false; 459 return false;
296 } 460 }
297 // For now we don't handle sad tab page. crbug.com/661609 461 // For now we don't handle sad tab page. crbug.com/661609
298 if (tab.isShowingSadTab()) { 462 if (tab.isShowingSadTab()) {
299 return false; 463 return false;
300 } 464 }
301 // crbug.com/667781 465 // crbug.com/667781
302 if (MultiWindowUtils.getInstance().isInMultiWindowMode(mActivity)) { 466 if (MultiWindowUtils.getInstance().isInMultiWindowMode(mActivity)) {
303 return false; 467 return false;
304 } 468 }
305 return true; 469 return true;
306 } 470 }
307 471
308 @CalledByNative 472 @CalledByNative
309 private void presentRequested() { 473 private void presentRequested() {
310 // TODO(mthiesse): There's a GVR bug where they're not calling us back w ith the intent we 474 // TODO(mthiesse): There's a GVR bug where they're not calling us back w ith the intent we
311 // ask them to when we call DaydreamApi#launchInVr. As a temporary hack, remember locally 475 // ask them to when we call DaydreamApi#launchInVr. As a temporary hack, remember locally
312 // that we want to enter webVR. 476 // that we want to enter webVR.
313 mRequestedWebVR = true; 477 mRequestedWebVR = true;
314 switch (enterVRIfNecessary()) { 478 switch (enterVRInternal()) {
315 case ENTER_VR_NOT_NECESSARY: 479 case ENTER_VR_NOT_NECESSARY:
316 mVrShell.setWebVrModeEnabled(true); 480 mVrShell.setWebVrModeEnabled(true);
317 nativeSetPresentResult(mNativeVrShellDelegate, true); 481 nativeSetPresentResult(mNativeVrShellDelegate, true);
318 mRequestedWebVR = false; 482 mRequestedWebVR = false;
319 break; 483 break;
320 case ENTER_VR_CANCELLED: 484 case ENTER_VR_CANCELLED:
321 nativeSetPresentResult(mNativeVrShellDelegate, false); 485 nativeSetPresentResult(mNativeVrShellDelegate, false);
322 mRequestedWebVR = false; 486 mRequestedWebVR = false;
323 break; 487 break;
324 case ENTER_VR_REQUESTED: 488 case ENTER_VR_REQUESTED:
325 break; 489 break;
326 case ENTER_VR_SUCCEEDED: 490 case ENTER_VR_SUCCEEDED:
327 nativeSetPresentResult(mNativeVrShellDelegate, true); 491 nativeSetPresentResult(mNativeVrShellDelegate, true);
328 mRequestedWebVR = false; 492 mRequestedWebVR = false;
329 break; 493 break;
330 default: 494 default:
331 Log.e(TAG, "Unexpected enum."); 495 Log.e(TAG, "Unexpected enum.");
332 } 496 }
333 } 497 }
334 498
335 /** 499 /**
336 * Enters VR Shell if necessary, displaying browser UI and tab contents in V R. 500 * Enters VR Shell if necessary, displaying browser UI and tab contents in V R.
337 */ 501 */
338 @EnterVRResult 502 @EnterVRResult
339 public int enterVRIfNecessary() { 503 private int enterVRInternal() {
340 // Update VR support level as it can change at runtime 504 // Update VR support level as it can change at runtime
341 updateVrSupportLevel(); 505 updateVrSupportLevel();
342 if (mVrSupportLevel == VR_NOT_AVAILABLE) return ENTER_VR_CANCELLED; 506 if (mVrSupportLevel == VR_NOT_AVAILABLE) return ENTER_VR_CANCELLED;
343 if (mInVr) return ENTER_VR_NOT_NECESSARY; 507 if (mInVr) return ENTER_VR_NOT_NECESSARY;
344 if (!canEnterVR(mActivity.getActivityTab())) return ENTER_VR_CANCELLED; 508 if (!canEnterVR(mActivity.getActivityTab())) return ENTER_VR_CANCELLED;
345 509
346 if (mVrSupportLevel == VR_CARDBOARD || !mVrDaydreamApi.isDaydreamCurrent Viewer()) { 510 if (mVrSupportLevel == VR_CARDBOARD || !mVrDaydreamApi.isDaydreamCurrent Viewer()) {
347 // Avoid using launchInVr which would trigger DON flow regardless cu rrent viewer type 511 // Avoid using launchInVr which would trigger DON flow regardless cu rrent viewer type
348 // due to the lack of support for unexported activities. 512 // due to the lack of support for unexported activities.
349 enterVR(); 513 enterVR();
350 } else { 514 } else {
351 if (!mVrDaydreamApi.launchInVr(getPendingEnterVRIntent())) return EN TER_VR_CANCELLED; 515 if (!mVrDaydreamApi.launchInVr(getEnterVRPendingIntent(mVrDaydreamAp i, mActivity))) {
516 return ENTER_VR_CANCELLED;
517 }
352 } 518 }
353 return ENTER_VR_REQUESTED; 519 return ENTER_VR_REQUESTED;
354 } 520 }
355 521
356 @CalledByNative 522 @CalledByNative
357 private boolean exitWebVR() { 523 private boolean exitWebVR() {
358 if (!mInVr) return false; 524 if (!mInVr) return false;
359 mVrShell.setWebVrModeEnabled(false); 525 mVrShell.setWebVrModeEnabled(false);
360 if (mVrSupportLevel == VR_CARDBOARD) { 526 if (mVrSupportLevel == VR_CARDBOARD) {
361 // Transition screen is not available for Cardboard only (non-Daydre am) devices. 527 // Transition screen is not available for Cardboard only (non-Daydre am) devices.
362 // TODO(bshe): Fix this once b/33490788 is fixed. 528 // TODO(bshe): Fix this once b/33490788 is fixed.
363 shutdownVR(false /* isPausing */, false /* showTransition */); 529 shutdownVR(false /* isPausing */, false /* showTransition */);
364 } else { 530 } else {
365 // TODO(bajones): Once VR Shell can be invoked outside of WebVR this 531 // TODO(bajones): Once VR Shell can be invoked outside of WebVR this
366 // should no longer exit the shell outright. Need a way to determine 532 // should no longer exit the shell outright. Need a way to determine
367 // how VrShell was created. 533 // how VrShell was created.
368 shutdownVR(false /* isPausing */, !isVrShellEnabled() /* showTransit ion */); 534 shutdownVR(
535 false /* isPausing */, !isVrShellEnabled(mVrSupportLevel) /* showTransition */);
369 } 536 }
370 return true; 537 return true;
371 } 538 }
372 539
373 /** 540 private void resumeVR() {
374 * Resumes VR Shell.
375 */
376 public void maybeResumeVR() {
377 mPaused = false; 541 mPaused = false;
378 if (mVrSupportLevel == VR_NOT_AVAILABLE) return; 542 if (mVrSupportLevel == VR_NOT_AVAILABLE) return;
379 if (mVrSupportLevel == VR_DAYDREAM 543 if (mVrSupportLevel == VR_DAYDREAM
380 && (isVrShellEnabled() || mListeningForWebVrActivateBeforePause) ) { 544 && (isVrShellEnabled(mVrSupportLevel) || mListeningForWebVrActiv ateBeforePause)) {
381 registerDaydreamIntent(); 545 registerDaydreamIntent(mVrDaydreamApi, mActivity);
382 } 546 }
383 547
384 if (mEnteringVr) { 548 if (mEnteringVr) {
385 enterVR(); 549 enterVR();
386 } else if (mRequestedWebVR) { 550 } else if (mRequestedWebVR) {
387 // If this is still set, it means the user backed out of the DON flo w, and we won't be 551 // If this is still set, it means the user backed out of the DON flo w, and we won't be
388 // receiving an intent from daydream. 552 // receiving an intent from daydream.
389 nativeSetPresentResult(mNativeVrShellDelegate, false); 553 nativeSetPresentResult(mNativeVrShellDelegate, false);
390 mRequestedWebVR = false; 554 mRequestedWebVR = false;
391 } 555 }
(...skipping 10 matching lines...) Expand all
402 oldPolicy = StrictMode.allowThreadDiskWrites(); 566 oldPolicy = StrictMode.allowThreadDiskWrites();
403 try { 567 try {
404 mVrShell.resume(); 568 mVrShell.resume();
405 } catch (IllegalArgumentException e) { 569 } catch (IllegalArgumentException e) {
406 Log.e(TAG, "Unable to resume VrShell", e); 570 Log.e(TAG, "Unable to resume VrShell", e);
407 } finally { 571 } finally {
408 StrictMode.setThreadPolicy(oldPolicy); 572 StrictMode.setThreadPolicy(oldPolicy);
409 } 573 }
410 } else if (mVrSupportLevel == VR_DAYDREAM && mVrDaydreamApi.isDaydreamCu rrentViewer() 574 } else if (mVrSupportLevel == VR_DAYDREAM && mVrDaydreamApi.isDaydreamCu rrentViewer()
411 && mLastVRExit + REENTER_VR_TIMEOUT_MS > SystemClock.uptimeMilli s()) { 575 && mLastVRExit + REENTER_VR_TIMEOUT_MS > SystemClock.uptimeMilli s()) {
412 enterVRIfNecessary(); 576 enterVRInternal();
413 } 577 }
414 } 578 }
415 579
416 /** 580 private void pauseVR() {
417 * Pauses VR Shell.
418 */
419 public void maybePauseVR() {
420 mPaused = true; 581 mPaused = true;
421 if (mVrSupportLevel == VR_NOT_AVAILABLE) return; 582 if (mVrSupportLevel == VR_NOT_AVAILABLE) return;
422 583
423 if (mVrSupportLevel == VR_DAYDREAM) { 584 if (mVrSupportLevel == VR_DAYDREAM) {
424 unregisterDaydreamIntent(); 585 unregisterDaydreamIntent(mVrDaydreamApi);
425 586
426 // When the active web page has a vrdisplayactivate event handler, 587 // When the active web page has a vrdisplayactivate event handler,
427 // mListeningForWebVrActivate should be set to true, which means a v rdisplayactive event 588 // mListeningForWebVrActivate should be set to true, which means a v rdisplayactive event
428 // should be fired once DON flow finished. However, DON flow will pa use our activity, 589 // should be fired once DON flow finished. However, DON flow will pa use our activity,
429 // which makes the active page becomes invisible. And the event fire s before the active 590 // which makes the active page becomes invisible. And the event fire s before the active
430 // page becomes visible again after DON finished. So here we remembe r the value of 591 // page becomes visible again after DON finished. So here we remembe r the value of
431 // mListeningForWebVrActivity before pause and use this value to dec ide if 592 // mListeningForWebVrActivity before pause and use this value to dec ide if
432 // vrdisplayactivate event should be dispatched in enterVRFromIntent . 593 // vrdisplayactivate event should be dispatched in enterVRFromIntent .
433 mListeningForWebVrActivateBeforePause = mListeningForWebVrActivate; 594 mListeningForWebVrActivateBeforePause = mListeningForWebVrActivate;
434 } 595 }
435 nativeOnPause(mNativeVrShellDelegate); 596 nativeOnPause(mNativeVrShellDelegate);
436 597
437 // TODO(mthiesse): When VR Shell lives in its own activity, and integrat es with Daydream 598 // TODO(mthiesse): When VR Shell lives in its own activity, and integrat es with Daydream
438 // home, pause instead of exiting VR here. For now, because VR Apps shou ldn't show up in the 599 // home, pause instead of exiting VR here. For now, because VR Apps shou ldn't show up in the
439 // non-VR recents, and we don't want ChromeTabbedActivity disappearing, exit VR. 600 // non-VR recents, and we don't want ChromeTabbedActivity disappearing, exit VR.
440 shutdownVR(true /* isPausing */, false /* showTransition */); 601 shutdownVR(true /* isPausing */, false /* showTransition */);
441 } 602 }
442 603
443 /** 604 private boolean onBackPressedInternal() {
444 * See {@link ChromeActivity#handleBackPressed}
445 */
446 public boolean onBackPressed() {
447 if (mVrSupportLevel == VR_NOT_AVAILABLE) return false; 605 if (mVrSupportLevel == VR_NOT_AVAILABLE) return false;
448 if (!mInVr) return false; 606 if (!mInVr) return false;
449 shutdownVR(false /* isPausing */, false /* showTransition */); 607 shutdownVR(false /* isPausing */, false /* showTransition */);
450 return true; 608 return true;
451 } 609 }
452 610
453 public void onExitVRResult(int resultCode) { 611 private void onExitVRResult(boolean success) {
454 assert mVrSupportLevel != VR_NOT_AVAILABLE; 612 assert mVrSupportLevel != VR_NOT_AVAILABLE;
455 if (resultCode == Activity.RESULT_OK) { 613 // For now, we don't handle re-entering VR when exit fails, so keep tryi ng to exit.
456 mVrClassesWrapper.setVrModeEnabled(false); 614 if (!success && sInstance.mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new Intent())) return;
457 } else { 615 sInstance.mVrClassesWrapper.setVrModeEnabled(sInstance.mActivity, false) ;
458 // For now, we don't handle re-entering VR when exit fails, so keep trying to exit.
459 if (!mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new Intent())) {
460 mVrClassesWrapper.setVrModeEnabled(false);
461 }
462 }
463 }
464
465 private PendingIntent getPendingEnterVRIntent() {
466 return PendingIntent.getActivity(mActivity, 0, mEnterVRIntent, PendingIn tent.FLAG_ONE_SHOT);
467 }
468
469 /**
470 * Registers the Intent to fire after phone inserted into a headset.
471 */
472 private void registerDaydreamIntent() {
473 mVrDaydreamApi.registerDaydreamIntent(getPendingEnterVRIntent());
474 }
475
476 /**
477 * Unregisters the Intent which registered by this context if any.
478 */
479 private void unregisterDaydreamIntent() {
480 mVrDaydreamApi.unregisterDaydreamIntent();
481 } 616 }
482 617
483 @CalledByNative 618 @CalledByNative
484 private long createNonPresentingNativeContext() { 619 private long createNonPresentingNativeContext() {
485 if (mVrClassesWrapper == null) return 0; 620 if (mVrClassesWrapper == null) return 0;
486 mNonPresentingGvrContext = mVrClassesWrapper.createNonPresentingGvrConte xt(); 621 mNonPresentingGvrContext = mVrClassesWrapper.createNonPresentingGvrConte xt(mActivity);
487 if (mNonPresentingGvrContext == null) return 0; 622 if (mNonPresentingGvrContext == null) return 0;
488 return mNonPresentingGvrContext.getNativeGvrContext(); 623 return mNonPresentingGvrContext.getNativeGvrContext();
489 } 624 }
490 625
491 @CalledByNative 626 @CalledByNative
492 private void shutdownNonPresentingNativeContext() { 627 private void shutdownNonPresentingNativeContext() {
493 mNonPresentingGvrContext.shutdown(); 628 mNonPresentingGvrContext.shutdown();
494 mNonPresentingGvrContext = null; 629 mNonPresentingGvrContext = null;
495 } 630 }
496 631
497 @CalledByNative 632 @CalledByNative
498 private void setListeningForWebVrActivate(boolean listening) { 633 private void setListeningForWebVrActivate(boolean listening) {
499 // Non-Daydream devices may not have the concept of display activate. So disable 634 // Non-Daydream devices may not have the concept of display activate. So disable
500 // mListeningForWebVrActivate for them. 635 // mListeningForWebVrActivate for them.
501 if (mVrSupportLevel != VR_DAYDREAM) return; 636 if (mVrSupportLevel != VR_DAYDREAM) return;
502 mListeningForWebVrActivate = listening; 637 mListeningForWebVrActivate = listening;
503 if (listening) { 638 if (listening) {
504 registerDaydreamIntent(); 639 registerDaydreamIntent(mVrDaydreamApi, mActivity);
505 } else { 640 } else {
506 unregisterDaydreamIntent(); 641 unregisterDaydreamIntent(mVrDaydreamApi);
507 } 642 }
508 } 643 }
509 644
510 /** 645 /**
511 * Exits VR Shell, performing all necessary cleanup. 646 * Exits VR Shell, performing all necessary cleanup.
512 */ 647 */
513 /* package */ void shutdownVR(boolean isPausing, boolean showTransition) { 648 /* package */ void shutdownVR(boolean isPausing, boolean showTransition) {
514 if (!mInVr) return; 649 if (!mInVr) return;
515 mInVr = false; 650 mInVr = false;
516 mRequestedWebVR = false; 651 mRequestedWebVR = false;
517 boolean transition = mVrSupportLevel == VR_DAYDREAM && showTransition; 652 boolean transition = mVrSupportLevel == VR_DAYDREAM && showTransition;
518 if (!isPausing) { 653 if (!isPausing) {
519 if (!transition || !mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new In tent())) { 654 if (!transition || !mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new In tent())) {
520 mVrClassesWrapper.setVrModeEnabled(false); 655 mVrClassesWrapper.setVrModeEnabled(mActivity, false);
521 } 656 }
522 } else { 657 } else {
523 mVrClassesWrapper.setVrModeEnabled(false); 658 mVrClassesWrapper.setVrModeEnabled(mActivity, false);
524 mLastVRExit = SystemClock.uptimeMillis(); 659 mLastVRExit = SystemClock.uptimeMillis();
525 } 660 }
526 if (mRestoreOrientation != null) mActivity.setRequestedOrientation(mRest oreOrientation); 661 if (mRestoreOrientation != null) mActivity.setRequestedOrientation(mRest oreOrientation);
527 mRestoreOrientation = null; 662 mRestoreOrientation = null;
528 mVrShell.pause(); 663 mVrShell.pause();
529 removeVrViews(); 664 removeVrViews();
530 clearVrModeWindowFlags(); 665 clearVrModeWindowFlags();
531 destroyVrShell(); 666 destroyVrShell();
532 mActivity.getFullscreenManager().setPositionsForTabToNonFullscreen(); 667 mActivity.getFullscreenManager().setPositionsForTabToNonFullscreen();
533 } 668 }
534 669
535 private boolean isVrCoreCompatible() { 670 private static boolean isVrCoreCompatible(
536 assert mVrClassesWrapper != null; 671 VrCoreVersionChecker versionChecker, Tab tabToShowInfobarIn) {
537 if (mVrCoreVersionChecker == null) {
538 mVrCoreVersionChecker = mVrClassesWrapper.createVrCoreVersionChecker ();
539 }
540
541 return verifyOrUpdateVrServices( 672 return verifyOrUpdateVrServices(
542 mVrCoreVersionChecker.getVrCoreCompatibility(), mActivity.getAct ivityTab()); 673 versionChecker.getVrCoreCompatibility(), tabToShowInfobarIn);
543 } 674 }
544 675
545 private boolean verifyOrUpdateVrServices(int vrCoreCompatibility, Tab tab) { 676 private static boolean verifyOrUpdateVrServices(int vrCoreCompatibility, Tab tab) {
546 if (vrCoreCompatibility == VrCoreVersionChecker.VR_READY) { 677 if (vrCoreCompatibility == VrCoreVersionChecker.VR_READY) {
547 return true; 678 return true;
548 } 679 }
549 if (tab == null) { 680 if (tab == null) {
550 return false; 681 return false;
551 } 682 }
552 // Make sure OS is supported before showing the user a prompt. 683 // Make sure OS is supported before showing the user a prompt.
553 if (Build.VERSION.SDK_INT < ChromeFeatureList.getFieldTrialParamByFeatur eAsInt( 684 if (Build.VERSION.SDK_INT < ChromeFeatureList.getFieldTrialParamByFeatur eAsInt(
554 ChromeFeatureList.WEBVR_CARDBOARD_SU PPORT, 685 ChromeFeatureList.WEBVR_CARDBOARD_SU PPORT,
555 MIN_SDK_VERSION_PARAM_NAME, 686 MIN_SDK_VERSION_PARAM_NAME,
556 Build.VERSION_CODES.KITKAT)) { 687 Build.VERSION_CODES.KITKAT)) {
557 return false; 688 return false;
558 } 689 }
559 690 final Activity activity = tab.getActivity();
560 String infobarText; 691 String infobarText;
561 String buttonText; 692 String buttonText;
562 if (vrCoreCompatibility == VrCoreVersionChecker.VR_NOT_AVAILABLE) { 693 if (vrCoreCompatibility == VrCoreVersionChecker.VR_NOT_AVAILABLE) {
563 // Supported, but not installed. Ask user to install instead of upgr ade. 694 // Supported, but not installed. Ask user to install instead of upgr ade.
564 infobarText = mActivity.getString(R.string.vr_services_check_infobar _install_text); 695 infobarText = activity.getString(R.string.vr_services_check_infobar_ install_text);
565 buttonText = mActivity.getString(R.string.vr_services_check_infobar_ install_button); 696 buttonText = activity.getString(R.string.vr_services_check_infobar_i nstall_button);
566 } else if (vrCoreCompatibility == VrCoreVersionChecker.VR_OUT_OF_DATE) { 697 } else if (vrCoreCompatibility == VrCoreVersionChecker.VR_OUT_OF_DATE) {
567 infobarText = mActivity.getString(R.string.vr_services_check_infobar _update_text); 698 infobarText = activity.getString(R.string.vr_services_check_infobar_ update_text);
568 buttonText = mActivity.getString(R.string.vr_services_check_infobar_ update_button); 699 buttonText = activity.getString(R.string.vr_services_check_infobar_u pdate_button);
569 } else { 700 } else {
570 Log.e(TAG, "Unknown VrCore compatibility: " + vrCoreCompatibility); 701 Log.e(TAG, "Unknown VrCore compatibility: " + vrCoreCompatibility);
571 return false; 702 return false;
572 } 703 }
573 704
574 SimpleConfirmInfoBarBuilder.create(tab, 705 SimpleConfirmInfoBarBuilder.create(tab,
575 new SimpleConfirmInfoBarBuilder.Listener() { 706 new SimpleConfirmInfoBarBuilder.Listener() {
576 @Override 707 @Override
577 public void onInfoBarDismissed() {} 708 public void onInfoBarDismissed() {}
578 709
579 @Override 710 @Override
580 public boolean onInfoBarButtonClicked(boolean isPrimary) { 711 public boolean onInfoBarButtonClicked(boolean isPrimary) {
581 mActivity.startActivity(new Intent(Intent.ACTION_VIEW, 712 activity.startActivity(new Intent(Intent.ACTION_VIEW,
582 Uri.parse("market://details?id=" + VR_CORE_PACKA GE_ID))); 713 Uri.parse("market://details?id=" + VR_CORE_PACKA GE_ID)));
583 return false; 714 return false;
584 } 715 }
585 }, 716 },
586 InfoBarIdentifier.VR_SERVICES_UPGRADE_ANDROID, R.drawable.vr_ser vices, infobarText, 717 InfoBarIdentifier.VR_SERVICES_UPGRADE_ANDROID, R.drawable.vr_ser vices, infobarText,
587 buttonText, null, true); 718 buttonText, null, true);
588 return false; 719 return false;
589 } 720 }
590 721
591 private boolean createVrShell() { 722 private boolean createVrShell() {
592 if (mVrClassesWrapper == null) return false; 723 if (mVrClassesWrapper == null) return false;
593 mVrShell = mVrClassesWrapper.createVrShell(this, mActivity.getCompositor ViewHolder()); 724 mTabModelSelector = mActivity.getCompositorViewHolder().detachForVR();
725 if (mTabModelSelector == null) return false;
726 mVrShell = mVrClassesWrapper.createVrShell(mActivity, this, mTabModelSel ector);
594 return mVrShell != null; 727 return mVrShell != null;
595 } 728 }
596 729
597 private void addVrViews() { 730 private void addVrViews() {
598 FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView(); 731 FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView();
599 LayoutParams params = new FrameLayout.LayoutParams( 732 LayoutParams params = new FrameLayout.LayoutParams(
600 ViewGroup.LayoutParams.MATCH_PARENT, 733 ViewGroup.LayoutParams.MATCH_PARENT,
601 ViewGroup.LayoutParams.MATCH_PARENT); 734 ViewGroup.LayoutParams.MATCH_PARENT);
602 decor.addView(mVrShell.getContainer(), params); 735 decor.addView(mVrShell.getContainer(), params);
603 mActivity.setUIVisibilityForVR(View.GONE); 736 mActivity.onEnterVR();
604 } 737 }
605 738
606 private void removeVrViews() { 739 private void removeVrViews() {
607 mActivity.setUIVisibilityForVR(View.VISIBLE); 740 mActivity.onExitVR();
608 FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView(); 741 FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView();
609 decor.removeView(mVrShell.getContainer()); 742 decor.removeView(mVrShell.getContainer());
610 } 743 }
611 744
612 private void setupVrModeWindowFlags() { 745 private void setupVrModeWindowFlags() {
613 if (mRestoreSystemUiVisibilityFlag == -1) { 746 if (mRestoreSystemUiVisibilityFlag == -1) {
614 mRestoreSystemUiVisibilityFlag = mActivity.getWindow().getDecorView( ) 747 mRestoreSystemUiVisibilityFlag = mActivity.getWindow().getDecorView( )
615 .getSystemUiVisibility(); 748 .getSystemUiVisibility();
616 } 749 }
617 mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCRE EN_ON); 750 mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCRE EN_ON);
618 mActivity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_U I_FLAG_LAYOUT_STABLE 751 mActivity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_U I_FLAG_LAYOUT_STABLE
619 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 752 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
620 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HI DE_NAVIGATION 753 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HI DE_NAVIGATION
621 | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE _STICKY); 754 | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE _STICKY);
622 } 755 }
623 756
624 private void clearVrModeWindowFlags() { 757 private void clearVrModeWindowFlags() {
625 mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SC REEN_ON); 758 mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SC REEN_ON);
626 if (mRestoreSystemUiVisibilityFlag != -1) { 759 if (mRestoreSystemUiVisibilityFlag != -1) {
627 mActivity.getWindow().getDecorView() 760 mActivity.getWindow().getDecorView()
628 .setSystemUiVisibility(mRestoreSystemUiVisibilityFlag); 761 .setSystemUiVisibility(mRestoreSystemUiVisibilityFlag);
629 } 762 }
630 mRestoreSystemUiVisibilityFlag = -1; 763 mRestoreSystemUiVisibilityFlag = -1;
631 } 764 }
632 765
633 /** 766 /**
634 * Clean up VrShell, and associated native objects. 767 * Clean up VrShell, and associated native objects.
635 */ 768 */
636 public void destroyVrShell() { 769 private void destroyVrShell() {
637 if (mVrShell != null) { 770 if (mVrShell != null) {
638 mVrShell.teardown(); 771 mVrShell.teardown();
639 mVrShell = null; 772 mVrShell = null;
773 mActivity.getCompositorViewHolder().onExitVR(mTabModelSelector);
640 } 774 }
641 } 775 }
642 776
643 /** 777 /**
644 * Whether or not the intent is a Daydream VR Intent.
645 */
646 public boolean isDaydreamVrIntent(Intent intent) {
647 if (intent == null || intent.getCategories() == null) return false;
648 return intent.getCategories().contains(DAYDREAM_CATEGORY);
649 }
650
651 /**
652 * Whether or not we are currently in VR.
653 */
654 public boolean isInVR() {
655 return mInVr;
656 }
657
658 /**
659 * @return Whether or not VR Shell is currently enabled.
660 */
661 private boolean isVrShellEnabled() {
662 // Only enable ChromeVR (VrShell) on Daydream devices as it currently ne eds a Daydream
663 // controller.
664 if (mVrSupportLevel != VR_DAYDREAM) return false;
665 return ChromeFeatureList.isEnabled(ChromeFeatureList.VR_SHELL);
666 }
667
668 /**
669 * @param api The VrDaydreamApi object this delegate will use instead of the default one 778 * @param api The VrDaydreamApi object this delegate will use instead of the default one
670 */ 779 */
671 @VisibleForTesting 780 @VisibleForTesting
672 public void overrideDaydreamApiForTesting(VrDaydreamApi api) { 781 public void overrideDaydreamApiForTesting(VrDaydreamApi api) {
673 mVrDaydreamApi = api; 782 mVrDaydreamApi = api;
674 } 783 }
675 784
676 /** 785 /**
677 * @return Pointer to the native VrShellDelegate object. 786 * @return Pointer to the native VrShellDelegate object.
678 */ 787 */
679 @CalledByNative 788 @CalledByNative
680 private long getNativePointer() { 789 private long getNativePointer() {
681 return mNativeVrShellDelegate; 790 return mNativeVrShellDelegate;
682 } 791 }
683 792
684 @CalledByNative 793 @CalledByNative
685 private void showTab(int id) { 794 private void showTab(int id) {
686 Tab tab = mActivity.getTabModelSelector().getTabById(id); 795 Tab tab = mActivity.getTabModelSelector().getTabById(id);
687 if (tab == null) { 796 if (tab == null) {
688 return; 797 return;
689 } 798 }
690 int index = mActivity.getTabModelSelector().getModel(tab.isIncognito()). indexOf(tab); 799 int index = mActivity.getTabModelSelector().getModel(tab.isIncognito()). indexOf(tab);
691 if (index == TabModel.INVALID_TAB_INDEX) { 800 if (index == TabModel.INVALID_TAB_INDEX) {
692 return; 801 return;
693 } 802 }
694 TabModelUtils.setIndex(mActivity.getTabModelSelector().getModel(tab.isIn cognito()), index); 803 TabModelUtils.setIndex(mActivity.getTabModelSelector().getModel(tab.isIn cognito()), index);
695 } 804 }
696 805
806 private void destroy() {
807 if (sInstance == null) return;
808 if (mNativeVrShellDelegate != 0) nativeDestroy(mNativeVrShellDelegate);
809 sInstance = null;
810 }
811
697 private native long nativeInit(); 812 private native long nativeInit();
813 private static native void nativeOnLibraryAvailable();
698 private native void nativeSetPresentResult(long nativeVrShellDelegate, boole an result); 814 private native void nativeSetPresentResult(long nativeVrShellDelegate, boole an result);
699 private native void nativeDisplayActivate(long nativeVrShellDelegate); 815 private native void nativeDisplayActivate(long nativeVrShellDelegate);
700 private native void nativeUpdateVSyncInterval(long nativeVrShellDelegate, lo ng timebaseNanos, 816 private native void nativeUpdateVSyncInterval(long nativeVrShellDelegate, lo ng timebaseNanos,
701 double intervalSeconds); 817 double intervalSeconds);
702 private native void nativeOnPause(long nativeVrShellDelegate); 818 private native void nativeOnPause(long nativeVrShellDelegate);
703 private native void nativeOnResume(long nativeVrShellDelegate); 819 private native void nativeOnResume(long nativeVrShellDelegate);
820 private native void nativeDestroy(long nativeVrShellDelegate);
704 } 821 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698