Example #1
0
        /// <summary>
        /// Open a install / license window and execute a command.
        /// </summary>
        /// <param name="toolPath">Tool to run.</param>
        /// <param name="toolArguments">Arguments to pass to the tool.</param>
        /// <param name="retrievingLicenses">Whether the command is retrieving licenses.</param>
        /// <param name="licenseResponder">Responds to license questions.</param>
        /// <param name="packages">List of package versions to install / upgrade.</param>
        /// <param name="complete">Called when installation is complete.</param>
        private static void DisplayInstallLicenseDialog(
            string toolPath, string toolArguments, bool retrievingLicenses,
            LicenseResponder licenseResponder,
            IEnumerable <AndroidSdkPackageNameVersion> packages,
            Action <CommandLine.Result> complete)
        {
            var summary = retrievingLicenses ?
                          "Attempting Android SDK package installation..." : DIALOG_TITLE + "...";
            var window = CommandLineDialog.CreateCommandLineDialog(DIALOG_TITLE);

            window.summaryText = summary;
            window.modal       = false;
            window.bodyText    = String.Format("{0} {1}\n\n", toolPath, toolArguments);
            // Note: not displaying progress bar
            window.autoScrollToBottom = true;
            CommandLine.IOHandler ioHandler = null;
            if (licenseResponder != null)
            {
                ioHandler = licenseResponder.AggregateLine;
            }
            PlayServicesResolver.Log(String.Format("{0} {1}", toolPath, toolArguments),
                                     level: LogLevel.Verbose);
            window.RunAsync(
                toolPath, toolArguments,
                (CommandLine.Result result) => {
                HandleProcessExited(result, window);
                LogInstallLicenseResult(toolPath, toolArguments, retrievingLicenses, packages,
                                        result);
                complete(result);
            },
                ioHandler: ioHandler,
                maxProgressLines: retrievingLicenses ? 250 : 500);
            window.Show();
        }
Example #2
0
        /// <summary>
        /// Convert an N component version string into an integer.
        /// </summary>
        /// <param name="versionString">Version string to convert.</param>
        /// <param name="componentMultiplier">Value to multiply each component by.</param>
        /// <returns>An integer representation of the version string.</returns>
        public static long ConvertVersionStringToInteger(string versionString,
                                                         long componentMultiplier = 1000000)
        {
            if (String.IsNullOrEmpty(versionString))
            {
                return(0);
            }
            var  components        = versionString.Split(new [] { '.' });
            long versionInteger    = 0;
            long currentMultiplier = 1;

            Array.Reverse(components);
            foreach (var component in components)
            {
                long componentInteger = 0;
                try {
                    componentInteger = Convert.ToInt64(component);
                } catch (FormatException) {
                    PlayServicesResolver.Log(
                        String.Format("Unable to convert version string {0} to " +
                                      "integer value", versionString),
                        level: LogLevel.Warning);
                    return(0);
                }
                versionInteger    += (componentInteger * currentMultiplier);
                currentMultiplier *= componentMultiplier;
            }
            return(versionInteger);
        }
Example #3
0
        /// <summary>
        /// Log a message that describes the installation / license fetching operation.
        /// </summary>
        /// <param name="toolPath">Tool that was executed.</param>
        /// <param name="toolArguments">Arguments to passed to the tool.</param>
        /// <param name="retrievingLicenses">Whether the command is retrieving licenses.</param>
        /// <param name="packages">List of package versions to install / upgrade..</param>
        /// <param name="toolResult">Result of the tool's execution.</param>
        private static void LogInstallLicenseResult(
            string toolPath, string toolArguments, bool retrievingLicenses,
            IEnumerable <AndroidSdkPackageNameVersion> packages,
            CommandLine.Result toolResult)
        {
            bool succeeded = toolResult.exitCode == 0;

            if (!retrievingLicenses || !succeeded)
            {
                var failedMessage = retrievingLicenses ?
                                    "Failed to retrieve Android SDK package licenses.\n\n" +
                                    "Aborted installation of the following packages:\n" :
                                    "Android package installation failed.\n\n" +
                                    "Failed when installing the following packages:\n";
                PlayServicesResolver.Log(
                    String.Format(
                        "{0}\n" +
                        "{1}\n\n" +
                        "{2}\n",
                        succeeded ? "Successfully installed Android packages.\n\n" : failedMessage,
                        AndroidSdkPackageNameVersion.ListToString(packages),
                        toolResult.message),
                    level: succeeded ? LogLevel.Info : LogLevel.Warning);
            }
        }
