Search Unity

Launching other Daydream apps from Unity - in VR mode

Discussion in 'Daydream' started by vroggojeff, Jun 21, 2019.

  1. vroggojeff

    vroggojeff

    Joined:
    Jun 21, 2019
    Posts:
    3
    I've been digging on this one for a solid day now, I have found plenty of info on how to launch apps from Unity, and that is working successfully. However, for applications that support a VR specific view and a non VR view, there is an issue. Applications that are an APK specific to VR are fine. However, Google expeditions for example is one APK for both Daydream and phone. There is a single player view meant for Daydream headsets, versus a default startup activity meant for phones. When this app is launched from the Daydream launcher, it opens with the following intent details:

    START u0 {cat=[com.google.intent.category.DAYDREAM] flg=0x14010000 cmp=com.google.vr.expeditions/.explorer.singleplayer.SinglePlayerActivity (has extras)}

    If I launch an intent for the com.google.vr.expeditions package either through startActivity or using the core DaydreamApi launchInVr method, it launches with these intent details:

    START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER,google.intent.category.DAYDREAM] flg=0x14010000 pkg=com.google.vr.expeditions cmp=com.google.vr.expeditions/.home.startup.ExpeditionsStartupActivity}


    Now, I have gone so far as to use the AndroidJNI tools to modify the intent as close as possible, and have successfully removed the extra category for launcher, revised the proper flag (any idea what that hex actually is for?) and have created a custom component name for the single player activity. The only thing I cant get my hands on is what the extras are that are called out via (has extras). I am assuming there may be a simple putExtra directive that can be added to the original intent to specify what mode to launch in, that is probably being set from the Daydream launcher. But for the life of me I can't find any documentation to identify what it is. Anyone have any ideas what may be needed here? It must be standardized, as every app that launches from the Daydream app launcher is being kicked off with extras, but i have no idea how to see what that value is. Thoughts?

    Here is the current block:

    Code (CSharp):
    1.  
    2.         AndroidJavaClass up = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    3.         AndroidJavaObject ca = up.GetStatic<AndroidJavaObject>("currentActivity");
    4.         AndroidJavaObject packageManager = ca.Call<AndroidJavaObject>("getPackageManager");
    5.  
    6.         AndroidJavaObject launchIntent = null;
    7.         launchIntent = packageManager.Call<AndroidJavaObject>("getLaunchIntentForPackage", bundleId);
    8.  
    9.         AndroidJavaClass daydreamApiClass = new AndroidJavaClass("com.google.vr.ndk.base.DaydreamApi");
    10.         AndroidJavaObject daydreamApiObj;
    11.         ca.Call("runOnUiThread", new AndroidJavaRunnable(() =>
    12.         {
    13.             daydreamApiObj = daydreamApiClass.CallStatic<AndroidJavaObject>("create", ca);
    14.             launchIntent.Call<AndroidJavaObject>("addCategory", "google.intent.category.DAYDREAM");
    15.             launchIntent.Call<AndroidJavaObject>("setFlags", 0x14010000);
    16.             daydreamApiObj.Call("launchInVr", launchIntent);
    17.             up.Dispose();
    18.             ca.Dispose();
    19.             packageManager.Dispose();
    20.             launchIntent.Dispose();
    21.         }
    22.         ));
    23.  
    24.  
    Here are some other snippets i've been using to modify the intent via JNI that do in fact work correctly, in case anyone is curious:

    Code (CSharp):
    1.  
    2. System.IntPtr removeCategoryMethodID = AndroidJNIHelper.GetMethodID(launchIntent.GetRawClass(), "removeCategory");
    3.         System.IntPtr setComponentMethodID = AndroidJNIHelper.GetMethodID(launchIntent.GetRawClass(), "setComponent");
    4.         AndroidJavaObject cmpCreator = new AndroidJavaObject("android.content.ComponentName", new[] { bundleId, cmp });
    5.  
    6.         AndroidJNI.CallVoidMethod(launchIntent.GetRawObject(), removeCategoryMethodID, AndroidJNIHelper.CreateJNIArgArray(new[] { "android.intent.category.LAUNCHER" }));
    7.         AndroidJNI.CallObjectMethod(launchIntent.GetRawObject(), setComponentMethodID, AndroidJNIHelper.CreateJNIArgArray(new[] {cmpCreator}));
     
  2. thep3000

    thep3000

    Unity Technologies

    Joined:
    Aug 9, 2013
    Posts:
    271
  3. vroggojeff

    vroggojeff

    Joined:
    Jun 21, 2019
    Posts:
    3
    Thank you! That definitely looks like what I need, but it isn't working quite as expected - i added the following:

    Code (CSharp):
    1.  
    2. launchIntent.Call<AndroidJavaObject>("putExtra", new object[] { "android.intent.extra.VR_LAUNCH", true });
    3.  
    The string value is what i found for the constant, so i am assuming that is the correct value, and I'm passing true for the second param - this doesnt work, am I adding this extra correctly to the intent?
     
  4. vroggojeff

    vroggojeff

    Joined:
    Jun 21, 2019
    Posts:
    3
    Follow up on this - it looks like it IS respecting the flag correctly. The problem is that it is defaulting to Cardboard mode and not daydream when setting that flag. I found in the manifest for the app the following line that does specify that proper activity:

    Code (CSharp):
    1.  
    2.         <activity android:configChanges="keyboardHidden|navigation|orientation|screenSize|uiMode" android:enableVrMode="@string/gvr_vr_mode_component" android:exported="true" android:label="@string/expeditions_app_name" android:launchMode="singleTop" android:name="com.google.vr.expeditions.explorer.singleplayer.SinglePlayerActivity" android:resizeableActivity="false" android:screenOrientation="landscape" android:theme="@style/ExpeditionsTheme.SinglePlayerActivity">
    3.  
    Any idea what might be a trigger to kick that directive off?