static void EnsureMinSdkVersion()
        {
            var arcoreSettings = ARCoreSettings.GetOrCreateSettings();
            var minSdkVersion  = arcoreSettings.requirement == ARCoreSettings.Requirement.Optional ? 14 : 24;

            if ((int)PlayerSettings.Android.minSdkVersion < minSdkVersion)
            {
                throw new BuildFailedException($"ARCore {arcoreSettings.requirement} apps require a minimum SDK version of {minSdkVersion}. Currently set to {PlayerSettings.Android.minSdkVersion}");
            }
        }
        static void EnsureGradleVersionIsSupported()
        {
            var settings = ARCoreSettings.GetOrCreateSettings();

            if (settings.ignoreGradleVersion)
            {
                return;
            }

            if (Gradle.TryGetVersion(out var gradleVersion, out var diagnosticMessage))
            {
                if (gradleVersion < k_MinimumGradleVersion)
                {
                    var errorMessage = $"ARCore requires at least Gradle version {k_MinimumGradleVersion} ({gradleVersion} detected). Visit https://developers.google.com/ar/develop/unity/android-11-build for further details.";
                    var selection    = EditorUtility.DisplayDialogComplex(
                        "Gradle update required",
                        errorMessage,
                        "Cancel build", "Continue anyway", "Continue and don't warn me again");

                    switch (selection)
                    {
                    // Cancel the build
                    case 0: throw new BuildFailedException(errorMessage);

                    // Continue as normal
                    case 1: break;

                    // Continue, and never ask again
                    case 2:
                    {
                        if (ARCoreSettings.currentSettings == null)
                        {
                            var shouldCreateSettingsProvider = EditorUtility.DisplayDialog("Create ARCoreSettings Asset",
                                                                                           "In order to remember this setting, you must create an ARCoreSettings asset in Edit > Project Settings > XR > ARCore",
                                                                                           "Create", "Cancel");

                            if (shouldCreateSettingsProvider)
                            {
                                ARCoreSettingsProvider.Create();
                                settings = ARCoreSettings.GetOrCreateSettings();
                            }
                        }

                        settings.ignoreGradleVersion = true;

                        break;
                    }
                    }
                }
            }
            else
            {
                Debug.LogWarning($"ARCore requires Gradle {k_MinimumGradleVersion} or later. The Gradle version could not be determined because \"{diagnosticMessage}\"");
            }
        }
        // This ensures the Android Manifest corresponds to
        // https://developers.google.com/ar/develop/java/enable-arcore
        public void OnPostGenerateGradleAndroidProject(string path)
        {
            if (!ARCorePreprocessBuild.isARCoreLoaderEnabled)
            {
                return;
            }

            string manifestPath = path + k_AndroidManifestPath;
            var    manifestDoc  = new XmlDocument();

            manifestDoc.Load(manifestPath);

            var manifestNode = FindFirstChild(manifestDoc, "manifest");

            if (manifestNode == null)
            {
                return;
            }

            var applicationNode = FindFirstChild(manifestNode, "application");

            if (applicationNode == null)
            {
                return;
            }

            FindOrCreateTagWithAttribute(manifestDoc, manifestNode, "uses-permission", "name", k_AndroidPermissionCamera);
            FindOrCreateTagWithAttributes(manifestDoc, applicationNode, "meta-data", "name", "unityplayer.SkipPermissionsDialog", "value", "true");

            var settings = ARCoreSettings.GetOrCreateSettings();

            if (settings.requirement == ARCoreSettings.Requirement.Optional)
            {
                FindOrCreateTagWithAttributes(manifestDoc, applicationNode, "meta-data", "name", k_AndroidNameValue, "value", "optional");
            }
            else if (settings.requirement == ARCoreSettings.Requirement.Required)
            {
                FindOrCreateTagWithAttributes(manifestDoc, manifestNode, "uses-feature", "name", k_AndroidHardwareCameraAr, "required", "true");
                FindOrCreateTagWithAttributes(manifestDoc, applicationNode, "meta-data", "name", k_AndroidNameValue, "value", "required");
            }

            if (settings.depth == ARCoreSettings.Requirement.Required)
            {
                FindOrCreateTagWithAttributes(manifestDoc, manifestNode, "uses-feature", "name", k_AndroidDepth, "required", "true");
            }
            manifestDoc.Save(manifestPath);
        }
        void EnsureMinSdkVersion()
        {
            var arcoreSettings = ARCoreSettings.GetOrCreateSettings();
            int minSdkVersion;

            if (arcoreSettings.requirement == ARCoreSettings.Requirement.Optional)
            {
                minSdkVersion = 14;
            }
            else
            {
                minSdkVersion = 24;
            }

            if ((int)PlayerSettings.Android.minSdkVersion < minSdkVersion)
            {
                throw new BuildFailedException(string.Format("ARCore {0} apps require a minimum SDK version of {1}. Currently set to {2}",
                                                             arcoreSettings.requirement, minSdkVersion, PlayerSettings.Android.minSdkVersion));
            }
        }