Example #4
0
        /// <summary>
        /// Find a tool in the Android SDK.
        /// </summary>
        /// <param name="toolName">Name of the tool to search for.</param>
        /// <param name="sdkPath">SDK path to search for the tool.  If this is null or empty, the
        // system path is searched instead.</param>
        /// <returns>String with the path to the tool if found, null otherwise.</returns>
        private static string FindAndroidSdkTool(string toolName, string sdkPath = null)
        {
            if (String.IsNullOrEmpty(sdkPath))
            {
                PlayServicesResolver.Log(String.Format(
                                             "Falling back to searching for the Android SDK tool {0} in the system path.",
                                             toolName));
            }
            else
            {
                var extensions = new List <string> {
                    CommandLine.GetExecutableExtension()
                };
                if (UnityEngine.RuntimePlatform.WindowsEditor ==
                    UnityEngine.Application.platform)
                {
                    extensions.AddRange(new [] { ".bat", ".cmd" });
                }
                foreach (var dir in new [] { "tools", Path.Combine("tools", "bin") })
                {
                    foreach (var extension in extensions)
                    {
                        var currentPath = Path.Combine(sdkPath,
                                                       Path.Combine(dir, toolName + extension));
                        if (File.Exists(currentPath))
                        {
                            return(currentPath);
                        }
                    }
                }
            }
            var toolPath = CommandLine.FindExecutable(toolName);

            return(toolPath != null && File.Exists(toolPath) ? toolPath : null);
        }
Example #5
0
 /// <summary>
 /// Called when the currently executing command completes.
 /// </summary>
 public void CommandLineToolCompletion(CommandLine.Result result)
 {
     PlayServicesResolver.Log(
         string.Format("Command completed with exit code {0}: {1}", result.exitCode, result.message),
         result.exitCode == 0 ? LogLevel.Info: LogLevel.Error);
     this.result = result;
 }
Example #6
0
 /// <summary>
 /// Retrieve package licenses, display license dialog and then install packages.
 /// </summary>
 /// <param name="toolPath">Tool to run.</param>
 /// <param name="toolArguments">Arguments to pass to the tool.</param>
 /// <param name="packages">List of package versions to install / upgrade.</param>
 /// <param name="licenseQuestion">License question to respond to.</param>
 /// <param name="licenseAgree">String used to agree to a license.</param>
 /// <param name="licenseDecline">String used to decline a license.</param>
 /// <param name="licenseTextHeader">Regex which matches the line which is the start of a
 /// license agreement.</param>
 /// <param name="complete">Called when installation is complete.</param>
 public static void InstallPackages(
     string toolPath, string toolArguments,
     HashSet <AndroidSdkPackageNameVersion> packages,
     string licenseQuestion, string licenseAgree, string licenseDecline,
     Regex licenseTextHeader, Action <bool> complete)
 {
     PlayServicesResolver.Log(String.Format("Install Android SDK packages\n" +
                                            "\n" +
                                            "{0} {1}\n",
                                            toolPath, toolArguments),
                              level: LogLevel.Verbose);
     // Display the license retrieval dialog.
     DisplayInstallLicenseDialog(
         toolPath, toolArguments, true,
         new LicenseResponder(licenseQuestion, licenseDecline), packages,
         (CommandLine.Result licensesResult) => {
         if (licensesResult.exitCode != 0)
         {
             complete(false);
             return;
         }
         // Get the license text.
         var licensesLines  = new List <string>();
         bool foundLicenses = false;
         foreach (var line in CommandLine.SplitLines(licensesResult.stdout))
         {
             foundLicenses = foundLicenses || licenseTextHeader.Match(line).Success;
             if (foundLicenses)
             {
                 licensesLines.Add(line);
             }
         }
         if (licensesLines.Count == 0)
         {
             LogInstallLicenseResult(toolPath, toolArguments, false, packages,
                                     licensesResult);
             complete(true);
             return;
         }
         // Display the license agreement dialog.
         DisplayLicensesDialog(
             String.Join("\n", licensesLines.ToArray()),
             (bool agreed) => {
             if (!agreed)
             {
                 complete(false);
                 return;
             }
             // Finally install the packages agreeing to the license questions.
             DisplayInstallLicenseDialog(
                 toolPath, toolArguments, false,
                 new LicenseResponder(licenseQuestion, licenseAgree), packages,
                 (CommandLine.Result installResult) => {
                 complete(installResult.exitCode == 0);
             });
         });
     });
 }
