All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gms.googleservices.GoogleServicesPlugin.groovy Maven / Gradle / Ivy

There is a newer version: 3.1.1
Show newest version
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.gms.googleservices

import org.gradle.BuildListener;
import org.gradle.BuildResult;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.initialization.Settings;
import org.gradle.api.invocation.Gradle;
import org.gradle.api.GradleException
import org.gradle.api.Plugin
import org.gradle.api.Project

class GoogleServicesPlugin implements Plugin {

    public final static String JSON_FILE_NAME = 'google-services.json'

    public final static String MODULE_GROUP = "com.google.android.gms"
    public final static String MODULE_GROUP_FIREBASE = "com.google.firebase"
    public final static String MODULE_CORE = "firebase-core"
    public final static String MODULE_VERSION = "9.0.0"
    public final static String MINIMUM_VERSION = "9.0.0"

    private static String targetVersion;
    private static String targetVersionRaw;
    private final static enum PluginType{
      APPLICATION, LIBRARY, FEATURE
    }

    @Override
    void apply(Project project) {

        if (project.plugins.hasPlugin("android") ||
                project.plugins.hasPlugin("com.android.application")) {
            // this is a bit fragile but since this is internal usage this is ok
            // (another plugin could declare itself to be 'android')
            addDependency(project)
            setupPlugin(project, PluginType.APPLICATION)
            return
        }
        if (project.plugins.hasPlugin("android-library") ||
                project.plugins.hasPlugin("com.android.library")) {
            // this is a bit fragile but since this is internal usage this is ok
            // (another plugin could declare itself to be 'android-library')
            addDependency(project)
            setupPlugin(project, PluginType.LIBRARY)
            return
        }
        if (project.plugins.hasPlugin("android-feature") ||
                project.plugins.hasPlugin("com.android.feature")) {
            // this is a bit fragile but since this is internal usage this is ok
            // (another plugin could declare itself to be 'android-feature')
            addDependency(project)
            setupPlugin(project, PluginType.FEATURE)
            return
        }
        // If the google-service plugin is applied before any android plugin.
        // We should warn that google service plugin should be applied at
        // the bottom of build file.
        showWarningForPluginLocation(project)

        // Setup google-services plugin after android plugin is applied.
        project.plugins.withId("android", {
            setupPlugin(project, PluginType.APPLICATION)
        })
        project.plugins.withId("android-library", {
            setupPlugin(project, PluginType.LIBRARY)
        })
        project.plugins.withId("android-feature", {
            setupPlugin(project, PluginType.FEATURE)
        })

        // Add dependencies after the build file is evaluate and hopefully it
        // can be execute before android plugin process the dependencies.
        project.afterEvaluate({
            addDependency(project)
        })
    }

    private void showWarningForPluginLocation(Project project) {
        project.getLogger().warn(
            "please apply google-services plugin at the bottom of the build file.")
    }

    private boolean checkMinimumVersion() {
        String[] subTargetVersions = targetVersion.split("\\.")
        String[] subMinimumVersions = MINIMUM_VERSION.split("\\.")
        for (int i = 0; i < subTargetVersions.length && i < subMinimumVersions.length; i++) {
            Integer subTargetVersion = Integer.valueOf(subTargetVersions[i])
            Integer subMinimumVersion = Integer.valueOf(subMinimumVersions[i])
            if (subTargetVersion > subMinimumVersion) {
                return true;
            } else if (subTargetVersion < subMinimumVersion) {
                return false;
            }
        }
        return subTargetVersions.length >= subMinimumVersions.length;
    }

    private void addDependency(Project project) {
        // We need to preserve the original version number, even though we check using only what is before the
        // hyphen. This is because versions like 10.2.0-SNAPSHOT are valid versions.
        targetVersionRaw = findTargetVersion(project)
        targetVersion = targetVersionRaw.split("-")[0]
        if (checkMinimumVersion()) {
            // If the target version is not lower than the minimum version.
            project.dependencies.add('compile', MODULE_GROUP_FIREBASE + ':' + MODULE_CORE + ':' + targetVersionRaw)
        } else {
            throw new GradleException("Version: " + targetVersionRaw + " is lower than the minimum version (" +
                MINIMUM_VERSION + ") required for google-services plugin.")
        }
    }

