/// <summary> /// Tries to install and run the Instant Preview android app. /// </summary> /// <param name="adbPath">Path to adb to use for installing.</param> /// <param name="localVersion">Local version of Instant Preview plugin to compare installed APK against.</param> /// <returns>Enumerator for coroutine that handles installation if necessary.</returns> private static IEnumerator InstallApkAndRunIfConnected(string adbPath, string localVersion) { string apkPath = null; #if UNITY_EDITOR apkPath = UnityEditor.AssetDatabase.GUIDToAssetPath(k_ApkGuid); #endif // !UNITY_EDITOR // Early outs if set to install but the apk can't be found. if (!File.Exists(apkPath)) { Debug.LogError( string.Format("Trying to install Instant Preview apk but reference to InstantPreview.apk is " + "broken. Couldn't find an asset with .meta file guid={0}", k_ApkGuid)); yield break; } Result result = new Result(); Thread checkAdbThread = new Thread((object obj) => { Result res = (Result)obj; string output; string errors; // Gets version of installed apk. RunAdbCommand(adbPath, "shell dumpsys package com.google.ar.core.instantpreview | grep versionName", out output, out errors); string installedVersion = null; if (!string.IsNullOrEmpty(output) && string.IsNullOrEmpty(errors)) { installedVersion = output.Substring(output.IndexOf('=') + 1); } // Early outs if no device is connected. if (string.Compare(errors, k_NoDevicesFoundAdbResult) == 0) { return; } // Prints errors and exits on failure. if (!string.IsNullOrEmpty(errors)) { Debug.LogError(errors); return; } if (installedVersion == null) { Debug.Log(string.Format( "Instant Preview: app not found on device, attempting to install it from {0}.", apkPath)); } else if (installedVersion != localVersion) { Debug.Log(string.Format( "Instant Preview: installed version \"{0}\" does not match local version \"{1}\", attempting upgrade.", installedVersion, localVersion)); } res.ShouldPromptForInstall = installedVersion != localVersion; }); checkAdbThread.Start(result); while (!checkAdbThread.Join(0)) { yield return(0); } if (result.ShouldPromptForInstall) { if (PromptToInstall()) { Thread installThread = new Thread(() => { string output; string errors; RunAdbCommand(adbPath, string.Format("uninstall com.google.ar.core.instantpreview", apkPath), out output, out errors); RunAdbCommand(adbPath, string.Format("install \"{0}\"", apkPath), out output, out errors); // Prints any output from trying to install. if (!string.IsNullOrEmpty(output)) { Debug.Log(output); } if (!string.IsNullOrEmpty(errors)) { if (string.Equals(errors, "Success")) { Debug.Log("Successfully installed Instant Preview app."); } else { Debug.LogError(errors); } } }); installThread.Start(); while (!installThread.Join(0)) { yield return(0); } } else { yield break; } } if (!NativeApi.IsConnected()) { new Thread(() => { string output; string errors; RunAdbCommand(adbPath, "shell am start -n com.google.ar.core.instantpreview/.InstantPreviewActivity", out output, out errors); }).Start(); } }
public SessionApi(NativeApi nativeApi) { m_NativeApi = nativeApi; }
private static IEnumerator UpdateLoop() { // Creates a target texture to capture the preview window onto. // Some video encoders prefer the dimensions to be a multiple of 16. var targetWidth = RoundUpToNearestMultipleOf16(Screen.width); var targetHeight = RoundUpToNearestMultipleOf16(Screen.height); var screenTexture = new RenderTexture(targetWidth, targetHeight, 0); var renderEventFunc = NativeApi.GetRenderEventFunc(); var shouldConvertToBrgra = SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D11; var targetTexture = screenTexture; RenderTexture bgrTexture = null; if (shouldConvertToBrgra) { bgrTexture = new RenderTexture(screenTexture.width, screenTexture.height, 0, RenderTextureFormat.BGRA32); targetTexture = bgrTexture; } var loggedAspectRatioWarning = false; // Begins update loop. The coroutine will cease when the // ARCoreSession component it's called from is destroyed. for (;;) { yield return(k_WaitForEndOfFrame); NativeApi.Update(); InstantPreviewInput.Update(); AddInstantPreviewTrackedPoseDriverWhenNeeded(); Graphics.Blit(null, screenTexture); if (shouldConvertToBrgra) { Graphics.Blit(screenTexture, bgrTexture); } var cameraTexture = Frame.CameraImage.Texture; if (!loggedAspectRatioWarning && cameraTexture != null) { var sourceWidth = cameraTexture.width; var sourceHeight = cameraTexture.height; var sourceAspectRatio = (float)sourceWidth / sourceHeight; var destinationWidth = Screen.width; var destinationHeight = Screen.height; var destinationAspectRatio = (float)destinationWidth / destinationHeight; if (Mathf.Abs(sourceAspectRatio - destinationAspectRatio) > k_MaxTolerableAspectRatioDifference) { Debug.LogWarning(string.Format(k_MismatchedAspectRatioWarningFormatString, sourceWidth, sourceHeight)); loggedAspectRatioWarning = true; } } NativeApi.SendFrame(targetTexture.GetNativeTexturePtr()); GL.IssuePluginEvent(renderEventFunc, 69); } }
private static IEnumerator UpdateLoop(string adbPath) { var renderEventFunc = NativeApi.GetRenderEventFunc(); var shouldConvertToBgra = SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D11; var loggedAspectRatioWarning = false; // Waits until the end of the first frame until capturing the screen size, // because it might be incorrect when first querying it. yield return(k_WaitForEndOfFrame); var currentWidth = 0; var currentHeight = 0; var needToStartActivity = true; var prevFrameLandscape = false; RenderTexture screenTexture = null; RenderTexture targetTexture = null; RenderTexture bgrTexture = null; // Begins update loop. The coroutine will cease when the // ARCoreSession component it's called from is destroyed. for (;;) { yield return(k_WaitForEndOfFrame); var curFrameLandscape = Screen.width > Screen.height; if (prevFrameLandscape != curFrameLandscape) { needToStartActivity = true; } prevFrameLandscape = curFrameLandscape; if (needToStartActivity) { string activityName = curFrameLandscape ? "InstantPreviewLandscapeActivity" : "InstantPreviewActivity"; string output; string errors; ShellHelper.RunCommand(adbPath, "shell am start -S -n com.google.ar.core.instantpreview/." + activityName, out output, out errors); needToStartActivity = false; } // Creates a target texture to capture the preview window onto. // Some video encoders prefer the dimensions to be a multiple of 16. var targetWidth = RoundUpToNearestMultipleOf16(Screen.width); var targetHeight = RoundUpToNearestMultipleOf16(Screen.height); if (targetWidth != currentWidth || targetHeight != currentHeight) { screenTexture = new RenderTexture(targetWidth, targetHeight, 0); targetTexture = screenTexture; if (shouldConvertToBgra) { bgrTexture = new RenderTexture( screenTexture.width, screenTexture.height, 0, RenderTextureFormat.BGRA32); targetTexture = bgrTexture; } currentWidth = targetWidth; currentHeight = targetHeight; } NativeApi.Update(); InstantPreviewInput.Update(); if (NativeApi.AppShowedTouchWarning()) { Debug.LogWarning(k_InstantPreviewInputWarning); NativeApi.UnityLoggedTouchWarning(); } AddInstantPreviewTrackedPoseDriverWhenNeeded(); Graphics.Blit(null, screenTexture); if (shouldConvertToBgra) { Graphics.Blit(screenTexture, bgrTexture); } var cameraTexture = Frame.CameraImage.Texture; if (!loggedAspectRatioWarning && cameraTexture != null) { var sourceWidth = cameraTexture.width; var sourceHeight = cameraTexture.height; var sourceAspectRatio = (float)sourceWidth / sourceHeight; var destinationWidth = Screen.width; var destinationHeight = Screen.height; var destinationAspectRatio = (float)destinationWidth / destinationHeight; if (Mathf.Abs(sourceAspectRatio - destinationAspectRatio) > k_MaxTolerableAspectRatioDifference) { Debug.LogWarningFormat( k_MismatchedAspectRatioWarningFormatString, sourceAspectRatio, destinationAspectRatio, sourceWidth, sourceHeight); loggedAspectRatioWarning = true; } } NativeApi.SendFrame(targetTexture.GetNativeTexturePtr()); GL.IssuePluginEvent(renderEventFunc, 1); } }