Example #7
0
 /// <summary>
 /// Log an error and complete a Create() operation.
 /// </summary>
 /// <param name="complete">Action called with null.</param>
 private static void CreateFailed(Action <IAndroidSdkManager> complete)
 {
     PlayServicesResolver.Log(String.Format(
                                  "Unable to find either the {0} or {1} command line tool.\n\n" +
                                  "It is not possible to query or install Android SDK packages.\n" +
                                  "To resolve this issue, open the Android Package Manager" +
                                  "and install the latest tools package.",
                                  SdkManager.TOOL_NAME, AndroidToolSdkManager.TOOL_NAME));
     complete(null);
 }
Example #8
0
 /// <summary>
 /// Handles window behavior when the CommandLineDialog finishes, closing the window automatically if
 /// execution succeeded and leaving it open with a "Close" button if it failed.
 /// </summary>
 /// <param name="result">The result of the process execution.</param>
 /// <param name="window">The window that should be adjusted based on the process execution result.</param>
 private static void HandleProcessExited(CommandLine.Result result, CommandLineDialog window)
 {
     if (result.exitCode == 0)
     {
         window.Close();
     }
     else
     {
         PlayServicesResolver.Log(string.Format(PACKAGES_MISSING, result.message));
         window.noText = "Close";
         // After adding the button we need to scroll down a little more.
         window.scrollPosition.y = Mathf.Infinity;
         window.Repaint();
     }
 }
Example #9
0
        /// <summary>
        /// Read package metadata from the source.properties file within the specified directory.
        /// </summary>
        /// <param name="sdkDirectory">Android SDK directory to query.</param>
        /// <param name="packageDirectory">Directory containing the package relative to
        /// sdkDirectory.</param>
        public static AndroidSdkPackage ReadFromSourceProperties(string sdkDirectory,
                                                                 string packageDirectory)
        {
            var propertiesPath = System.IO.Path.Combine(
                sdkDirectory, System.IO.Path.Combine(packageDirectory, "source.properties"));
            string propertiesText = null;

            try {
                propertiesText = File.ReadAllText(propertiesPath);
            } catch (Exception e) {
                PlayServicesResolver.Log(String.Format("Unable to read {0}\n{1}\n",
                                                       propertiesPath, e.ToString()),
                                         level: LogLevel.Verbose);
                return(null);
            }
            // Unfortunately the package name is simply based upon the path within the SDK.
            var sdkPackage = new AndroidSdkPackage {
                Path = packageDirectory
            };
            const string VERSION_FIELD_NAME     = "Pkg.Revision=";
            const string DESCRIPTION_FIELD_NAME = "Pkg.Desc=";

            foreach (var rawLine in CommandLine.SplitLines(propertiesText))
            {
                var line = rawLine.Trim();
                // Ignore comments.
                if (line.StartsWith("#"))
                {
                    continue;
                }
                // Parse fields
                if (line.StartsWith(VERSION_FIELD_NAME))
                {
                    sdkPackage.VersionString = line.Substring(VERSION_FIELD_NAME.Length);
                }
                else if (line.StartsWith(DESCRIPTION_FIELD_NAME))
                {
                    sdkPackage.Description = line.Substring(DESCRIPTION_FIELD_NAME.Length);
                }
            }
            return(sdkPackage);
        }
