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