--- a/geekdroid-firebase/build.gradle.kts Tue Nov 29 15:05:58 2022 -0400
+++ b/geekdroid-firebase/build.gradle.kts Tue Nov 29 17:48:50 2022 -0400
@@ -40,7 +40,7 @@
implementation(enforcedPlatform(kotlin("bom")))
implementation(kotlin("stdlib-jdk8"))
- implementation(enforcedPlatform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.3.5"))
+ implementation(enforcedPlatform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.4"))
api("org.jetbrains.kotlinx:kotlinx-coroutines-core")
api("org.jetbrains.kotlinx:kotlinx-coroutines-play-services")
--- a/geekdroid/build.gradle.kts Tue Nov 29 15:05:58 2022 -0400
+++ b/geekdroid/build.gradle.kts Tue Nov 29 17:48:50 2022 -0400
@@ -86,7 +86,7 @@
implementation(enforcedPlatform(kotlin("bom")))
implementation(kotlin("stdlib-jdk8"))
- implementation(enforcedPlatform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.3.5"))
+ implementation(enforcedPlatform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.4"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core")
implementation("androidx.lifecycle:lifecycle-livedata-core-ktx:2.5.1")
--- a/geekdroid/src/main/java/com/geekorum/geekdroid/network/BrowserLauncher.kt Tue Nov 29 15:05:58 2022 -0400
+++ b/geekdroid/src/main/java/com/geekorum/geekdroid/network/BrowserLauncher.kt Tue Nov 29 17:48:50 2022 -0400
@@ -136,11 +136,11 @@
launchUrl(context, uri) { customizer?.customize(this) }
}
- interface LaunchCustomizer {
+ fun interface LaunchCustomizer {
fun customize(builder: CustomTabsIntent.Builder)
}
- interface PreferredPackageSelector {
+ fun interface PreferredPackageSelector {
fun orderByPreference(availablePackages: List<String>): List<String>
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/geekdroid/src/main/java/com/geekorum/geekdroid/osslicenses/LicenseInfoRepository.kt Tue Nov 29 17:48:50 2022 -0400
@@ -0,0 +1,63 @@
+/*
+ * Geekdroid is a utility library for development on the Android
+ * Platform.
+ *
+ * Copyright (C) 2017-2022 by Frederic-Charles Barthelery.
+ *
+ * This file is part of Geekdroid.
+ *
+ * Geekdroid is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Geekdroid is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Geekdroid. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.geekorum.geekdroid.osslicenses
+
+import android.content.Context
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.withContext
+
+class LicenseInfoRepository(
+ private val appContext: Context,
+ private val mainCoroutineDispatcher: CoroutineDispatcher,
+ private val ioCoroutineDispatcher: CoroutineDispatcher,
+) {
+
+ private var licensesInfo: Map<String, String>? = null
+
+ suspend fun getLicensesInfo(): Map<String, String> = withContext(mainCoroutineDispatcher) {
+ parseLicenses()
+ checkNotNull(licensesInfo)
+ }
+
+ suspend fun getLicenseFor(dependency: String): String = withContext(mainCoroutineDispatcher) {
+ parseLicenses()
+ checkNotNull(licensesInfo).let {
+ return@withContext it[dependency] ?: error("Dependency not found")
+ }
+ }
+
+ private suspend fun parseLicenses() = withContext(mainCoroutineDispatcher) {
+ if (licensesInfo == null) {
+ val licenses = withContext(ioCoroutineDispatcher) {
+ OssLicenseParser.openDefaultThirdPartyLicenses(appContext).use { licensesInput ->
+ OssLicenseParser.openDefaultThirdPartyLicensesMetadata(appContext).use { licensesMetadataInput ->
+ val parser = OssLicenseParser(
+ thirdPartyLicensesInput = licensesInput,
+ thirdPartyLicensesMetadataInput = licensesMetadataInput)
+ parser.parseLicenses()
+ }
+ }
+ }
+ licensesInfo = licenses
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/geekdroid/src/main/java/com/geekorum/geekdroid/osslicenses/OssLicenseParser.kt Tue Nov 29 17:48:50 2022 -0400
@@ -0,0 +1,122 @@
+/*
+ * Geekdroid is a utility library for development on the Android
+ * Platform.
+ *
+ * Copyright (C) 2017-2022 by Frederic-Charles Barthelery.
+ *
+ * This file is part of Geekdroid.
+ *
+ * Geekdroid is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Geekdroid is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Geekdroid. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.geekorum.geekdroid.osslicenses
+
+import android.annotation.SuppressLint
+import android.content.Context
+import okio.ByteString
+import okio.buffer
+import okio.source
+import java.io.InputStream
+
+/**
+ * Parse licences data generated by the "com.google.android.gms.oss-licenses-plugin" gradle plugin.
+ * [thirdPartyLicensesInput] is usually res/raw/third_party_licenses file
+ * [thirdPartyLicensesMetadataInput] is usually res/raw/third_party_license_metadata file
+ */
+class OssLicenseParser(
+ private val thirdPartyLicensesInput: InputStream,
+ private val thirdPartyLicensesMetadataInput: InputStream
+) {
+ fun parseLicenses(): Map<String, String> {
+ val licenses = readLicensesFile()
+ return buildLicenseInfo(licenses)
+ }
+
+ private fun readLicensesFile(): ByteString {
+ return thirdPartyLicensesInput.source().use { source ->
+ source.buffer().use {
+ it.readByteString()
+ }
+ }
+ }
+
+ private fun buildLicenseInfo(license: ByteString): Map<String, String> {
+ return thirdPartyLicensesMetadataInput.source().use { source ->
+ source.buffer().use {
+ buildMap {
+ while (true) {
+ val line = it.readUtf8Line() ?: break
+ if (line.isNotBlank()) {
+ with(line.toLineParser()) {
+ val start = readStartIdx()
+ val length = readLength()
+ val dependency = readName()
+ val licenseTxt = license.substring(
+ beginIndex = start,
+ endIndex = start + length + 1
+ ).string(Charsets.UTF_8)
+ put(dependency, licenseTxt)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ companion object {
+ @SuppressLint("DiscouragedApi")
+ fun openDefaultThirdPartyLicenses(context: Context): InputStream {
+ val thirdPartyLicensesId = context.resources.getIdentifier("third_party_licenses", "raw", context.packageName)
+ check(thirdPartyLicensesId != 0) { "third_party_licenses was not found in resources raw of ${context.packageName}"}
+ return context.resources.openRawResource(thirdPartyLicensesId)
+ }
+
+ @SuppressLint("DiscouragedApi")
+ fun openDefaultThirdPartyLicensesMetadata(context: Context): InputStream {
+ val thirdPartyLicensesMetadataId = context.resources.getIdentifier("third_party_license_metadata", "raw", context.packageName)
+ check(thirdPartyLicensesMetadataId != 0) { "third_party_license_metadata was not found in resources raw of ${context.packageName}"}
+ return context.resources.openRawResource(thirdPartyLicensesMetadataId)
+ }
+ }
+}
+
+private class LicenseMetadataLineParser(
+ private val line: String
+) {
+
+ private var idx = 0
+
+ fun readStartIdx(): Int {
+ val end = line.indexOf(':', startIndex = idx)
+ val result = line.substring(idx, end).toInt()
+ idx = end + 1
+ return result
+ }
+
+ fun readLength(): Int {
+ val end = line.indexOf(' ', startIndex = idx)
+ val result = line.substring(idx, end).toInt()
+ idx = end + 1
+ return result
+ }
+
+ fun readName(): String {
+ val result = line.substring(idx)
+ idx = line.length + 1
+ return result
+ }
+
+}
+
+private fun String.toLineParser() = LicenseMetadataLineParser(this)