    private String findTargetVersion(Project project) {
        def configurations = project.getConfigurations()
        if (configurations == null) return
        for (def configuration : configurations) {
            if (configuration == null) continue
            def dependencies = configuration.getDependencies()
            if (dependencies == null) continue
            for (def dependency : dependencies) {
                if (dependency == null) continue
                if (MODULE_GROUP.equalsIgnoreCase(dependency.getGroup()) ||
                    MODULE_GROUP_FIREBASE.equalsIgnoreCase(dependency.getGroup())) {
                    // Use the first version found in the dependencies.
                    return dependency.getVersion()
                }
            }
        }

        // If none of the version for Google play services is found, default
        // version is used and a warning that google-services plugin should be
        // applied at the bottom of the build file.
        project.getLogger().warn(
            "google-services plugin could not detect any version for " +
            MODULE_GROUP + " or " + MODULE_GROUP_FIREBASE +
            ", default version: " + MODULE_VERSION + " will be used.")
        showWarningForPluginLocation(project)
        // If no version is found, use the default one for the plugin.
        return MODULE_VERSION
    }


  private void setupPlugin(Project project, PluginType pluginType) {
      switch (pluginType) {
        case PluginType.APPLICATION:
          project.android.applicationVariants.all { variant ->
              handleVariant(project, variant)
          }
          break;
        case PluginType.LIBRARY:
          project.android.LibraryVariants.all { variant ->
              handleVariant(project, variant)
          }
          break;
        case PluginType.FEATURE:
          project.android.featureVariants.all { variant ->
              handleVariant(project, variant)
          }
          break;
        }
  }


    private static void handleVariant(Project project,
        def variant) {

        File quickstartFile = null

        String variantName = "$variant.dirName";
        String[] variantTokens = variantName.split('/')

        List fileLocation = new ArrayList<>()

        if (variantTokens.length == 2) {
            // If flavor and buildType are found.
            String flavorName = variantTokens[0]
            String buildType = variantTokens[1]
            fileLocation.add('src/' + flavorName + '/' + buildType)
            fileLocation.add('src/' + buildType + '/' + flavorName)
            fileLocation.add('src/' + flavorName)
            fileLocation.add('src/' + buildType)
            fileLocation.add('src/' + flavorName + buildType.capitalize())
        } else if (variantTokens.length == 1) {
            // If only buildType is found.
            fileLocation.add('src/' + variantTokens[0])
        }

        String searchedLocation = System.lineSeparator()
        for (String location : fileLocation) {
            File jsonFile = project.file(location + '/' + JSON_FILE_NAME)
            searchedLocation = searchedLocation + jsonFile.getPath() + System.lineSeparator()
            if (jsonFile.isFile()) {
                quickstartFile = jsonFile
                break
            }
        }

        if (quickstartFile == null) {
            quickstartFile = project.file(JSON_FILE_NAME)
            searchedLocation = searchedLocation + quickstartFile.getPath()
        }

        File outputDir =
          project.file("$project.buildDir/generated/res/google-services/$variant.dirName")

        GoogleServicesTask task = project.tasks
          .create("process${variant.name.capitalize()}GoogleServices",
          GoogleServicesTask)

        task.quickstartFile = quickstartFile
        task.intermediateDir = outputDir
        task.packageName = variant.applicationId
        task.moduleGroup = MODULE_GROUP
        task.moduleGroupFirebase = MODULE_GROUP_FIREBASE
        // Use the target version for the task.
        task.moduleVersion = targetVersionRaw;
        variant.registerResGeneratingTask(task, outputDir)
        task.searchedLocation = searchedLocation
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy