Пример #1
0
        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();
                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, sourceWidth,
                                               sourceHeight);
                        loggedAspectRatioWarning = true;
                    }
                }

                NativeApi.SendFrame(targetTexture.GetNativeTexturePtr());
                GL.IssuePluginEvent(renderEventFunc, 1);
            }
        }
Пример #2
0
        /// <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.LogErrorFormat("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();

#if !UNITY_WSA
            Thread checkAdbThread = new Thread((object obj) =>
            {
                Result res = (Result)obj;
                string output;
                string errors;

                // Gets version of installed apk.
                ShellHelper.RunCommand(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.LogFormat(
                        "Instant Preview app not installed on device.",
                        apkPath);
                }
                else if (installedVersion != localVersion)
                {
                    Debug.LogFormat(
                        "Instant Preview installed version \"{0}\" does not match local version \"{1}\".",
                        installedVersion, localVersion);
                }

                res.ShouldPromptForInstall = installedVersion != localVersion;
            });
            checkAdbThread.Start(result);

            while (!checkAdbThread.Join(0))
            {
                yield return(0);
            }
#endif

            if (result.ShouldPromptForInstall)
            {
                if (PromptToInstall())
                {
#if !UNITY_WSA
                    Thread installThread = new Thread(() =>
                    {
                        string output;
                        string errors;

                        Debug.LogFormat(
                            "Installing Instant Preview app version {0}.",
                            localVersion);

                        ShellHelper.RunCommand(adbPath,
                                               string.Format("uninstall com.google.ar.core.instantpreview", apkPath),
                                               out output, out errors);

                        ShellHelper.RunCommand(adbPath,
                                               string.Format("install \"{0}\"", apkPath),
                                               out output, out errors);

                        // Prints any output from trying to install.
                        if (!string.IsNullOrEmpty(output))
                        {
                            Debug.LogFormat("Instant Preview installation\n{0}", output);
                        }

                        if (!string.IsNullOrEmpty(errors))
                        {
                            Debug.LogErrorFormat("Failed to install Instant Preview app:\n{0}", errors);
                        }
                    });
                    installThread.Start();

                    while (!installThread.Join(0))
                    {
                        yield return(0);
                    }
#endif
                }
                else
                {
                    yield break;
                }
            }
        }
        private void PreprocessAndroidBuild()
        {
            // This function causes build error in 2020.2 if the current directory is changed.
            // So do the check first here.
            CheckCompatibilityWithAllSesssionConfigs(
                ARCoreProjectSettings.Instance, AndroidDependenciesHelper.GetAllSessionConfigs());

            string cachedCurrentDirectory = Directory.GetCurrentDirectory();
            string pluginsFolderPath      = Path.Combine(cachedCurrentDirectory,
                                                         AssetDatabase.GUIDToAssetPath(_pluginsFolderGuid));
            string customizedManifestAarPath =
                Path.Combine(pluginsFolderPath, "customized_manifest.aar");

            string jarPath = Path.Combine(AndroidDependenciesHelper.GetJdkPath(), "bin/jar");

            var tempDirectoryPath =
                Path.Combine(cachedCurrentDirectory, FileUtil.GetUniqueTempPathInProject());

            try
            {
                // Move to a temp directory.
                Directory.CreateDirectory(tempDirectoryPath);
                Directory.SetCurrentDirectory(tempDirectoryPath);

                CreateClassesJar(jarPath, tempDirectoryPath);

                XDocument customizedManifest =
                    GenerateCustomizedAndroidManifest(ARCoreProjectSettings.Instance);
                var manifestPath = Path.Combine(tempDirectoryPath, "AndroidManifest.xml");
                customizedManifest.Save(manifestPath);

                // Compress the new AAR.
                var fileListBuilder = new StringBuilder();
                foreach (var filePath in Directory.GetFiles(tempDirectoryPath))
                {
                    fileListBuilder.AppendFormat(" {0}", Path.GetFileName(filePath));
                }

                string command = string.Format(
                    "cf customized_manifest.aar {0}", fileListBuilder.ToString());

                string output;
                string errors;
                ShellHelper.RunCommand(jarPath, command, out output, out errors);

                if (!string.IsNullOrEmpty(errors))
                {
                    throw new BuildFailedException(
                              string.Format(
                                  "Error creating aar for manifest: {0}", errors));
                }

                File.Copy(Path.Combine(tempDirectoryPath, "customized_manifest.aar"),
                          customizedManifestAarPath, true);
            }
            finally
            {
                // Cleanup.
                Directory.SetCurrentDirectory(cachedCurrentDirectory);
                Directory.Delete(tempDirectoryPath, true);

                AssetDatabase.Refresh();
            }

            AssetHelper.GetPluginImporterByName("customized_manifest.aar")
            .SetCompatibleWithPlatform(BuildTarget.Android, true);
        }
