/// <summary> /// Initializes the <see cref="GooglePlayServices.PlayServicesResolver"/> class. /// </summary> static PlayServicesResolver() { svcSupport = PlayServicesSupport.CreateInstance( "PlayServicesResolver", EditorPrefs.GetString("AndroidSdkRoot"), "ProjectSettings"); }
/// <summary> /// Initializes the <see cref="GooglePlayGames.BackgroundResolution"/> class. /// </summary> static BackgroundResolution() { svcSupport = PlayServicesSupport.CreateInstance( "Google.GPGS", EditorPrefs.GetString("AndroidSdkRoot"), "ProjectSettings"); AddDependencies(); }
/// <summary> /// Initializes static members of the <see cref="SampleDependencies"/> class. /// </summary> static GPGSDependencies() { svcSupport = PlayServicesSupport.CreateInstance( PluginName, EditorPrefs.GetString("AndroidSdkRoot"), "ProjectSettings"); RegisterDependencies(); }
/// <summary> /// Initializes static members of the <see cref="FuseSDKDependencies"/> class. /// </summary> static FuseSDKDependencies() { svcSupport = PlayServicesSupport.CreateInstance(PluginName, EditorPrefs.GetString("AndroidSdkRoot"), "ProjectSettings"); svcSupport.ClearDependencies(); svcSupport.DependOn("com.google.android.gms", "play-services-basement", "8.4.0"); svcSupport.DependOn("com.android.support", "support-annotations", "23.4.0"); svcSupport.DependOn("com.android.support", "support-v4", "23.4.0"); svcSupport.DependOn("com.android.support", "recyclerview-v7", "23.4.0"); }
/// <summary> /// Initializes the <see cref="GooglePlayServices.PlayServicesResolver"/> class. /// </summary> static PlayServicesResolver() { svcSupport = PlayServicesSupport.CreateInstance( "PlayServicesResolver", EditorPrefs.GetString("AndroidSdkRoot"), "ProjectSettings", logger: UnityEngine.Debug.Log); EditorApplication.update -= AutoResolve; EditorApplication.update += AutoResolve; EditorApplication.update -= PollBundleId; EditorApplication.update += PollBundleId; }
/// <summary> /// Perform the resolution and the exploding/cleanup as needed. /// </summary> public override void DoResolution(PlayServicesSupport svcSupport, string destinationDirectory, PlayServicesSupport.OverwriteConfirmation handleOverwriteConfirmation) { // Get the collection of dependencies that need to be copied. Dictionary<string, Dependency> deps = svcSupport.ResolveDependencies(true); // Copy the list svcSupport.CopyDependencies(deps, destinationDirectory, handleOverwriteConfirmation); // we want to look at all the .aars to decide to explode or not. // Some aars have variables in their AndroidManifest.xml file, // e.g. ${applicationId}. Unity does not understand how to process // these, so we handle it here. ProcessAars(destinationDirectory); }
/// <summary> /// Creates an instance of PlayServicesSupport. This instance is /// used to add dependencies for the calling client and invoke the resolution. /// </summary> /// <returns>The instance.</returns> /// <param name="clientName">Client name. Must be a valid filename. /// This is used to uniquely identify /// the calling client so that dependencies can be associated with a specific /// client to help in resetting dependencies.</param> /// <param name="sdkPath">Sdk path for Android SDK.</param> /// <param name="additionalRepositories">Array of additional repository paths. can be /// null</param> /// <param name="settingsDirectory">This parameter is obsolete.</param> /// <param name="logger">Delegate used to write messages to the log.</param> internal static PlayServicesSupport CreateInstance( string clientName, string sdkPath, string[] additionalRepositories, string settingsDirectory, LogMessage logger = null) { PlayServicesSupport instance = new PlayServicesSupport(); PlayServicesSupport.logger = PlayServicesSupport.logger ?? logger; PlayServicesSupport.sdk = String.IsNullOrEmpty(sdkPath) ? PlayServicesSupport.sdk : sdkPath; string badchars = new string(Path.GetInvalidFileNameChars()); foreach (char ch in clientName) { if (badchars.IndexOf(ch) >= 0) { throw new Exception("Invalid clientName: " + clientName); } } instance.clientName = clientName; var repoPaths = new List <string>(); repoPaths.AddRange(additionalRepositories ?? new string[] {}); // Add the standard repo paths from the Android SDK string sdkExtrasDir = Path.Combine(SdkVariable, "extras"); repoPaths.AddRange( new string [] { Path.Combine(sdkExtrasDir, Path.Combine("android", "m2repository")), Path.Combine(sdkExtrasDir, Path.Combine("google", "m2repository")) }); instance.repositoryPaths = UniqueList(repoPaths); instances[instance.clientName] = instance; return(instance); }
/// <summary> /// Creates an instance of PlayServicesSupport. This instance is /// used to add dependencies for the calling client and invoke the resolution. /// </summary> /// <returns>The instance.</returns> /// <param name="clientName">Client name. Must be a valid filename. /// This is used to uniquely identify /// the calling client so that dependencies can be associated with a specific /// client to help in resetting dependencies.</param> /// <param name="sdkPath">Sdk path for Android SDK.</param> /// <param name="settingsDirectory">The relative path to the directory /// to save the settings. For Unity projects this is "ProjectSettings"</param> public static PlayServicesSupport CreateInstance( string clientName, string sdkPath, string settingsDirectory) { PlayServicesSupport instance = new PlayServicesSupport(); instance.sdk = sdkPath; string badchars = new string(Path.GetInvalidFileNameChars()); foreach (char ch in clientName) { if (badchars.IndexOf(ch) >= 0) { throw new Exception("Invalid clientName: " + clientName); } } instance.clientName = clientName; instance.settingsDirectory = settingsDirectory; instance.clientDependenciesMap = instance.LoadDependencies(false); return(instance); }
/// <summary> /// Creates an instance of PlayServicesSupport. This instance is /// used to add dependencies for the calling client and invoke the resolution. /// </summary> /// <returns>The instance.</returns> /// <param name="clientName">Client name. Must be a valid filename. /// This is used to uniquely identify /// the calling client so that dependencies can be associated with a specific /// client to help in resetting dependencies.</param> /// <param name="sdkPath">Sdk path for Android SDK.</param> /// <param name="additionalRepositories">Array of additional repository paths. can be null</param> /// <param name="settingsDirectory">The relative path to the directory /// to save the settings. For Unity projects this is "ProjectSettings"</param> internal static PlayServicesSupport CreateInstance( string clientName, string sdkPath, string[] additionalRepositories, string settingsDirectory) { PlayServicesSupport instance = new PlayServicesSupport(); instance.sdk = sdkPath; string badchars = new string(Path.GetInvalidFileNameChars()); foreach (char ch in clientName) { if (badchars.IndexOf(ch) >= 0) { throw new Exception("Invalid clientName: " + clientName); } } instance.clientName = clientName; instance.settingsDirectory = settingsDirectory; // Add the standard repo paths from the Android SDK string sdkExtrasDir = Path.Combine("$SDK", "extras"); instance.repositoryPaths.Add(Path.Combine(sdkExtrasDir, Path.Combine("android", "m2repository"))); instance.repositoryPaths.Add(Path.Combine(sdkExtrasDir, Path.Combine("google", "m2repository"))); if (additionalRepositories != null) { instance.repositoryPaths.AddRange(additionalRepositories); } instance.clientDependenciesMap = instance.LoadDependencies(false); return(instance); }
/// <summary> /// Creates an instance of PlayServicesSupport. This instance is /// used to add dependencies for the calling client and invoke the resolution. /// </summary> /// <returns>The instance.</returns> /// <param name="clientName">Client name. Must be a valid filename. /// This is used to uniquely identify /// the calling client so that dependencies can be associated with a specific /// client to help in resetting dependencies.</param> /// <param name="sdkPath">Sdk path for Android SDK.</param> /// <param name="additionalRepositories">Array of additional repository paths. can be null</param> /// <param name="settingsDirectory">The relative path to the directory /// to save the settings. For Unity projects this is "ProjectSettings"</param> /// <param name="logger">Delegate used to write messages to the log.</param> internal static PlayServicesSupport CreateInstance( string clientName, string sdkPath, string[] additionalRepositories, string settingsDirectory, LogMessage logger = null) { PlayServicesSupport instance = new PlayServicesSupport(); instance.logger = logger; instance.sdk = sdkPath; string badchars = new string(Path.GetInvalidFileNameChars()); foreach (char ch in clientName) { if (badchars.IndexOf(ch) >= 0) { throw new Exception("Invalid clientName: " + clientName); } } instance.clientName = clientName; instance.settingsDirectory = settingsDirectory; // Add the standard repo paths from the Android SDK string sdkExtrasDir = Path.Combine("$SDK", "extras"); instance.repositoryPaths[ Path.Combine(sdkExtrasDir, Path.Combine("android","m2repository"))] = true; instance.repositoryPaths[ Path.Combine(sdkExtrasDir, Path.Combine("google","m2repository"))] = true; foreach (string repo in additionalRepositories ?? new string[] {}) { instance.repositoryPaths[repo] = true; } instance.clientDependenciesMap = instance.LoadDependencies(false, true); return instance; }
/// <summary> /// Compatibility method for synchronous implementations of DoResolution(). /// </summary> /// <param name="svcSupport">Svc support.</param> /// <param name="destinationDirectory">Destination directory.</param> /// <param name="handleOverwriteConfirmation">Handle overwrite confirmation.</param> public abstract void DoResolution( PlayServicesSupport svcSupport, string destinationDirectory, PlayServicesSupport.OverwriteConfirmation handleOverwriteConfirmation);
/// <summary> /// Does the resolution of the play-services aars. /// </summary> /// <param name="svcSupport">Svc support.</param> /// <param name="destinationDirectory">Destination directory.</param> /// <param name="handleOverwriteConfirmation">Handle overwrite confirmation.</param> /// <param name="resolutionComplete">Delegate called when resolution is complete.</param> public virtual void DoResolution( PlayServicesSupport svcSupport, string destinationDirectory, PlayServicesSupport.OverwriteConfirmation handleOverwriteConfirmation, System.Action resolutionComplete) { DoResolution(svcSupport, destinationDirectory, handleOverwriteConfirmation); resolutionComplete(); }
/// <summary> /// Find a tool in the Android SDK. /// </summary> /// <param name="svcSupport">PlayServicesSupport instance used to retrieve the SDK /// path. </param> /// <param name="toolName">Name of the tool to search for.</param> /// <returns>String with the path to the tool if found, null otherwise.</returns> internal static string FindAndroidSdkTool(PlayServicesSupport svcSupport, string toolName) { string toolPath = null; string sdkPath = svcSupport.SDK; if (sdkPath == null || sdkPath == "") { Debug.LogWarning(PlayServicesSupport.AndroidSdkConfigurationError + " Will fallback to searching for " + toolName + " in the system path."); } else { toolPath = Path.Combine( sdkPath, Path.Combine( "tools", toolName + CommandLine.GetExecutableExtension())); } if (toolPath == null || !File.Exists(toolPath)) { toolPath = CommandLine.FindExecutable(toolName); } return toolPath; }
/// <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> /// Initializes the <see cref="GooglePlayServices.PlayServicesResolver"/> class. /// </summary> static PlayServicesResolver() { if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android) { svcSupport = PlayServicesSupport.CreateInstance( "PlayServicesResolver", EditorPrefs.GetString("AndroidSdkRoot"), "ProjectSettings", logger: UnityEngine.Debug.Log); EditorApplication.update -= AutoResolve; EditorApplication.update += AutoResolve; BundleIdChanged -= ResolveOnBundleIdChanged; BundleIdChanged += ResolveOnBundleIdChanged; } EditorApplication.update -= PollBundleId; EditorApplication.update += PollBundleId; }
/// <summary> /// Perform resolution with no Android package dependency checks. /// </summary> private void DoResolutionNoAndroidPackageChecks( PlayServicesSupport svcSupport, string destinationDirectory, PlayServicesSupport.OverwriteConfirmation handleOverwriteConfirmation) { try { // Get the collection of dependencies that need to be copied. Dictionary<string, Dependency> deps = svcSupport.ResolveDependencies(true); // Copy the list svcSupport.CopyDependencies(deps, destinationDirectory, handleOverwriteConfirmation); } catch (Google.JarResolver.ResolutionException e) { Debug.LogError(e.ToString()); return; } // we want to look at all the .aars to decide to explode or not. // Some aars have variables in their AndroidManifest.xml file, // e.g. ${applicationId}. Unity does not understand how to process // these, so we handle it here. ProcessAars(destinationDirectory); SaveAarExplodeCache(); }
public override void DoResolution( PlayServicesSupport svcSupport, string destinationDirectory, PlayServicesSupport.OverwriteConfirmation handleOverwriteConfirmation) { DoResolution(svcSupport, destinationDirectory, handleOverwriteConfirmation, () => {}); }
/// <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); }); }