Open Source License Info for Android

Simple Display of Open Source License Info in Android Apps?

This past week I came across a page in the Google developer documentation for a new plugin and related library in Google Play services for Including Open Source Notices.

Displaying open source notices is certainly important, but it also tends to be a tedious and sometimes painful process so I was intrigued by the promise of a simplified workflow that could nearly automate the process.

I decided to give it a quick try.  Quick is an appropriate term here, because It really did take only a few minutes to get a working example up and running to quickly evaluate the new tools.

I’ll explain how I made my evaluation below, but the tl;dr is … this is probably not the tool you are looking for.  Unless all the libraries you’re using have the correct license info included in the POM (they probably all don’t), you’re most likely going to want to find a different solution.

This is not the tool you’re looking for…probably.

 

Setup

This new set of tools includes 2 components:

  1. A plugin that parses your dependencies’ POM file and looks for license info
  2. A library that includes an OssLicensesMenuActivity that will display the parsed license info

Add Dependencies

The setup for incorporating these new tools can be found here and is quite straightforward:

  1. Update root-level build.gradle file
    • Make sure the Google maven repository is defined
      • maven { url "https://maven.google.com" } // or google() for Gradle 4+
    • Add oss-licenses plugin to the dependenices section
      • classpath com.google.gms:oss-licenses:0.9.0
  2. Update app-level build.gradle file
    • Apply the plugin by adding the following line
      • apply plugin: 'com.google.gms.oss.licenses.plugin'
    • Declare the library dependency
      • compile 'com.google.android.gms:play-services-oss-licenses:11.2.2'

Generate License Info

Once this is done, rebuild your project and you should see 2 new files added

  • ‘src/main/res/raw/third_party_license_metadata’
    • contains a list of dependency names
  • ‘src/main/res/raw/third_party_licenses’
    • contains a list of license urls

 

Usage

To display the license info within your app, simply start the provided Activity class

  • startActivity(new Intent(this, OssLicensesMenuActivity.class));

 

Does it work?

Simple Example

For this set of dependencies

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"

    implementation 'com.android.support:appcompat-v7:26.0.2'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    implementation 'com.android.support:design:26.0.2'
    implementation 'com.google.android.gms:play-services-oss-licenses:11.2.2'

    testImplementation 'junit:junit:4.12'
    androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
}

the started Activity will look something like this:

 

For this small set of dependencies the plugin seems to do pretty well.  There are 10+ license items included in this list, and clicking on an item displays the url for the license text file.  (It would be nice if the license url was clickable, but it’s certainly better than nothing)

More Realistic Example

Since most projects are going to have more than a handful of dependencies, I added some additional items to my dependencies section and redeployed to see the results.

With this updated set of dependencies

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"

    implementation 'com.android.support:appcompat-v7:26.0.2'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    implementation 'com.android.support:design:26.0.2'
    implementation 'com.google.android.gms:play-services-oss-licenses:11.2.2'

    implementation 'com.facebook.device.yearclass:yearclass:2.0.0'
    implementation 'com.squareup.moshi:moshi-kotlin:1.5.0'
    implementation 'com.google.code.gson:gson:2.8.1'

    implementation 'uk.co.chrisjenx:calligraphy:2.3.0'
    implementation 'com.birbit:android-priority-jobqueue:2.0.1'
    implementation 'io.reactivex:rxjava:1.3.0'

    implementation 'com.squareup.retrofit2:retrofit:2.2.0'
    implementation 'com.squareup:otto:1.3.8'

    implementation 'com.google.android.exoplayer:exoplayer:r1.5.16'

    testImplementation 'junit:junit:4.12'
    androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
}

The resulting license list is certainly longer

 

but… it doesn’t include everything I would expect.  There were no items for some of the libraries such as retrofit, moshi, or exoplayer.

I tried out this same approach on a production project, and the number of missing dependencies was even greater.  This discrepancy is why I don’t think this is a valid solution right now for including open source dependencies.  If you can’t trust that everything will be included, then, in my opinion, you’re better off handling it all manually to ensure you don’t miss anything.

If you try it out, and everything seems to be in order then by all means use these tools.  They’re easy enough to quickly try and validate, but you would need to be sure to revalidate the parsed license data each time you add a dependency.

Alternatives

If your set of dependencies isn’t completed covered by these tools, what are your options?

Probably the most straightforward approach is to simply roll your own solution to display info for the licenses you add.

  • Pros
    • Full control of UI/UX
    • Full control of what is added (or missing)
  • Cons
    • Tedious
    • Time consuming

 

Since it’s an open source problem, it would be nice to have an open source solution as well.  There are a couple solutions I’ve come across that could be a good starting point

 

Try it yourself

I encourage you to try these tools out in your own project, but if you want to start on something smaller you can check out my sample code here

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.