Пример #4
0
        /// <summary>
        /// Coroutine method that communicates to the Instant Preview plugin
        /// every frame.
        ///
        /// If Instant Preview is not the providing platform, this does nothing.
        /// </summary>
        /// <returns>Enumerator for a coroutine that updates Instant Preview
        /// every frame.</returns>
        public static IEnumerator InitializeIfNeeded()
        {
            // Terminates if instant preview is not providing the platform.
            if (!IsProvidingPlatform)
            {
                yield break;
            }

            // User may have explicitly disabled Instant Preview.
            if (ARCoreProjectSettings.Instance != null &&
                !ARCoreProjectSettings.Instance.IsInstantPreviewEnabled)
            {
                yield break;
            }

#if UNITY_EDITOR
            // When build platform is not Android, verify min game view scale is 1.0x to prevent
            // confusing 2x scaling when Unity editor is running on a high density display.
            if (EditorUserBuildSettings.activeBuildTarget != BuildTarget.Android)
            {
                float minGameViewScale = GetMinGameViewScaleOrUnknown();
                if (minGameViewScale != 1.0)
                {
                    String viewScaleText = minGameViewScale == k_UnknownGameViewScale ?
                                           "<unknown>" : string.Format("{0}x", minGameViewScale);
                    Debug.LogWarningFormat(
                        "Instant Preview disabled, {0} minimum Game view scale unsupported for " +
                        "target build platform '{1}'.\n" +
                        "To use Instant Preview, switch build platform to '{2}' from the 'Build " +
                        "settings' window.",
                        viewScaleText,
                        EditorUserBuildSettings.activeBuildTarget,
                        BuildTarget.Android);
                    yield break;
                }
            }

            // Determine if any augmented image databases need a rebuild.
            List <AugmentedImageDatabase> databases = new List <AugmentedImageDatabase>();
            bool shouldRebuild = false;

            var augmentedImageDatabaseGuids = AssetDatabase.FindAssets("t:AugmentedImageDatabase");
            foreach (var databaseGuid in augmentedImageDatabaseGuids)
            {
                var database = AssetDatabase.LoadAssetAtPath <AugmentedImageDatabase>(
                    AssetDatabase.GUIDToAssetPath(databaseGuid));
                databases.Add(database);

                shouldRebuild = shouldRebuild || database.IsBuildNeeded();
            }

            // If the preference is to ask the user to rebuild, ask now.
            if (shouldRebuild && PromptToRebuildAugmentedImagesDatabase())
            {
                foreach (var database in databases)
                {
                    string error;
                    database.BuildIfNeeded(out error);
                    if (!string.IsNullOrEmpty(error))
                    {
                        Debug.LogWarning("Failed to rebuild augmented image database: " + error);
                    }
                }
            }
#endif

            var adbPath = ShellHelper.GetAdbPath();
            if (adbPath == null)
            {
                Debug.LogError("Instant Preview requires your Unity Android SDK path to be set. " +
                               "Please set it under 'Preferences > External Tools > Android'. " +
                               "You may need to install the Android SDK first.");
                yield break;
            }
            else if (!File.Exists(adbPath))
            {
                Debug.LogErrorFormat(
                    "adb not found at \"{0}\". Please verify that 'Preferences > External Tools " +
                    "> Android' has the correct Android SDK path that the Android Platform Tools " +
                    "are installed, and that \"{0}\" exists. You may need to install the Android " +
                    "SDK first.", adbPath);
                yield break;
            }

            if (Environment.GetEnvironmentVariable("ADB_TRACE") != null)
            {
                Debug.LogWarning("Instant Preview: ADB_TRACE was defined. Unsetting environment " +
                                 "variable for compatibility with Instant Preview.");
                Environment.SetEnvironmentVariable("ADB_TRACE", null);
            }

            string localVersion;
            if (!StartServer(adbPath, out localVersion))
            {
                yield break;
            }

            yield return(InstallApkAndRunIfConnected(adbPath, localVersion));

            yield return(UpdateLoop(adbPath));
        }
        private void _PreprocessAndroidBuild()
        {
            // Get the Jdk path.
            var jdkPath = UnityEditor.EditorPrefs.GetString("JdkPath");

            if (string.IsNullOrEmpty(jdkPath))
            {
                Debug.Log("JDK path Unity pref is not set. Falling back to JAVA_HOME environment variable.");
                jdkPath = System.Environment.GetEnvironmentVariable("JAVA_HOME");
            }
            if (string.IsNullOrEmpty(jdkPath))
            {
                throw new BuildFailedException("A JDK path needs to be specified for the Android build.");
            }
            bool cloudAnchorsEnabled    = !string.IsNullOrEmpty(ARCoreProjectSettings.Instance.CloudServicesApiKey);
            var  cachedCurrentDirectory = Directory.GetCurrentDirectory();
            var  pluginsFolderPath      = Path.Combine(cachedCurrentDirectory,
                                                       AssetDatabase.GUIDToAssetPath(k_PluginsFolderGuid));
            string cloudAnchorsManifestAarPath = Path.Combine(pluginsFolderPath, "cloud_anchor_manifest.aar");
            var    jarPath = Path.Combine(jdkPath, "bin/jar");

            if (cloudAnchorsEnabled)
            {
                // If the Api Key didn't change then do nothing.
                if (!_IsApiKeyDirty(jarPath, cloudAnchorsManifestAarPath,
                                    ARCoreProjectSettings.Instance.CloudServicesApiKey))
                {
                    return;
                }
                // Replace the project's cloud anchor AAR with the newly generated AAR.
                Debug.Log("Enabling Cloud Anchors in this build.");
                var tempDirectoryPath = Path.Combine(cachedCurrentDirectory, FileUtil.GetUniqueTempPathInProject());
                try {
                    // Move to a temp directory.
                    Directory.CreateDirectory(tempDirectoryPath);
                    Directory.SetCurrentDirectory(tempDirectoryPath);
                    var manifestTemplatePath = Path.Combine(cachedCurrentDirectory, AssetDatabase.GUIDToAssetPath(k_ManifestTemplateGuid));
                    // Extract the "template AAR" and remove it.
                    string output;
                    string errors;
                    ShellHelper.RunCommand(jarPath, string.Format("xf \"{0}\"", manifestTemplatePath),
                                           out output, out errors);
                    // Replace Api key template parameter in manifest file.
                    var manifestPath = Path.Combine(tempDirectoryPath, "AndroidManifest.xml");
                    var manifestText = File.ReadAllText(manifestPath);
                    manifestText = manifestText.Replace("{{CLOUD_ANCHOR_API_KEY}}", ARCoreProjectSettings.Instance.CloudServicesApiKey);
                    File.WriteAllText(manifestPath, manifestText);
                    // Compress the new AAR.
                    var fileListBuilder = new StringBuilder();
                    foreach (var filePath in Directory.GetFiles(tempDirectoryPath))
                    {
                        fileListBuilder.AppendFormat(" {0}", Path.GetFileName(filePath));
                    }
                    ShellHelper.RunCommand(jarPath,
                                           string.Format("cf cloud_anchor_manifest.aar {0}", fileListBuilder.ToString()),
                                           out output, out errors);
                    if (!string.IsNullOrEmpty(errors))
                    {
                        throw new BuildFailedException(
                                  string.Format("Error creating jar for cloud anchor manifest: {0}", errors));
                    }
                    File.Copy(Path.Combine(tempDirectoryPath, "cloud_anchor_manifest.aar"),
                              cloudAnchorsManifestAarPath, true);
                } finally {
                    // Cleanup.
                    Directory.SetCurrentDirectory(cachedCurrentDirectory);
                    Directory.Delete(tempDirectoryPath, true);
                    AssetDatabase.Refresh();
                }
                AssetHelper.GetPluginImporterByName("cloud_anchor_manifest.aar")
                .SetCompatibleWithPlatform(BuildTarget.Android, true);
            }
            else
            {
                Debug.Log("A cloud anchor API key has not been set.  Cloud anchors are disabled in this build.");
                File.Delete(cloudAnchorsManifestAarPath);
                AssetDatabase.Refresh();
            }
        }
        private static void RunDirtyQualityJobs(AugmentedImageDatabase database)
        {
            if (database == null)
            {
                return;
            }

            if (_databaseForQualityJobs != database)
            {
                // If another database is already running quality evaluation,
                // stop all pending jobs to prioritise the current database.
                if (_databaseForQualityJobs != null)
                {
                    _qualityBackgroundExecutor.RemoveAllPendingJobs();
                }

                _databaseForQualityJobs = database;
            }

            UpdateDatabaseQuality(database);

            // Set database dirty to refresh inspector UI for each frame that there are still
            // pending jobs.
            // Otherwise if there exists one frame with no newly finished jobs, the UI will never
            // get refreshed.
            // EditorUtility.SetDirty can only be called from main thread.
            if (_qualityBackgroundExecutor.PendingJobsCount > 0)
            {
                EditorUtility.SetDirty(database);
                return;
            }

            List <AugmentedImageDatabaseEntry> dirtyEntries = database.GetDirtyQualityEntries();

            if (dirtyEntries.Count == 0)
            {
                return;
            }

            string cliBinaryPath;

            if (!AugmentedImageDatabase.FindCliBinaryPath(out cliBinaryPath))
            {
                return;
            }

            for (int i = 0; i < dirtyEntries.Count; ++i)
            {
                AugmentedImageDatabaseEntry image = dirtyEntries[i];
                var imagePath   = AssetDatabase.GetAssetPath(image.Texture);
                var textureGUID = image.TextureGUID;
                _qualityBackgroundExecutor.PushJob(() =>
                {
                    string quality;
                    string error;
                    ShellHelper.RunCommand(
                        cliBinaryPath,
                        string.Format("eval-img --input_image_path \"{0}\"", imagePath),
                        out quality,
                        out error);
                    if (!string.IsNullOrEmpty(error))
                    {
                        Debug.LogError(error);
                        quality = "ERROR";
                    }

                    lock (_updatedQualityScores)
                    {
                        _updatedQualityScores.Add(textureGUID, quality);
                    }
                });
            }

            // For refreshing inspector UI as new jobs have been enqueued.
            EditorUtility.SetDirty(database);
        }
        private void SetApiKeyOnAndroid()
        {
            string cachedCurrentDirectory = Directory.GetCurrentDirectory();
            string pluginsFolderPath      = Path.Combine(cachedCurrentDirectory,
                                                         AssetDatabase.GUIDToAssetPath(_pluginsFolderGuid));
            string cloudAnchorsManifestAarPath =
                Path.Combine(pluginsFolderPath, "cloud_anchor_manifest.aar");

            bool cloudAnchorsEnabled =
                !string.IsNullOrEmpty(ARCoreProjectSettings.Instance.CloudServicesApiKey);

            if (cloudAnchorsEnabled)
            {
                string jarPath = AndroidDependenciesHelper.GetJdkPath();
                if (string.IsNullOrEmpty(jarPath))
                {
                    throw new BuildFailedException("Cannot find a valid JDK path in this build.");
                }

                jarPath = Path.Combine(jarPath, "bin/jar");

                // If the API Key didn't change then do nothing.
                if (!IsApiKeyDirty(jarPath, cloudAnchorsManifestAarPath,
                                   ARCoreProjectSettings.Instance.CloudServicesApiKey))
                {
                    return;
                }

                // Replace the project's cloud anchor AAR with the newly generated AAR.
                Debug.Log("Enabling Cloud Anchors with API Key Authentication in this build.");

                var tempDirectoryPath =
                    Path.Combine(cachedCurrentDirectory, FileUtil.GetUniqueTempPathInProject());

                try
                {
                    // Move to a temp directory.
                    Directory.CreateDirectory(tempDirectoryPath);
                    Directory.SetCurrentDirectory(tempDirectoryPath);

                    var manifestTemplatePath = Path.Combine(
                        cachedCurrentDirectory,
                        AssetDatabase.GUIDToAssetPath(_manifestTemplateGuid));

                    // Extract the "template AAR" and remove it.
                    string output;
                    string errors;
                    ShellHelper.RunCommand(
                        jarPath, string.Format("xf \"{0}\"", manifestTemplatePath), out output,
                        out errors);

                    // Replace Api key template parameter in manifest file.
                    var manifestPath = Path.Combine(tempDirectoryPath, "AndroidManifest.xml");
                    var manifestText = File.ReadAllText(manifestPath);
                    manifestText = manifestText.Replace(
                        "{{CLOUD_ANCHOR_API_KEY}}",
                        ARCoreProjectSettings.Instance.CloudServicesApiKey);
                    File.WriteAllText(manifestPath, manifestText);

                    // Compress the new AAR.
                    var fileListBuilder = new StringBuilder();
                    foreach (var filePath in Directory.GetFiles(tempDirectoryPath))
                    {
                        fileListBuilder.AppendFormat(" {0}", Path.GetFileName(filePath));
                    }

                    string command = string.Format(
                        "cf cloud_anchor_manifest.aar {0}", fileListBuilder.ToString());

                    ShellHelper.RunCommand(
                        jarPath,
                        command,
                        out output,
                        out errors);

                    if (!string.IsNullOrEmpty(errors))
                    {
                        throw new BuildFailedException(
                                  string.Format(
                                      "Error creating jar for cloud anchor manifest: {0}", errors));
                    }

                    File.Copy(Path.Combine(tempDirectoryPath, "cloud_anchor_manifest.aar"),
                              cloudAnchorsManifestAarPath, true);
                }
                finally
                {
                    // Cleanup.
                    Directory.SetCurrentDirectory(cachedCurrentDirectory);
                    Directory.Delete(tempDirectoryPath, true);

                    AssetDatabase.Refresh();
                }

                AssetHelper.GetPluginImporterByName("cloud_anchor_manifest.aar")
                .SetCompatibleWithPlatform(BuildTarget.Android, true);
            }
            else
            {
                Debug.Log(
                    "Cloud Anchor API key has not been set in this build.");
                File.Delete(cloudAnchorsManifestAarPath);
                AssetDatabase.Refresh();
            }
        }
