diff --git a/source/AndroidResolver/src/PlayServicesResolver.cs b/source/AndroidResolver/src/PlayServicesResolver.cs index bbfb5ead..74a011bb 100644 --- a/source/AndroidResolver/src/PlayServicesResolver.cs +++ b/source/AndroidResolver/src/PlayServicesResolver.cs @@ -18,6 +18,7 @@ namespace GooglePlayServices { using System; using System.Collections.Generic; using System.IO; + using System.Linq; using System.Text.RegularExpressions; using System.Threading; using System.Xml; @@ -1747,7 +1748,7 @@ private static void ScheduleResolve(bool forceResolution, bool closeWindowOnComp new ResolutionJob( isAutoResolveJob, () => { - ResolveUnsafeAfterJetifierCheck( + ResolveUnsafeAfterMainTemplateCheck( (success) => { SignalResolveJobComplete(() => { if (resolutionCompleteWithResult != null) { @@ -1763,6 +1764,72 @@ private static void ScheduleResolve(bool forceResolution, bool closeWindowOnComp if (firstJob) ExecuteNextResolveJob(); } + /// + /// Ensures that the mainTemplate.gradle and gradle.properties files are present in the project, + /// creating them via the Unity Editor's template files if needed. + /// + /// True if both files are present. + private static bool EnableGradleTemplates() { + return GradleTemplateResolver.EnsureGradleTemplateEnabled(GradleTemplateResolver.GradleTemplateFilename) && + GradleTemplateResolver.EnsureGradleTemplateEnabled(GradleTemplateResolver.GradlePropertiesTemplateFilename); + } + + /// + /// Resolve dependencies after checking if mainTemplate.gradle is enabled (or previously disabled). + /// + /// Delegate called when resolution is complete + /// with a parameter that indicates whether it succeeded or failed. + /// Whether resolution should be executed when no dependencies + /// have changed. This is useful if a dependency specifies a wildcard in the version + /// expression. + /// Whether this is an auto-resolution job. + /// Whether to unconditionally close the resolution + /// window when complete. + private static void ResolveUnsafeAfterMainTemplateCheck(Action resolutionComplete, + bool forceResolution, + bool isAutoResolveJob, + bool closeWindowOnCompletion) { + // If mainTemplate.gradle is already enabled, or if the user has rejected the switch, + // move to the next step. + if (GradleTemplateEnabled || + SettingsDialogObj.UserRejectedGradleUpgrade) { + ResolveUnsafeAfterJetifierCheck(resolutionComplete, forceResolution, isAutoResolveJob, closeWindowOnCompletion); + return; + } + + // Else, if there are no resolved files tracked by this (aka, it hasn't been run before), + // turn on mainTemplate, and log a message to the user. + // Or, if using Batch mode, we want to enable the templates as well, since that is now the + // desired default behavior. If Users want to preserve the old method, they can save their + // SettingsObject with the UserRejectedGradleUpgrade option enabled. + if (ExecutionEnvironment.InBatchMode || !PlayServicesResolver.FindLabeledAssets().Any()) { + EnableGradleTemplates(); + ResolveUnsafeAfterJetifierCheck(resolutionComplete, forceResolution, isAutoResolveJob, closeWindowOnCompletion); + return; + } + + // Else, prompt the user to turn it on for them. + DialogWindow.Display( + "Enable Android Gradle templates?", + "Android Resolver recommends using Gradle templates " + + "for managing Android dependencies. The old method of downloading " + + "the dependencies into Plugins/Android is no longer recommended.", + DialogWindow.Option.Selected0, "Enable", "Disable", + complete: (selectedOption) => { + switch (selectedOption) { + case DialogWindow.Option.Selected0: // Enable + EnableGradleTemplates(); + break; + case DialogWindow.Option.Selected1: // Disable + SettingsDialogObj.UserRejectedGradleUpgrade = true; + break; + } + + // Either way, proceed with the resolution. + ResolveUnsafeAfterJetifierCheck(resolutionComplete, forceResolution, isAutoResolveJob, closeWindowOnCompletion); + }); + } + /// /// Resolve dependencies after checking the configuration is compatible with the Jetifier /// settings. diff --git a/source/AndroidResolver/src/SettingsDialog.cs b/source/AndroidResolver/src/SettingsDialog.cs index 69a58143..33bea57d 100644 --- a/source/AndroidResolver/src/SettingsDialog.cs +++ b/source/AndroidResolver/src/SettingsDialog.cs @@ -48,6 +48,7 @@ private class Settings { internal bool autoResolutionDisabledWarning; internal bool promptBeforeAutoResolution; internal bool useProjectSettings; + internal bool userRejectedGradleUpgrade; internal EditorMeasurement.Settings analyticsSettings; /// @@ -72,6 +73,7 @@ internal Settings() { autoResolutionDisabledWarning = SettingsDialog.AutoResolutionDisabledWarning; promptBeforeAutoResolution = SettingsDialog.PromptBeforeAutoResolution; useProjectSettings = SettingsDialog.UseProjectSettings; + userRejectedGradleUpgrade = SettingsDialog.UserRejectedGradleUpgrade; analyticsSettings = new EditorMeasurement.Settings(PlayServicesResolver.analytics); } @@ -97,6 +99,7 @@ internal void Save() { SettingsDialog.AutoResolutionDisabledWarning = autoResolutionDisabledWarning; SettingsDialog.PromptBeforeAutoResolution = promptBeforeAutoResolution; SettingsDialog.UseProjectSettings = useProjectSettings; + SettingsDialog.UserRejectedGradleUpgrade = userRejectedGradleUpgrade; analyticsSettings.Save(); } } @@ -121,6 +124,7 @@ internal void Save() { private const string PromptBeforeAutoResolutionKey = Namespace + "PromptBeforeAutoResolution"; private const string UseGradleDaemonKey = Namespace + "UseGradleDaemon"; + private const string UserRejectedGradleUpgradeKey = Namespace + "UserRejectedGradleUpgrade"; // List of preference keys, used to restore default settings. private static string[] PreferenceKeys = new[] { @@ -140,7 +144,8 @@ internal void Save() { VerboseLoggingKey, AutoResolutionDisabledWarningKey, PromptBeforeAutoResolutionKey, - UseGradleDaemonKey + UseGradleDaemonKey, + UserRejectedGradleUpgradeKey }; internal const string AndroidPluginsDir = "Assets/Plugins/Android"; @@ -293,6 +298,11 @@ internal static bool VerboseLogging { get { return projectSettings.GetBool(VerboseLoggingKey, false); } } + internal static bool UserRejectedGradleUpgrade { + set { projectSettings.SetBool(UserRejectedGradleUpgradeKey, value); } + get { return projectSettings.GetBool(UserRejectedGradleUpgradeKey, false); } + } + internal static string ValidatePackageDir(string directory) { // Make sure the package directory starts with the same name. // This is case insensitive to handle cases where developers rename Unity @@ -507,6 +517,12 @@ public void OnGUI() { "builds when mixing legacy Android support libraries and Jetpack libraries."); } + GUILayout.BeginHorizontal(); + GUILayout.Label("Disable MainTemplate Gradle prompt", EditorStyles.boldLabel); + settings.userRejectedGradleUpgrade = + EditorGUILayout.Toggle(settings.userRejectedGradleUpgrade); + GUILayout.EndHorizontal(); + GUILayout.BeginHorizontal(); GUILayout.Label("Patch mainTemplate.gradle", EditorStyles.boldLabel); settings.patchMainTemplateGradle = @@ -697,7 +713,9 @@ public void OnGUI() { new KeyValuePair( "patchSettingsTemplateGradle", SettingsDialog.PatchSettingsTemplateGradle.ToString()), - + new KeyValuePair( + "userRejectedGradleUpgrade", + SettingsDialog.UserRejectedGradleUpgrade.ToString()), }, "Settings Save"); diff --git a/source/AndroidResolver/test/src/AndroidResolverIntegrationTests.cs b/source/AndroidResolver/test/src/AndroidResolverIntegrationTests.cs index c8d61ea9..cc7a6e66 100644 --- a/source/AndroidResolver/test/src/AndroidResolverIntegrationTests.cs +++ b/source/AndroidResolver/test/src/AndroidResolverIntegrationTests.cs @@ -642,6 +642,8 @@ private static void ClearAllDependencies() { GooglePlayServices.SettingsDialog.PatchPropertiesTemplateGradle = false; GooglePlayServices.SettingsDialog.PatchSettingsTemplateGradle = false; + GooglePlayServices.SettingsDialog.UserRejectedGradleUpgrade = true; + PlayServicesSupport.ResetDependencies(); UpdateAdditionalDependenciesFile(false, ADDITIONAL_DEPENDENCIES_FILENAME); UpdateAdditionalDependenciesFile(false, ADDITIONAL_DUPLICATE_DEPENDENCIES_FILENAME);