コード例 #1
0
        private static void WriteCommand(string program, string arguments, StreamWriter writer)
        {
            if (string.IsNullOrEmpty(program))
            {
                writer.WriteLine("error: program path was null");
            }
            else
            {
                string stdOut;
                string stdErr;

                ShellHelper.RunCommand(program, arguments, out stdOut, out stdErr);

                if (!string.IsNullOrEmpty(stdOut))
                {
                    writer.WriteLine(stdOut);
                }

                if (!string.IsNullOrEmpty(stdErr))
                {
                    writer.WriteLine(stdErr);
                }
            }

            writer.WriteLine();
        }
コード例 #2
0
        private bool _IsApiKeyDirty(string jarPath, string aarPath, string apiKey)
        {
            bool isApiKeyDirty          = true;
            var  cachedCurrentDirectory = Directory.GetCurrentDirectory();
            var  tempDirectoryPath      =
                Path.Combine(cachedCurrentDirectory, FileUtil.GetUniqueTempPathInProject());

            if (!File.Exists(aarPath))
            {
                return(isApiKeyDirty);
            }

            try
            {
                // Move to a temp directory.
                Directory.CreateDirectory(tempDirectoryPath);
                Directory.SetCurrentDirectory(tempDirectoryPath);
                var tempAarPath = Path.Combine(tempDirectoryPath, "cloud_anchor_manifest.aar");
                File.Copy(aarPath, tempAarPath, true);

                // Extract the aar.
                string output;
                string errors;
                ShellHelper.RunCommand(jarPath, string.Format("xf \"{0}\"", tempAarPath),
                                       out output, out errors);

                // Read Api key parameter in manifest file.
                var         manifestPath = Path.Combine(tempDirectoryPath, "AndroidManifest.xml");
                XmlDocument xmlDocument  = new XmlDocument();
                xmlDocument.Load(manifestPath);
                XmlNode metaDataNode =
                    xmlDocument.SelectSingleNode("/manifest/application/meta-data");
                string oldApiKey = metaDataNode.Attributes["android:value"].Value;
                isApiKeyDirty = !apiKey.Equals(oldApiKey);
            }
            finally
            {
                // Cleanup.
                Directory.SetCurrentDirectory(cachedCurrentDirectory);
                Directory.Delete(tempDirectoryPath, true);
            }

            return(isApiKeyDirty);
        }
コード例 #3
0
        private static void WritePackageVersionString(
            string adbPath, string package, StreamWriter writer)
        {
            if (string.IsNullOrEmpty(adbPath))
            {
                writer.WriteLine("error: adb path was null");
            }
            else
            {
                string stdOut;
                string stdErr;
                string arguments = "shell pm dump " + package + " | " +
                                   "egrep -m 1 -i 'versionName' | sed -n 's/.*versionName=//p'";

                ShellHelper.RunCommand(adbPath, arguments, out stdOut, out stdErr);

                // If stdOut is populated, the device is connected and the app is installed
                if (!string.IsNullOrEmpty(stdOut))
                {
                    writer.WriteLine(stdOut);
                }
                else
                {
                    // If stdErr isn't empty, then either the device isn't connected or something
                    // else went wrong, such as adb not being installed.
                    if (!string.IsNullOrEmpty(stdErr))
                    {
                        writer.WriteLine(stdErr);
                    }
                    else
                    {
                        // If stdErr is empty, then the device is connected and the app isn't
                        // installed
                        writer.WriteLine(package + " is not installed on device");
                    }
                }
            }

            writer.WriteLine();
        }
コード例 #4
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();

            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);
            }

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

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

                        ShellHelper.RunCommand(adbPath,
                                               "uninstall com.google.ar.core.instantpreview",
                                               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) && errors != "Success")
                        {
                            Debug.LogErrorFormat(
                                "Failed to install Instant Preview app:\n{0}", errors);
                        }
                    });
                    installThread.Start();

                    while (!installThread.Join(0))
                    {
                        yield return(0);
                    }
                }
                else
                {
                    yield break;
                }
            }
        }
コード例 #5
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();

                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);
            }
        }
コード例 #6
0
        private static void _RunDirtyQualityJobs(AugmentedImageDatabase database)
        {
            if (database == null)
            {
                return;
            }

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

                s_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 (s_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;
                s_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 (s_UpdatedQualityScores)
                    {
                        s_UpdatedQualityScores.Add(textureGUID, quality);
                    }
                });
            }

            // For refreshing inspector UI as new jobs have been enqueued.
            EditorUtility.SetDirty(database);
        }
コード例 #7
0
        private void _PreprocessAndroidBuild()
        {
            // Get the Jdk path.
            var jdkPath = UnityEditor.EditorPrefs.GetString("JdkPath");

            if (string.IsNullOrEmpty(jdkPath))
            {
                Debug.Log(
                    "Unity 'Preferences > External Tools > Android JDK' path 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));
                    }

                    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. Cloud Anchors will be disabled in " +
                    "this build.");
                File.Delete(cloudAnchorsManifestAarPath);
                AssetDatabase.Refresh();
            }
        }
コード例 #8
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, k_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;
            }
        }