Example #10
0
        /// <summary>
        /// Use the package manager to retrieve the set of installed and available packages.
        /// </summary>
        /// <param name="toolPath">Tool to run.</param>
        /// <param name="toolArguments">Arguments to pass to the tool.</param>
        /// <param name="complete">Called when the query is complete.</param>
        public static void QueryPackages(string toolPath, string toolArguments,
                                         Action <CommandLine.Result> complete)
        {
            var window = CommandLineDialog.CreateCommandLineDialog(
                "Querying Android SDK packages");

            PlayServicesResolver.Log(String.Format("Query Android SDK packages\n" +
                                                   "\n" +
                                                   "{0} {1}\n",
                                                   toolPath, toolArguments),
                                     level: LogLevel.Verbose);
            window.summaryText = "Getting Installed Android SDK packages.";
            window.modal       = false;
            // Note: not displaying progress bar
            window.autoScrollToBottom = true;
            window.RunAsync(
                toolPath, toolArguments,
                (CommandLine.Result result) => {
                HandleProcessExited(result, window);
                complete(result);
            },
                maxProgressLines: 50);
            window.Show();
        }
Example #11
0
 /// <summary>
 /// Asynchronously execute a command line tool in this window, showing progress
 /// and finally calling the specified delegate on completion from the main / UI thread.
 /// </summary>
 /// <param name="toolPath">Tool to execute.</param>
 /// <param name="arguments">String to pass to the tools' command line.</param>
 /// <param name="completionDelegate">Called when the tool completes.</param>
 /// <param name="workingDirectory">Directory to execute the tool from.</param>
 /// <param name="ioHandler">Allows a caller to provide interactive input and also handle
 /// both output and error streams from a single delegate.</param>
 /// <param name="maxProgressLines">Specifies the number of lines output by the
 /// command line that results in a 100% value on a progress bar.</param>
 /// <returns>Reference to the new window.</returns>
 public void RunAsync(
     string toolPath, string arguments,
     CommandLine.CompletionHandler completionDelegate,
     string workingDirectory         = null, Dictionary <string, string> envVars = null,
     CommandLine.IOHandler ioHandler = null, int maxProgressLines                = 0)
 {
     CommandLineDialog.ProgressReporter reporter = new CommandLineDialog.ProgressReporter();
     reporter.maxProgressLines = maxProgressLines;
     // Call the reporter from the UI thread from this window.
     UpdateEvent += reporter.Update;
     // Connect the user's delegate to the reporter's completion method.
     reporter.Complete += completionDelegate;
     // Connect the caller's IoHandler delegate to the reporter.
     reporter.DataHandler += ioHandler;
     // Disconnect the reporter when the command completes.
     CommandLine.CompletionHandler reporterUpdateDisable =
         (CommandLine.Result unusedResult) => { this.UpdateEvent -= reporter.Update; };
     reporter.Complete += reporterUpdateDisable;
     PlayServicesResolver.Log(String.Format(
                                  "Executing command: {0} {1}", toolPath, arguments), level: LogLevel.Verbose);
     CommandLine.RunAsync(toolPath, arguments, reporter.CommandLineToolCompletion,
                          workingDirectory: workingDirectory, envVars: envVars,
                          ioHandler: reporter.AggregateLine);
 }