1 // Copyright 2018 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.chrome.browser.vr; 6 7 import android.app.Activity; 8 import android.app.ActivityOptions; 9 import android.content.Context; 10 import android.content.Intent; 11 import android.os.Build; 12 import android.os.Bundle; 13 import android.view.Display; 14 15 import org.chromium.chrome.R; 16 17 /** Intent-specific delegate to call into VR. */ 18 public abstract class VrIntentDelegate { 19 public static final String DAYDREAM_CATEGORY = "com.google.intent.category.DAYDREAM"; 20 21 /** 22 * @return Whether or not the given intent is a VR-specific intent. 23 */ isVrIntent(Intent intent)24 public boolean isVrIntent(Intent intent) { 25 // For simplicity, we only return true here if VR is enabled on the platform and this intent 26 // is not fired from a recent apps page. The latter is there so that we don't enter VR mode 27 // when we're being resumed from the recent apps in 2D mode. 28 // Note that Daydream removes the Daydream category for deep-links (for no real reason). In 29 // addition to the category, DAYDREAM_VR_EXTRA tells us that this intent is coming directly 30 // from VR. 31 return intent != null && intent.hasCategory(DAYDREAM_CATEGORY) 32 && !((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0); 33 } 34 35 /** 36 * @param activity The Activity to check. 37 * @param intent The intent the Activity was launched with. 38 * @return Whether this Activity is launching into VR. 39 */ isLaunchingIntoVr(Activity activity, Intent intent)40 public boolean isLaunchingIntoVr(Activity activity, Intent intent) { 41 return VrModuleProvider.getDelegate().isDaydreamReadyDevice() && isVrIntent(intent) 42 && VrModuleProvider.getDelegate().activitySupportsVrBrowsing(activity); 43 } 44 45 /** 46 * @return Options that a VR-specific Chrome activity should be launched with. 47 */ getVrIntentOptions(Context context)48 public Bundle getVrIntentOptions(Context context) { 49 // These options are used to start the Activity with a custom animation to keep it hidden 50 // for a few hundred milliseconds - enough time for us to draw the first black view. 51 // The animation is sufficient to hide the 2D screenshot but not to the 2D UI while the 52 // WebVR page is being loaded because the animation is somehow cancelled when we try to 53 // enter VR (I don't know what's canceling it). To hide the 2D UI, we resort to the black 54 // overlay view added in {@link startWithVrIntentPreNative}. 55 int animation = VrDelegate.USE_HIDE_ANIMATION ? R.anim.stay_hidden : 0; 56 ActivityOptions options = ActivityOptions.makeCustomAnimation(context, animation, 0); 57 if (VrModuleProvider.getDelegate().bootsToVr()) { 58 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { 59 assert false; 60 } else { 61 options.setLaunchDisplayId(Display.DEFAULT_DISPLAY); 62 } 63 } 64 return options.toBundle(); 65 } 66 67 /** 68 * This function returns an intent that will launch a VR activity that will prompt the 69 * user to take off their headset and forward the freIntent to the standard 70 * 2D FRE activity. 71 * 72 * @param freIntent The intent that will be used to start the first run in 2D mode. 73 * @return The intermediate VR activity intent. 74 */ setupVrFreIntent(Context context, Intent freIntent)75 public abstract Intent setupVrFreIntent(Context context, Intent freIntent); 76 77 /** 78 * Removes VR specific extras from the given intent to make it a non-VR intent. 79 */ removeVrExtras(Intent intent)80 public abstract void removeVrExtras(Intent intent); 81 82 /** 83 * Adds the necessary VR flags to an intent. 84 * @param intent The intent to add VR flags to. 85 * @return the intent with VR flags set. 86 */ setupVrIntent(Intent intent)87 public abstract Intent setupVrIntent(Intent intent); 88 } 89