Gradle Android Plugin – add custom flavor attribute?-ThrowExceptions

Exception or error:

Is there any way to add custom attributes to productFlavor or buildType in android plugin for gradle?
I’d like to have such additional flexibility in configuration of buildVariants, so that I can check my custom property when specifying tasks for buildVariants.

productFlavors {
    flavorGroups "drm", "storeType"
    googlePlay {
        flavorGroup "storeType"
        buildConfig "public static final String TARGET_STORE = \"google\";"
    }
    samsungApps {
        flavorGroup "storeType"
        buildConfig "public static final String TARGET_STORE = \"samsung\";"
    }

    platformDrm {
        flavorGroup "drm"
    }

    widevineAppDrm {
        flavorGroup "drm"
        minSdkVersion 9
        useWidevineAppDrmLib true
    }

}

so here you can see I’ve added custom attribute “useWidevineAppDrmLib” to build flavor.
It would be nice to see the same attribute in buildVariant.mergedFlavor, so that I can check that attribute value and do build additional tasks, such as package additional .so files when the attribute is set to true:

android.applicationVariants.each { variant ->
if(variant.mergedFlavor.useWidevineAppDrmLib ) {
... // add copy .so task
}
}

maybe there is a way to do that already but I didn’t find out yet…
checking build variant name for substring (flavor name) works for me, but it looks dirty.

Ideally I’d like to have a map of custom attributes of different types for buildType and productFlavor.

How to solve:

There’s an alternative solution which doesn’t require the creation of your own custom class. You can utilize the already existing extras property which is already attached to the ‘productFlavors’ class. This was specifically designed to allow custom user defined variables.

android {
  // We can add any custom variable so long as it's prefaced with ext
  productFlavors {
    widevineAppDrm {
      ext.useWidevineAppDrmLib = true
    }
  }
}

Then you can later reference like so. Note, if you didn’t add the custom variable to other productFlavors you’ll need to be sure to check for it first, else gradle will complain about not finding the property.

android.applicationVariants.each { variant ->
    if (variant.productFlavors[0].ext.has("useWidevineAppDrmLib")) {
        if (variant.productFlavors.get(0).ext.useWidevineAppDrmLib) {
            ...
        }
    }
}

###

You can extend an object to add a property dynamically.
So you could do it on flavor object when they get added, using something like this:

// First declare a class that holds a boolean
class BooleanExtension {
  boolean value
  BooleanExtension(boolean value) {
    this.value = value
  }

  public void setValue(boolean value) {
    this.value = value
  }

  public boolean getValue() {
    return value
  }
}

android {
  // add the boolean extension to all flavor object when they are created.
  productFlavors.whenObjectAdded { flavor ->
    flavor.extensions.create("useWidevineAppDrmLib", BooleanExtension, false)
  }

  // then we can set the value on the extension of any flavor object
  productFlavors {
    widevineAppDrm {
      useWidevineAppDrmLib.value true
    }
  }
}

However this won’t get passed to the merged flavor. So you’d have to do

android.applicationVariants.each { variant ->
  if (variant.productFlavors.get(0).useWidevineAppDrmLib.value) {
    ...
  }
}

Edited to make the code actually work from @blackdigger’s feedback.

Leave a Reply

Your email address will not be published. Required fields are marked *