diff --git a/plugin/build.gradle b/plugin/build.gradle index 497f062..4e0a362 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -28,7 +28,7 @@ apply plugin: 'maven' archivesBaseName = 'license-tools' group = 'com.cookpad.android.plugin' -version = '1.2.8' +version = '1.2.9' dependencies { compileOnly gradleApi() diff --git a/plugin/src/main/java/com/cookpad/android/plugin/license/LicenseToolsPlugin.kt b/plugin/src/main/java/com/cookpad/android/plugin/license/LicenseToolsPlugin.kt index a051c67..8824a8b 100644 --- a/plugin/src/main/java/com/cookpad/android/plugin/license/LicenseToolsPlugin.kt +++ b/plugin/src/main/java/com/cookpad/android/plugin/license/LicenseToolsPlugin.kt @@ -3,10 +3,7 @@ package com.cookpad.android.plugin.license -import com.cookpad.android.plugin.license.task.CheckLicenses -import com.cookpad.android.plugin.license.task.GenerateLicenseJson -import com.cookpad.android.plugin.license.task.GenerateLicensePage -import com.cookpad.android.plugin.license.task.UpdateLicenses +import com.cookpad.android.plugin.license.task.* import org.gradle.api.Plugin import org.gradle.api.Project @@ -18,6 +15,7 @@ class LicenseToolsPlugin : Plugin { ) CheckLicenses.register(project) UpdateLicenses.register(project) + UpdateMissingLicenses.register(project) GenerateLicensePage.register(project) GenerateLicenseJson.register(project) } diff --git a/plugin/src/main/java/com/cookpad/android/plugin/license/Templates.kt b/plugin/src/main/java/com/cookpad/android/plugin/license/Templates.kt index 732956e..baf8edf 100644 --- a/plugin/src/main/java/com/cookpad/android/plugin/license/Templates.kt +++ b/plugin/src/main/java/com/cookpad/android/plugin/license/Templates.kt @@ -47,7 +47,7 @@ object Templates { @Throws(NotEnoughInformationException::class) private fun assertLicenseAndStatement(library: LibraryInfo) { - if (library.license.isNullOrBlank()) { + if (library.license.isNullOrBlank() && library.customLicenseName.isNullOrBlank()) { throw NotEnoughInformationException( library, "Missing info in the \"license\" field" diff --git a/plugin/src/main/java/com/cookpad/android/plugin/license/data/LibraryInfo.kt b/plugin/src/main/java/com/cookpad/android/plugin/license/data/LibraryInfo.kt index d50520c..7fa6e3f 100644 --- a/plugin/src/main/java/com/cookpad/android/plugin/license/data/LibraryInfo.kt +++ b/plugin/src/main/java/com/cookpad/android/plugin/license/data/LibraryInfo.kt @@ -15,7 +15,9 @@ data class LibraryInfo( val notice: String? = null, val licenseUrl: String?, val skip: Boolean? = null, - val forceGenerate: Boolean? = null + val forceGenerate: Boolean? = null, + val customLicenseName: String? = null, + val customLicenseContent: String? = null ) { fun normalizedLicense(): String { @@ -70,6 +72,7 @@ data class LibraryInfo( amazon_software_license.matches(license) -> "amazon_software_license" play_core_software_development_kit_terms_of_service.matches(license) -> "play_core_software_development_kit_terms_of_service" pushwoosh_license.matches(license) -> "pushwoosh_license" + custom_license.matches(license) -> "custom_license" else -> license } } @@ -142,5 +145,6 @@ data class LibraryInfo( val amazon_software_license = """(?i).*\bAmazon.*\bSoftware.*\bLicense\b.*""".toRegex() val play_core_software_development_kit_terms_of_service = """(?i).*\bPlay.*\bCore.*\bSoftware.*\bDevelopment.*\bKit.*\bTerms.*\bof.*\bService\b.*""".toRegex() val pushwoosh_license = """(?i).*\bPushwoosh.*\bLicense\b.*""".toRegex() + val custom_license = """(?i).*\bCustom.*\bLicense\b.*""".toRegex() } } diff --git a/plugin/src/main/java/com/cookpad/android/plugin/license/extension/LibraryInfoExtensions.kt b/plugin/src/main/java/com/cookpad/android/plugin/license/extension/LibraryInfoExtensions.kt index 05e414d..d6793e7 100644 --- a/plugin/src/main/java/com/cookpad/android/plugin/license/extension/LibraryInfoExtensions.kt +++ b/plugin/src/main/java/com/cookpad/android/plugin/license/extension/LibraryInfoExtensions.kt @@ -2,17 +2,60 @@ package com.cookpad.android.plugin.license.extension import com.cookpad.android.plugin.license.data.LibraryInfo -internal fun LibraryInfo.generateLibraryInfoText(): String { +internal fun LibraryInfo.generateLibraryInfoText(updatedInfo: LibraryInfo? = null): String { val text = StringBuffer() text.append("- artifact: ${artifactId.withWildcardVersion()}\n") - text.append(" name: ${name ?: "#NAME#"}\n") - text.append(" copyrightHolder: ${copyrightHolder ?: "#COPYRIGHT_HOLDER#"}\n") - text.append(" license: ${license ?: "#LICENSE#"}\n") + + var currentName = name ?: "#NAME#" + currentName = if (updatedInfo?.name != null && currentName == "#NAME#") { + updatedInfo.name + } else currentName + var currentCopyrightHolder = copyrightHolder ?: "#COPYRIGHT_HOLDER#" + currentCopyrightHolder = if (updatedInfo?.copyrightHolder != null && currentCopyrightHolder == "#COPYRIGHT_HOLDER#") { + updatedInfo.copyrightHolder + } else currentCopyrightHolder + var currentLicense = license ?: "#LICENSE#" + currentLicense = if (updatedInfo?.license != null && currentLicense == "#LICENSE#") { + updatedInfo.license + } else currentLicense + + + + if (currentName != "#NAME#" || skip != true) { + text.append(" name: ${currentName}\n") + } + if (notice != null) { + if (notice.lines().size > 1) { + text.append(" notice: |\n ${notice.replace("\n", "\n ")}\n") + } else { + text.append(" notice: ${notice}\n") + } + } else if (currentCopyrightHolder != "#COPYRIGHT_HOLDER#" || skip != true) { + text.append(" copyrightHolder: ${currentCopyrightHolder}\n") + } + if (currentLicense != "#LICENSE#" || skip != true) { + text.append(" license: ${currentLicense}\n") + } if (licenseUrl?.isNotBlank() == true) { text.append(" licenseUrl: ${licenseUrl}\n") + } else if (updatedInfo?.licenseUrl?.isNotBlank() == true) { + text.append(" licenseUrl: ${updatedInfo.licenseUrl}\n") } if (url?.isNotBlank() == true) { text.append(" url: ${url}\n") + } else if (updatedInfo?.url?.isNotBlank() == true) { + text.append(" url: ${updatedInfo.url}\n") + } + + if (customLicenseName?.isNotBlank() == true) { + text.append(" customLicenseName: ${customLicenseName}\n") + } + if (customLicenseContent?.isNotBlank() == true) { + text.append(" customLicenseContent: |\n ${customLicenseContent.replace("\n", "\n ")}\n") + } + + if (skip == true) { + text.append(" skip: true\n") } return text.toString().trim() } diff --git a/plugin/src/main/java/com/cookpad/android/plugin/license/task/GenerateLicensePage.kt b/plugin/src/main/java/com/cookpad/android/plugin/license/task/GenerateLicensePage.kt index 3ef084e..1f084d5 100644 --- a/plugin/src/main/java/com/cookpad/android/plugin/license/task/GenerateLicensePage.kt +++ b/plugin/src/main/java/com/cookpad/android/plugin/license/task/GenerateLicensePage.kt @@ -9,6 +9,7 @@ import com.cookpad.android.plugin.license.data.LibraryInfo import com.cookpad.android.plugin.license.exception.NotEnoughInformationException import com.cookpad.android.plugin.license.extension.writeLicenseHtml import com.cookpad.android.plugin.license.util.YamlUtils +import org.gradle.api.Action import org.gradle.api.GradleException import org.gradle.api.Project import org.gradle.api.Task @@ -16,10 +17,15 @@ import org.gradle.internal.impldep.com.google.common.annotations.VisibleForTesti object GenerateLicensePage { fun register(project: Project): Task { - return project.task("generateLicensePage").doLast { - val ext = project.extensions.getByType(LicenseToolsPluginExtension::class.java) - val yamlInfoList = YamlUtils.loadToLibraryInfo(project.file(ext.licensesYaml)) - project.writeLicenseHtml(yamlInfoList.toHtml(project)) + return project.task("generateLicensePage").doLast(GenerateLicensePageAction()) + } + + // can't use lambdas to define the action if you want to allow this to be used as a cacheable task + class GenerateLicensePageAction : Action { + override fun execute(task: Task) { + val ext = task.project.extensions.getByType(LicenseToolsPluginExtension::class.java) + val yamlInfoList = YamlUtils.loadToLibraryInfo(task.project.file(ext.licensesYaml)) + task.project.writeLicenseHtml(yamlInfoList.toHtml(task.project)) } } diff --git a/plugin/src/main/java/com/cookpad/android/plugin/license/task/UpdateMissingLicenses.kt b/plugin/src/main/java/com/cookpad/android/plugin/license/task/UpdateMissingLicenses.kt new file mode 100644 index 0000000..46254b7 --- /dev/null +++ b/plugin/src/main/java/com/cookpad/android/plugin/license/task/UpdateMissingLicenses.kt @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2016 Cookpad Inc. + +package com.cookpad.android.plugin.license.task + +import com.cookpad.android.plugin.license.LicenseToolsPluginExtension +import com.cookpad.android.plugin.license.data.LibraryInfo +import com.cookpad.android.plugin.license.extension.generateLibraryInfoText +import com.cookpad.android.plugin.license.extension.notListedIn +import com.cookpad.android.plugin.license.util.YamlUtils +import org.gradle.api.Action +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.internal.impldep.com.google.common.annotations.VisibleForTesting + +object UpdateMissingLicenses { + fun register(project: Project): Task { + return project.task("updateMissingLicenses").doLast(UpdateMissingLicensesAction()) + } + + // can't use lambdas to define the action if you want to allow this to be used as a cacheable task + class UpdateMissingLicensesAction : Action { + override fun execute(task: Task) { + val ext = task.project.extensions.getByType(LicenseToolsPluginExtension::class.java) + val resolvedArtifacts = + CheckLicenses.resolveProjectDependencies(task.project, ext.ignoredProjects) + val dependencyLicenses = + CheckLicenses.loadDependencyLicenses(task.project, resolvedArtifacts, ext.ignoredGroups) + updateMissingLicensesYaml(task.project, ext.licensesYaml, dependencyLicenses) + + } + } + @VisibleForTesting + internal fun updateMissingLicensesYaml( + project: Project, + licensesYaml: String, + dependencyLicenses: List + ) { + // Dedup and sort dependencies + val sortedDependencies = dependencyLicenses.associateBy { it.artifactId.withWildcardVersion() } + .toSortedMap { o1, o2 -> + o1.compareTo(o2, ignoreCase = true) + }.values.toList() + val yamlList = YamlUtils.loadToLibraryInfo(project.file(licensesYaml)) + val notInDependencies = sortedDependencies.notListedIn(yamlList) + + + project.file(licensesYaml).apply { + // Clean content + writeText("") + for (libraryInfo in yamlList) { + sortedDependencies.find { it.artifactId.matches(libraryInfo.artifactId) }?.let { + appendText("${libraryInfo.generateLibraryInfoText(it)}\n") + } + } + for (libraryInfo in notInDependencies) { + appendText("${libraryInfo.generateLibraryInfoText()}\n") + } + } + } +} diff --git a/plugin/src/main/java/com/cookpad/android/plugin/license/util/YamlUtils.kt b/plugin/src/main/java/com/cookpad/android/plugin/license/util/YamlUtils.kt index 5bd1b67..135c481 100644 --- a/plugin/src/main/java/com/cookpad/android/plugin/license/util/YamlUtils.kt +++ b/plugin/src/main/java/com/cookpad/android/plugin/license/util/YamlUtils.kt @@ -33,7 +33,9 @@ object YamlUtils { forceGenerate = it.getOrDefault( "forceGenerate", "false" - ).toString().toBoolean() + ).toString().toBoolean(), + customLicenseName = it["customLicenseName"] as String?, + customLicenseContent = it["customLicenseContent"] as String? ) } } diff --git a/plugin/src/main/resources/template/licenses/custom_license.html b/plugin/src/main/resources/template/licenses/custom_license.html new file mode 100644 index 0000000..2b90fac --- /dev/null +++ b/plugin/src/main/resources/template/licenses/custom_license.html @@ -0,0 +1,9 @@ +
+

${library.name}

+

${library.copyrightStatement.replaceAll("\n\n", "
")}

+ <% print library.url == null || library.url.isEmpty() ? "" : """

${library.url}

""" %> +
+

${library.customLicenseName}

+ ${library.customLicenseContent} +
+
diff --git a/plugin/src/test/java/com/cookpad/android/plugin/license/task/UpdateMissingLicensesTest.kt b/plugin/src/test/java/com/cookpad/android/plugin/license/task/UpdateMissingLicensesTest.kt new file mode 100644 index 0000000..d289c26 --- /dev/null +++ b/plugin/src/test/java/com/cookpad/android/plugin/license/task/UpdateMissingLicensesTest.kt @@ -0,0 +1,86 @@ +package com.cookpad.android.plugin.license.task + +import com.cookpad.android.plugin.license.data.ArtifactId +import com.cookpad.android.plugin.license.loadYamlFromResources +import com.cookpad.android.plugin.license.util.YamlUtils +import com.google.common.truth.Truth.assertThat +import com.nhaarman.mockitokotlin2.doReturn +import com.nhaarman.mockitokotlin2.whenever +import org.gradle.api.Project +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TemporaryFolder +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import java.io.File + +@RunWith(MockitoJUnitRunner::class) +class UpdateMissingLicensesTest { + + @get:Rule + val tempFolder = TemporaryFolder() + private lateinit var licensesYamlFile: File + + @Mock + lateinit var project: Project + + @Before + fun setUp() { + licensesYamlFile = tempFolder.newFile() + whenever(project.file(FILENAME_LICENSES_YAML)) doReturn licensesYamlFile + } + + @After + fun tearDown() { + licensesYamlFile.delete() + } + + @Test + fun updateLicensesYaml_addsMissingDependencies() { + val licenses = loadYamlFromResources("yaml/missing_licenses.yml") + assertThat(licenses.size).isEqualTo(3) + UpdateMissingLicenses.updateMissingLicensesYaml(project, FILENAME_LICENSES_YAML, licenses) + + var result = YamlUtils.loadToLibraryInfo(licensesYamlFile) + assertThat(result.size).isEqualTo(3) + + val update = loadYamlFromResources("yaml/missing_licenses_update.yml") + UpdateMissingLicenses.updateMissingLicensesYaml(project, FILENAME_LICENSES_YAML, update) + result = YamlUtils.loadToLibraryInfo(licensesYamlFile) + assertThat(result.size).isEqualTo(4) + + assertThat(result.size).isEqualTo(update.size) + for (info in update) { + val finalInfo = result.find { it.artifactId.matches(info.artifactId) } + assertThat(finalInfo).isNotNull() + if (info.artifactId.matches(ArtifactId("com.android.support", "+", "+"))) { + assertThat(info).isNotEqualTo(finalInfo) + assertThat(finalInfo!!.license).isEqualTo("apache2") + } else { + assertThat(info).isEqualTo(finalInfo) + } + } + } + + @Test + fun updateLicensesYaml_removeMissingDependencies() { + val licenses = loadYamlFromResources("yaml/missing_licenses_update.yml") + assertThat(licenses.size).isEqualTo(4) + UpdateMissingLicenses.updateMissingLicensesYaml(project, FILENAME_LICENSES_YAML, licenses) + + var result = YamlUtils.loadToLibraryInfo(licensesYamlFile) + assertThat(result.size).isEqualTo(4) + + val update = loadYamlFromResources("yaml/removed_licenses.yml") + UpdateMissingLicenses.updateMissingLicensesYaml(project, FILENAME_LICENSES_YAML, update) + result = YamlUtils.loadToLibraryInfo(licensesYamlFile) + assertThat(result.size).isEqualTo(3) + } + + companion object { + private const val FILENAME_LICENSES_YAML = "licenses.yml" + } +} diff --git a/plugin/src/test/resources/yaml/licenses.yml b/plugin/src/test/resources/yaml/licenses.yml index 890bfde..e6359f8 100644 --- a/plugin/src/test/resources/yaml/licenses.yml +++ b/plugin/src/test/resources/yaml/licenses.yml @@ -76,3 +76,44 @@ license: cc-by-4.0 licenseUrl: https://creativecommons.org/licenses/by/4.0/legalcode url: https://creativecommons.org/ +- artifact: org.concentus:Concentus:+ + name: Concentus + copyrightHolder: | + Copyright (c) by various holding parties, including (but not limited to): + Skype Limited, Xiph.Org Foundation, CSIRO, Microsoft Corporation, + Jean-Marc Valin, Gregory Maxwell, Mark Borgerding, Timothy B. Terriberry, + Logan Stromberg. All rights are reserved by their respective holders. + license: Custom License + customLicenseName: Concentus License + customLicenseContent: | + Copyright (c) by various holding parties, including (but not limited to): + Skype Limited, Xiph.Org Foundation, CSIRO, Microsoft Corporation, + Jean-Marc Valin, Gregory Maxwell, Mark Borgerding, Timothy B. Terriberry, + Logan Stromberg. All rights are reserved by their respective holders. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of Internet Society, IETF or IETF Trust, nor the + names of specific contributors, may be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + licenseUrl: https://github.com/lostromb/concentus/blob/master/LICENSE diff --git a/plugin/src/test/resources/yaml/missing_licenses.yml b/plugin/src/test/resources/yaml/missing_licenses.yml new file mode 100644 index 0000000..c8f062b --- /dev/null +++ b/plugin/src/test/resources/yaml/missing_licenses.yml @@ -0,0 +1,17 @@ +- artifact: com.android.support:+:+ + name: Android Support Libraries + copyrightHolder: The Android Open Source Project + license: apache2 +- artifact: com.mopub:libAvid-mopub:+ + name: AVID SDK (MoPub Android namespace) + copyrightHolder: MoPub (a division of Twitter, Inc.) + license: MoPub SDK License + licenseUrl: http://www.mopub.com/legal/sdk-license-agreement/ + url: https://github.com/mopub/mopub-android-sdk +# This is example license +- artifact: com.example:example-common:+ + name: example-common + copyrightHolder: Example Author + license: #LICENSE# + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: https://example.com/example/example-common diff --git a/plugin/src/test/resources/yaml/missing_licenses_update.yml b/plugin/src/test/resources/yaml/missing_licenses_update.yml new file mode 100644 index 0000000..1d39e79 --- /dev/null +++ b/plugin/src/test/resources/yaml/missing_licenses_update.yml @@ -0,0 +1,23 @@ +- artifact: com.android.support:+:+ + name: Android Support Libraries + copyrightHolder: The Android Open Source Project + license: #LICENSE# +- artifact: com.mopub:libAvid-mopub:+ + name: AVID SDK (MoPub Android namespace) + copyrightHolder: MoPub (a division of Twitter, Inc.) + license: MoPub SDK License + licenseUrl: http://www.mopub.com/legal/sdk-license-agreement/ + url: https://github.com/mopub/mopub-android-sdk +- artifact: com.mopub:mopub-sdk-base:+ + name: mopub-sdk-base + copyrightHolder: MoPub (a division of Twitter, Inc.) + license: MoPub SDK License + licenseUrl: http://www.mopub.com/legal/sdk-license-agreement/ + url: https://github.com/mopub/mopub-android-sdk +# This is example license +- artifact: com.example:example-common:+ + name: example-common + copyrightHolder: Example Author + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: https://example.com/example/example-common diff --git a/plugin/src/test/resources/yaml/removed_licenses.yml b/plugin/src/test/resources/yaml/removed_licenses.yml new file mode 100644 index 0000000..a2142a5 --- /dev/null +++ b/plugin/src/test/resources/yaml/removed_licenses.yml @@ -0,0 +1,19 @@ +- artifact: com.mopub:libAvid-mopub:+ + name: AVID SDK (MoPub Android namespace) + copyrightHolder: MoPub (a division of Twitter, Inc.) + license: MoPub SDK License + licenseUrl: http://www.mopub.com/legal/sdk-license-agreement/ + url: https://github.com/mopub/mopub-android-sdk +- artifact: org.jetbrains.kotlinx:kotlinx-coroutines-android:+ + name: kotlinx-coroutines-android + copyrightHolder: JetBrains s.r.o. + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: https://github.com/Kotlin/kotlinx.coroutines +# This is example license +- artifact: com.example:example-common:+ + name: example-common + copyrightHolder: Example Author + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: https://example.com/example/example-common diff --git a/sample/build.gradle b/sample/build.gradle index e2534ce..a2139d4 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -7,7 +7,7 @@ // mavenLocal() // } // dependencies { -// classpath 'com.cookpad.android.plugin:license-tools:$your_version' +// classpath 'com.cookpad.android.plugin:license-tools:1.2.9' // } //} //apply plugin: 'com.cookpad.android.plugin.license-tools' diff --git a/sample/licenses.yml b/sample/licenses.yml index 21022c5..8705415 100644 --- a/sample/licenses.yml +++ b/sample/licenses.yml @@ -190,3 +190,44 @@ license: The Apache Software License, Version 2.0 licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt url: http://www.jetbrains.org +- artifact: org.concentus:Concentus:+ + name: Concentus + copyrightHolder: | + Copyright (c) by various holding parties, including (but not limited to): + Skype Limited, Xiph.Org Foundation, CSIRO, Microsoft Corporation, + Jean-Marc Valin, Gregory Maxwell, Mark Borgerding, Timothy B. Terriberry, + Logan Stromberg. All rights are reserved by their respective holders. + license: Custom License + customLicenseName: Concentus License + customLicenseContent: | + Copyright (c) by various holding parties, including (but not limited to): + Skype Limited, Xiph.Org Foundation, CSIRO, Microsoft Corporation, + Jean-Marc Valin, Gregory Maxwell, Mark Borgerding, Timothy B. Terriberry, + Logan Stromberg. All rights are reserved by their respective holders.

+ + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met:

+ + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer.

+ + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution.

+ + * Neither the name of Internet Society, IETF or IETF Trust, nor the + names of specific contributors, may be used to endorse or promote + products derived from this software without specific prior written + permission.

+ + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + licenseUrl: https://github.com/lostromb/concentus/blob/master/LICENSE \ No newline at end of file diff --git a/sample/src/main/assets/licenses.html b/sample/src/main/assets/licenses.html index 58f8a0a..a00b3d8 100644 --- a/sample/src/main/assets/licenses.html +++ b/sample/src/main/assets/licenses.html @@ -7979,6 +7979,49 @@

APPENDIX: How to apply the Apache License to your work.

Copyright [yyyy] [name of copyright owner]

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.
+
+

Concentus

+

Copyright © Copyright (c) by various holding parties, including (but not limited to): + Skype Limited, Xiph.Org Foundation, CSIRO, Microsoft Corporation, + Jean-Marc Valin, Gregory Maxwell, Mark Borgerding, Timothy B. Terriberry, + Logan Stromberg. All rights are reserved by their respective holders. + . All rights reserved.

+ +
+

Concentus License

+ Copyright (c) by various holding parties, including (but not limited to): + Skype Limited, Xiph.Org Foundation, CSIRO, Microsoft Corporation, + Jean-Marc Valin, Gregory Maxwell, Mark Borgerding, Timothy B. Terriberry, + Logan Stromberg. All rights are reserved by their respective holders.

+ + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met:

+ + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer.

+ + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution.

+ + * Neither the name of Internet Society, IETF or IETF Trust, nor the + names of specific contributors, may be used to endorse or promote + products derived from this software without specific prior written + permission.

+ + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +
+