Пример #8
0
        private void StripAndBackupClientAar()
        {
            // Strip the <queries> tag from the arcore_client.aar when it's incompatible with
            // Unity's built-in gradle version.
            string cachedCurrentDirectory = Directory.GetCurrentDirectory();
            string pluginsFolderPath      = Path.Combine(cachedCurrentDirectory,
                                                         AssetDatabase.GUIDToAssetPath(_pluginsFolderGuid));

            string[] plugins       = Directory.GetFiles(pluginsFolderPath);
            string   clientAarPath = string.Empty;

            foreach (var pluginPath in plugins)
            {
                if (pluginPath.Contains(_clientAarName) &&
                    !pluginPath.Contains(".meta") &&
                    AssetHelper.GetPluginImporterByName(Path.GetFileName(pluginPath))
                    .GetCompatibleWithPlatform(BuildTarget.Android))
                {
                    clientAarPath = pluginPath;
                    break;
                }
            }

            if (string.IsNullOrEmpty(clientAarPath))
            {
                throw new BuildFailedException(
                          string.Format("Cannot find a valid arcore client plugin under '{0}'",
                                        pluginsFolderPath));
            }

            string clientAarFileName = Path.GetFileName(clientAarPath);
            string jarPath           = AndroidDependenciesHelper.GetJdkPath();

            if (string.IsNullOrEmpty(jarPath))
            {
                throw new BuildFailedException("Cannot find a valid JDK path in this build.");
            }

            jarPath = Path.Combine(jarPath, "bin/jar");
            var tempDirectoryPath =
                Path.Combine(cachedCurrentDirectory, FileUtil.GetUniqueTempPathInProject());

            // Back up existing client AAR.
            string backupFilename = clientAarFileName + _backupExtension;

            Debug.LogFormat("Backing up {0} in {1}.", clientAarFileName, backupFilename);
            File.Copy(clientAarPath, Path.Combine(pluginsFolderPath, backupFilename), true);
            _hasBackup = true;

            Debug.LogFormat("Stripping the <queries> tag from {0} in this build.",
                            clientAarFileName);
            try
            {
                // Move to a temp directory.
                Directory.CreateDirectory(tempDirectoryPath);
                Directory.SetCurrentDirectory(tempDirectoryPath);

                // Extract the existing AAR in the temp directory.
                string output;
                string errors;
                ShellHelper.RunCommand(
                    jarPath, string.Format("xf \"{0}\"", clientAarPath), out output,
                    out errors);

                // Strip the <queries> tag from AndroidManifest.xml.
                var manifestPath = Path.Combine(tempDirectoryPath, "AndroidManifest.xml");
                var manifestText = File.ReadAllText(manifestPath);
                manifestText = System.Text.RegularExpressions.Regex.Replace(
                    manifestText, "(/s)?<queries>(.*)</queries>(\n|\r|\r\n)", string.Empty,
                    System.Text.RegularExpressions.RegexOptions.Singleline);
                File.WriteAllText(manifestPath, manifestText);

                // Compress the modified AAR.
                string command = string.Format("cf {0} .", clientAarFileName);
                ShellHelper.RunCommand(
                    jarPath,
                    command,
                    out output,
                    out errors);

                if (!string.IsNullOrEmpty(errors))
                {
                    throw new BuildFailedException(
                              string.Format(
                                  "Error creating jar for stripped arcore client manifest: {0}", errors));
                }

                // Override the existing client AAR with the modified one.
                File.Copy(Path.Combine(tempDirectoryPath, clientAarFileName),
                          clientAarPath, true);
            }
            finally
            {
                // Cleanup.
                Directory.SetCurrentDirectory(cachedCurrentDirectory);
                Directory.Delete(tempDirectoryPath, true);

                AssetDatabase.Refresh();
            }

            AssetHelper.GetPluginImporterByName(clientAarFileName)
            .SetCompatibleWithPlatform(BuildTarget.Android, true);
        }
