// public event CommandLineDialog.UpdateDelegate UpdateEvent // { // add // { // CommandLineDialog.UpdateDelegate updateDelegate = this.UpdateEvent; // CommandLineDialog.UpdateDelegate updateDelegate2; // do // { // updateDelegate2 = updateDelegate; // updateDelegate = Interlocked.CompareExchange<CommandLineDialog.UpdateDelegate>(ref this.UpdateEvent, (CommandLineDialog.UpdateDelegate)Delegate.Combine(updateDelegate2, value), updateDelegate); // } // while (updateDelegate != updateDelegate2); // } // remove // { // CommandLineDialog.UpdateDelegate updateDelegate = this.UpdateEvent; // CommandLineDialog.UpdateDelegate updateDelegate2; // do // { // updateDelegate2 = updateDelegate; // updateDelegate = Interlocked.CompareExchange<CommandLineDialog.UpdateDelegate>(ref this.UpdateEvent, (CommandLineDialog.UpdateDelegate)Delegate.Remove(updateDelegate2, value), updateDelegate); // } // while (updateDelegate != updateDelegate2); // } // } public static CommandLineDialog CreateCommandLineDialog(string title) { CommandLineDialog commandLineDialog = (!ExecutionEnvironment.InBatchMode) ? ((CommandLineDialog)EditorWindow.GetWindow(typeof(CommandLineDialog), true, title)) : new CommandLineDialog(); commandLineDialog.Initialize(); return(commandLineDialog); }
/// <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); window.progressTitle = window.summaryText; 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) => { window.Close(); LogInstallLicenseResult(toolPath, toolArguments, retrievingLicenses, packages, result); complete(result); }, ioHandler: ioHandler, maxProgressLines: retrievingLicenses ? 250 : 500); window.Show(); }
/// <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; window.progressTitle = window.summaryText; window.autoScrollToBottom = true; window.RunAsync( toolPath, toolArguments, (CommandLine.Result result) => { window.Close(); if (result.exitCode != 0) { PlayServicesResolver.Log(String.Format(PACKAGES_MISSING, result.message)); } complete(result); }, maxProgressLines: 50); window.Show(); }
// Handles the platform specific differences of executing the generate gradle script, and // creating the dialog responsible for showing the progress of the execution. // Any errors are reported to the console as well. /// <param name="args">Arguments to be passed to the generate gradle script tool.</param> private static void RunGenGradleScript(string args) { // b/35663224 Combine execute-python-exe which handles the windows logic. bool onWindows = UnityEngine.Application.platform == UnityEngine.RuntimePlatform.WindowsEditor; string command = "\"" + Path.Combine(GRADLE_SCRIPT_LOCATION, onWindows ? GENERATE_GRADLE_EXE_WINDOWS : GENERATE_GRADLE_EXE_GENERIC) + "\""; if (!onWindows) { args = command + args; command = CommandLine.FindExecutable("python"); } CommandLineDialog window = CommandLineDialog.CreateCommandLineDialog( "Resolving Jars."); window.modal = false; window.summaryText = "Generating and running Gradle prebuild."; window.progressTitle = window.summaryText; window.autoScrollToBottom = true; window.RunAsync( command, args, (result) => { if (result.exitCode != 0) { Debug.LogError("Error somewhere in the process of creating the gradle build, " + "executing it, and copying the outputs.\n" + "This will break dependency resolution and your build will not run.\n" + "See the output below for possible gradle build errors. The most likely " + "cases are: an invalid bundleID (which you can correct in the Android " + "Player Settings), or a failure to determine the Android SDK platform " + "and build tools verison (you can verify that you have a valid android " + "SDK path in the Unity preferences.\n" + "If you're not able to diagnose the error, please report a bug at: " + "https://github.com/googlesamples/unity-jar-resolver/issues" + "A possible work-around is to turn off the " + "\"Gradle Prebuild\" from the Jar Resolver Settings.\n\n" + "Error (" + result.exitCode + "):\n" + result.stdout + result.stderr); window.bodyText += "\n\nResolution Failed."; } else { window.bodyText += "\n\nResolution Complete."; } window.noText = "Close"; // After adding the button we need to scroll down a little more. window.scrollPosition.y = Mathf.Infinity; window.Repaint(); window.buttonClicked = (TextAreaDialog dialog) => { if (!dialog.result) { window.Close(); } }; }, maxProgressLines: 50); window.Show(); }
/// <summary> /// Create a dialog box which can display command line output. /// </summary> /// <returns>Reference to the new window.</returns> public static CommandLineDialog CreateCommandLineDialog(string title) { CommandLineDialog window = (CommandLineDialog)EditorWindow.GetWindow( typeof(CommandLineDialog), true, title); window.Initialize(); return(window); }
/// <summary> /// Create a dialog box which can display command line output. /// </summary> /// <returns>Reference to the new window.</returns> public static CommandLineDialog CreateCommandLineDialog(string title) { // In batch mode we simply create the class without instancing the visible window. CommandLineDialog window = ExecutionEnvironment.InBatchMode ? new CommandLineDialog() : (CommandLineDialog)EditorWindow.GetWindow( typeof(CommandLineDialog), true, title); window.Initialize(); return(window); }
/// <summary> /// Get the set of available SDK packages and whether they're installed. /// </summary> /// <param name="androidTool">Path to the Android SDK manager tool.</param> /// <param name="svcSupport">PlayServicesSupport instance used to retrieve the SDK /// path.</param> /// <param name="packages">Delegate called with a dictionary of package names and whether /// they're installed or null if the Android SDK isn't configured correctly.</param> internal static void GetAvailablePackages( string androidTool, PlayServicesSupport svcSupport, GetAvailablePackagesComplete complete) { CommandLineDialog window = CommandLineDialog.CreateCommandLineDialog( "Get Installed Android SDK packages."); window.modal = false; window.summaryText = "Getting list of installed Android packages."; window.progressTitle = window.summaryText; window.autoScrollToBottom = true; window.RunAsync( androidTool, "list sdk -u -e -a", (result) => { window.Close(); if (result.exitCode != 0) { Debug.LogError("Unable to determine which Android packages are " + "installed. Failed to run " + androidTool + ". " + result.stderr + " (" + result.exitCode.ToString() + ")"); complete(null); return; } Dictionary <string, bool> packages = new Dictionary <string, bool>(); string[] lines = Regex.Split(result.stdout, "\r\n|\r|\n"); string packageIdentifier = null; foreach (string line in lines) { // Find the start of a package description. Match match = Regex.Match(line, "^id:\\W+\\d+\\W+or\\W+\"([^\"]+)\""); if (match.Success) { packageIdentifier = match.Groups[1].Value; packages[packageIdentifier] = false; continue; } if (packageIdentifier == null) { continue; } // Parse the install path and record whether the package is installed. match = Regex.Match(line, "^\\W+Install[^:]+:\\W+([^ ]+)"); if (match.Success) { packages[packageIdentifier] = File.Exists( Path.Combine(Path.Combine(svcSupport.SDK, match.Groups[1].Value), "source.properties")); packageIdentifier = null; } } complete(packages); }, maxProgressLines: 50); window.Show(); }
/// <summary> /// Called from CommandLineDialog in the context of the main / UI thread. /// </summary> public void Update(CommandLineDialog window) { if (textQueue.Count > 0) { List <string> textList = new List <string>(); while (textQueue.Count > 0) { textList.Add((string)textQueue.Dequeue()); } string bodyText = window.bodyText + String.Join("", textList.ToArray()); // Really weak handling of carriage returns. Truncates to the previous // line for each newline detected. while (true) { // Really weak handling carriage returns for progress style updates. int carriageReturn = bodyText.LastIndexOf("\r"); if (carriageReturn < 0 || bodyText.Substring(carriageReturn, 1) == "\n") { break; } string bodyTextHead = ""; int previousNewline = bodyText.LastIndexOf("\n", carriageReturn, carriageReturn); if (previousNewline >= 0) { bodyTextHead = bodyText.Substring(0, previousNewline + 1); } bodyText = bodyTextHead + bodyText.Substring(carriageReturn + 1); } window.bodyText = bodyText; if (window.autoScrollToBottom) { window.scrollPosition.y = Mathf.Infinity; } window.Repaint(); } if (maxProgressLines > 0) { window.progress = (float)linesReported / (float)maxProgressLines; } if (result != null) { window.progressTitle = ""; if (Complete != null) { Complete(result); Complete = null; } } }
public void Update(CommandLineDialog window) { if (this.textQueue.Count > 0) { List <string> list = new List <string>(); while (this.textQueue.Count > 0) { list.Add((string)this.textQueue.Dequeue()); } string text = window.bodyText + string.Join(string.Empty, list.ToArray()); while (true) { int num = text.LastIndexOf("\r"); if (num < 0 || text.Substring(num, 1) == "\n") { break; } string str = string.Empty; int num2 = text.LastIndexOf("\n", num, num); if (num2 >= 0) { str = text.Substring(0, num2 + 1); } text = str + text.Substring(num + 1); } window.bodyText = text; if (window.autoScrollToBottom) { window.scrollPosition.y = float.PositiveInfinity; } window.Repaint(); } if (this.maxProgressLines > 0) { window.progress = (float)this.linesReported / (float)this.maxProgressLines; } if (this.result != null) { window.progressTitle = string.Empty; this.SignalComplete(); } }
/// <summary> /// Display license dialog. /// </summary> /// <param name="licenses">String containing the licenses to display.</param> /// <param name="complete">Called when the user agrees / disagrees to the licenses.</param> private static void DisplayLicensesDialog(string licenses, Action <bool> complete) { var window = CommandLineDialog.CreateCommandLineDialog(DIALOG_TITLE); window.summaryText = "License agreement(s) required to install Android SDK packages"; window.modal = false; window.bodyText = licenses; window.yesText = "agree"; window.noText = "decline"; window.result = false; window.Repaint(); window.buttonClicked = (TextAreaDialog dialog) => { window.Close(); if (!dialog.result) { complete(false); return; } complete(true); }; window.Show(); }
/// <summary> /// Called from CommandLineDialog in the context of the main / UI thread. /// </summary> public void Update(CommandLineDialog window) { if (textQueue.Count > 0) { List<string> textList = new List<string>(); while (textQueue.Count > 0) textList.Add((string)textQueue.Dequeue()); string bodyText = window.bodyText + String.Join("", textList.ToArray()); // Really weak handling of carriage returns. Truncates to the previous // line for each newline detected. while (true) { // Really weak handling carriage returns for progress style updates. int carriageReturn = bodyText.LastIndexOf("\r"); if (carriageReturn < 0 || bodyText.Substring(carriageReturn, 1) == "\n") { break; } string bodyTextHead = ""; int previousNewline = bodyText.LastIndexOf("\n", carriageReturn, carriageReturn); if (previousNewline >= 0) { bodyTextHead = bodyText.Substring(0, previousNewline + 1); } bodyText = bodyTextHead + bodyText.Substring(carriageReturn + 1); } window.bodyText = bodyText; if (window.autoScrollToBottom) { window.scrollPosition.y = Mathf.Infinity; } window.Repaint(); } if (maxProgressLines > 0) { window.progress = (float)linesReported / (float)maxProgressLines; } if (result != null) { window.progressTitle = ""; if (Complete != null) { Complete(result); Complete = null; } } }
/// <summary> /// Perform the resolution and the exploding/cleanup as needed. /// </summary> public override void DoResolution( PlayServicesSupport svcSupport, string destinationDirectory, PlayServicesSupport.OverwriteConfirmation handleOverwriteConfirmation, System.Action resolutionComplete) { System.Action resolve = () => { DoResolutionNoAndroidPackageChecks(svcSupport, destinationDirectory, handleOverwriteConfirmation); resolutionComplete(); }; // Set of packages that need to be installed. Dictionary <string, bool> installPackages = new Dictionary <string, bool>(); // Retrieve the set of required packages and whether they're installed. Dictionary <string, Dictionary <string, bool> > requiredPackages = new Dictionary <string, Dictionary <string, bool> >(); foreach (Dependency dependency in svcSupport.LoadDependencies(true, keepMissing: true).Values) { if (dependency.PackageIds != null) { foreach (string packageId in dependency.PackageIds) { Dictionary <string, bool> dependencySet; if (!requiredPackages.TryGetValue(packageId, out dependencySet)) { dependencySet = new Dictionary <string, bool>(); } dependencySet[dependency.Key] = false; requiredPackages[packageId] = dependencySet; // If the dependency is missing, add it to the set that needs to be // installed. if (System.String.IsNullOrEmpty(dependency.BestVersionPath)) { installPackages[packageId] = false; } } } } // If no packages need to be installed or Android SDK package installation is disabled. if (installPackages.Count == 0 || !AndroidPackageInstallationEnabled()) { // Report missing packages as warnings and try to resolve anyway. foreach (string pkg in requiredPackages.Keys) { string depString = System.String.Join( ", ", CollectionToArray(requiredPackages[pkg].Keys)); if (installPackages.ContainsKey(pkg) && depString.Length > 0) { Debug.LogWarning(pkg + " not installed or out of date! This is " + "required by the following dependencies " + depString); } } // Attempt resolution. resolve(); return; } // Find the Android SDK manager. string sdkPath = svcSupport.SDK; string androidTool = FindAndroidSdkTool(svcSupport, "android"); if (androidTool == null || sdkPath == null || sdkPath == "") { Debug.LogError("Unable to find the Android SDK manager tool. " + "Required Android packages (" + System.String.Join(", ", CollectionToArray(installPackages.Keys)) + ") can not be installed. " + PlayServicesSupport.AndroidSdkConfigurationError); return; } // Get the set of available and installed packages. GetAvailablePackages( androidTool, svcSupport, (Dictionary <string, bool> packageInfo) => { if (packageInfo == null) { return; } // Filter the set of packages to install by what is available. foreach (string pkg in requiredPackages.Keys) { bool installed = false; string depString = System.String.Join( ", ", CollectionToArray(requiredPackages[pkg].Keys)); if (packageInfo.TryGetValue(pkg, out installed)) { if (!installed) { installPackages[pkg] = false; Debug.LogWarning(pkg + " not installed or out of date! " + "This is required by the following " + "dependencies " + depString); } } else { Debug.LogWarning(pkg + " referenced by " + depString + " not available in the Android SDK. This " + "package will not be installed."); installPackages.Remove(pkg); } } if (installPackages.Count == 0) { resolve(); return; } // Start installation. string installPackagesString = System.String.Join( ",", CollectionToArray(installPackages.Keys)); string packagesCommand = "update sdk -a -u -t " + installPackagesString; CommandLineDialog window = CommandLineDialog.CreateCommandLineDialog( "Install Android SDK packages"); window.summaryText = "Retrieving licenses..."; window.modal = false; window.progressTitle = window.summaryText; window.RunAsync( androidTool, packagesCommand, (CommandLine.Result getLicensesResult) => { // Get the start of the license text. int licenseTextStart = getLicensesResult.stdout.IndexOf("--------"); if (getLicensesResult.exitCode != 0 || licenseTextStart < 0) { window.Close(); Debug.LogError("Unable to retrieve licenses for packages " + installPackagesString); return; } // Remove the download output from the string. string licenseText = getLicensesResult.stdout.Substring( licenseTextStart); window.summaryText = ("License agreement(s) required to install " + "Android SDK packages"); window.bodyText = licenseText; window.yesText = "agree"; window.noText = "decline"; window.result = false; window.Repaint(); window.buttonClicked = (TextAreaDialog dialog) => { if (!dialog.result) { window.Close(); return; } window.summaryText = "Installing Android SDK packages..."; window.bodyText = ""; window.yesText = ""; window.noText = ""; window.buttonClicked = null; window.progressTitle = window.summaryText; window.autoScrollToBottom = true; window.Repaint(); // Kick off installation. ((CommandLineDialog)window).RunAsync( androidTool, packagesCommand, (CommandLine.Result updateResult) => { window.Close(); if (updateResult.exitCode == 0) { resolve(); } else { Debug.LogError("Android SDK update failed. " + updateResult.stderr + "(" + updateResult.exitCode.ToString() + ")"); } }, ioHandler: (new LicenseResponder(true)).AggregateLine, maxProgressLines: 500); }; }, ioHandler: (new LicenseResponder(false)).AggregateLine, maxProgressLines: 250); }); }