Пример #9
0
        private static void CaptureBugReport()
        {
            string desktopPath = Environment.GetFolderPath(
                Environment.SpecialFolder.Desktop);
            DateTime timeStamp         = DateTime.Now;
            string   fileNameTimestamp = timeStamp.ToString("yyyyMMdd_hhmmss");
            string   filePath          = Path.Combine(
                desktopPath, _fileNamePrefix + fileNameTimestamp + ".txt");
            StreamWriter writer;

            // Operating system and hardware info have to be handled separately based on OS
            switch (SystemInfo.operatingSystemFamily)
            {
            case OperatingSystemFamily.MacOSX:
                writer = File.CreateText(filePath);

                writer.WriteLine("*** GOOGLE ARCORE SDK FOR UNITY OSX BUG REPORT ***");
                writer.WriteLine("Timestamp: " + timeStamp.ToString());

                writer.WriteLine();
                writer.WriteLine("*** OPERATING SYSTEM INFORMATION ***");
                WriteCommand("system_profiler", "SPSoftwareDataType", writer);

                writer.WriteLine("*** GRAPHICS INFORMATION ***");
                WriteCommand("system_profiler", "SPDisplaysDataType", writer);

                WriteOsIndependentFields(writer);

                string stdOut;
                string stdErr;

                // Get PATH directories to search for adb in.
                ShellHelper.RunCommand(
                    "/bin/bash", "-c -l \"echo $PATH\"", out stdOut, out stdErr);
                stdOut.Trim();

                writer.WriteLine("*** ADB VERSIONS ON PATH ***");
                WriteAdbPathVersions(stdOut.Split(':'), writer);

                writer.WriteLine("*** TYPE -A ADB ***");
                WriteCommand("/bin/bash", "-c -l \"type -a adb\"", writer);

                writer.WriteLine("*** RUNNING ADB PROCESSES ***");
                WriteCommand(
                    "/bin/bash", "-c -l \"ps -ef | grep -i adb | grep -v grep\"", writer);

                writer.WriteLine("*** RUNNING UNITY PROCESSES ***");
                WriteCommand(
                    "/bin/bash", "-c -l \"ps -ef | grep -i Unity | grep -v grep\"", writer);

                writer.Close();

                Debug.Log(
                    "ARCore bug report captured. File can be found here:\n" +
                    Path.GetFullPath(filePath));
                break;

            case OperatingSystemFamily.Windows:
                writer = File.CreateText(filePath);

                writer.WriteLine("*** GOOGLE ARCORE SDK FOR UNITY WINDOWS BUG REPORT ***");
                writer.WriteLine("Timestamp: " + timeStamp.ToString());

                writer.WriteLine("*** OPERATING SYSTEM INFORMATION ***");
                WriteCommand("cmd.exe", "/C systeminfo", writer);

                writer.WriteLine("*** GRAPHICS INFORMATION ***");
                WriteCommand(
                    "cmd.exe", "/C wmic path win32_VideoController get /format:list", writer);

                WriteOsIndependentFields(writer);

                string pathStr = Environment.GetEnvironmentVariable("PATH").Trim();

                writer.WriteLine("*** ADB VERSIONS ON PATH ***");
                WriteAdbPathVersions(pathStr.Split(';'), writer);

                writer.WriteLine("*** RUNNING ADB PROCESSES ***");
                WriteCommand("cmd.exe",
                             "/C TASKLIST | c:\\Windows\\System32\\findstr.exe \"adb\"", writer);

                writer.WriteLine("*** RUNNING UNITY PROCESSES ***");
                WriteCommand("cmd.exe",
                             "/C TASKLIST | c:\\Windows\\System32\\findstr.exe \"Unity\"", writer);

                writer.Close();

                Debug.Log(
                    "ARCore bug report captured. File can be found here:\n" +
                    Path.GetFullPath(filePath));
                break;

            default:
                string dialogMessage = "ARCore does not support capturing bug reports for " +
                                       SystemInfo.operatingSystemFamily + " at this time.";

                EditorUtility.DisplayDialog("ARCore Bug Report", dialogMessage, "OK");
                break;
            }
        }