Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 34 additions & 32 deletions LICENSES.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,37 @@
# Open Source Licenses

Infomaniak Android Core declares the following notable open source libraries as runtime dependencies (build-time and test-only dependencies are excluded). This list may not be exhaustive.
Infomaniak Android Core declares the following notable open source libraries as runtime dependencies (build-time and test-only

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the whole file changed ?

@Elouan1411 Elouan1411 Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just format it and add qrose

dependencies are excluded). This list may not be exhaustive.

| Library | License |
|---------|---------|
| [AndroidX AppCompat](https://developer.android.com/jetpack/androidx/releases/appcompat) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX Biometric](https://developer.android.com/jetpack/androidx/releases/biometric) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX Browser](https://developer.android.com/jetpack/androidx/releases/browser) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX Core KTX](https://developer.android.com/jetpack/androidx/releases/core) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX Core Splashscreen](https://developer.android.com/jetpack/androidx/releases/core) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX DataStore Preferences](https://developer.android.com/jetpack/androidx/releases/datastore) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX Lifecycle](https://developer.android.com/jetpack/androidx/releases/lifecycle) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX Navigation](https://developer.android.com/jetpack/androidx/releases/navigation) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX RecyclerView](https://developer.android.com/jetpack/androidx/releases/recyclerview) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX Room](https://developer.android.com/jetpack/androidx/releases/room) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX Work Runtime](https://developer.android.com/jetpack/androidx/releases/work) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Coil](https://github.com/coil-kt/coil) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Dagger Hilt](https://dagger.dev/hilt/) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [DotLottie Android](https://github.com/LottieFiles/dotlottie-android) | [MIT License](https://opensource.org/licenses/MIT) |
| [Google Material Components for Android](https://github.com/material-components/material-components-android) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Google Play App Update](https://developer.android.com/guide/playcore/in-app-updates) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Google Play Integrity](https://developer.android.com/google/play/integrity) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Google Play Review](https://developer.android.com/guide/playcore/in-app-review) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Jetpack Compose](https://developer.android.com/jetpack/compose) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Kotlin Standard Library](https://kotlinlang.org/) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Kotlinx Coroutines](https://github.com/Kotlin/kotlinx.coroutines) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Kotlinx Serialization](https://github.com/Kotlin/kotlinx.serialization) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Ktor](https://ktor.io/) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Lottie](https://github.com/airbnb/lottie-android) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Matomo SDK for Android](https://github.com/matomo-org/matomo-sdk-android) | [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause) |
| [OkHttp](https://github.com/square/okhttp) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Okio](https://github.com/square/okio) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Sentry Android SDK](https://github.com/getsentry/sentry-java) | [MIT License](https://opensource.org/licenses/MIT) |
| [Splitties](https://github.com/LouisCAD/Splitties) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| Library | License |
|--------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------|
| [AndroidX AppCompat](https://developer.android.com/jetpack/androidx/releases/appcompat) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX Biometric](https://developer.android.com/jetpack/androidx/releases/biometric) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX Browser](https://developer.android.com/jetpack/androidx/releases/browser) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX Core KTX](https://developer.android.com/jetpack/androidx/releases/core) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX Core Splashscreen](https://developer.android.com/jetpack/androidx/releases/core) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX DataStore Preferences](https://developer.android.com/jetpack/androidx/releases/datastore) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX Lifecycle](https://developer.android.com/jetpack/androidx/releases/lifecycle) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX Navigation](https://developer.android.com/jetpack/androidx/releases/navigation) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX RecyclerView](https://developer.android.com/jetpack/androidx/releases/recyclerview) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX Room](https://developer.android.com/jetpack/androidx/releases/room) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [AndroidX Work Runtime](https://developer.android.com/jetpack/androidx/releases/work) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Coil](https://github.com/coil-kt/coil) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Dagger Hilt](https://dagger.dev/hilt/) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [DotLottie Android](https://github.com/LottieFiles/dotlottie-android) | [MIT License](https://opensource.org/licenses/MIT) |
| [Google Material Components for Android](https://github.com/material-components/material-components-android) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Google Play App Update](https://developer.android.com/guide/playcore/in-app-updates) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Google Play Integrity](https://developer.android.com/google/play/integrity) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Google Play Review](https://developer.android.com/guide/playcore/in-app-review) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Jetpack Compose](https://developer.android.com/jetpack/compose) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Kotlin Standard Library](https://kotlinlang.org/) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Kotlinx Coroutines](https://github.com/Kotlin/kotlinx.coroutines) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Kotlinx Serialization](https://github.com/Kotlin/kotlinx.serialization) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Ktor](https://ktor.io/) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Lottie](https://github.com/airbnb/lottie-android) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Matomo SDK for Android](https://github.com/matomo-org/matomo-sdk-android) | [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause) |
| [QRose](https://github.com/alexzhirkevich/qrose) | [MIT License](https://opensource.org/licenses/MIT) |
| [OkHttp](https://github.com/square/okhttp) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Okio](https://github.com/square/okio) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
| [Sentry Android SDK](https://github.com/getsentry/sentry-java) | [MIT License](https://opensource.org/licenses/MIT) |
| [Splitties](https://github.com/LouisCAD/Splitties) | [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
2 changes: 1 addition & 1 deletion Network/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ android {
}

dependencies {
api(core.okhttp)
api(project(":Network:Models"))
implementation(project(":Sentry"))

implementation(core.androidx.core.ktx)
implementation(core.gson)
implementation(core.kotlinx.serialization.json)
implementation(core.ktor.client.core)
implementation(core.okhttp)
implementation(core.splitties.mainhandler)
implementation(core.splitties.systemservices)
implementation(core.splitties.toast)
Expand Down
36 changes: 36 additions & 0 deletions Ui/Compose/ContactCard/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
plugins {
alias(core.plugins.infomaniak.android.library)
alias(core.plugins.infomaniak.android.library.flavor.aware)
alias(core.plugins.compose.compiler)
}

android {
namespace = "com.infomaniak.core.ui.compose.contactcard"

buildFeatures {
compose = true
}
}

dependencies {
api(core.androidx.lifecycle.viewmodel.ktx)
api(project(":Auth"))
implementation(project(":Avatar"))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put all the project together.

implementation(project(":Common"))
implementation(project(":Ui:View:PrimaryPalette"))
implementation(project(":Ui:Compose:Margin"))
implementation(project(":Network"))

implementation(platform(core.compose.bom))
api(core.compose.runtime)
api(core.compose.ui)
implementation(core.compose.foundation)
implementation(core.compose.material3)
implementation(core.compose.material.icons)
implementation("androidx.compose.material:material-icons-extended")
implementation(core.compose.ui.tooling.preview)

implementation(core.androidx.lifecycle.viewmodel.compose)
implementation(core.androidx.lifecycle.runtime.compose)
implementation(core.qrose)
Comment thread
Elouan1411 marked this conversation as resolved.
}
16 changes: 16 additions & 0 deletions Ui/Compose/ContactCard/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application>
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed

<provider
android:name=".ContactCardFileProvider"
android:authorities="${applicationId}.core.contactcard.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/contact_card_paths" />
</provider>
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Infomaniak Core - Android
* Copyright (C) 2026 Infomaniak Network SA
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.infomaniak.core.ui.compose.contactcard

import androidx.core.content.FileProvider

class ContactCardFileProvider : FileProvider()
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Infomaniak Core - Android
* Copyright (C) 2026 Infomaniak Network SA
*
* This program 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 (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.infomaniak.core.ui.compose.contactcard

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.util.Base64
import androidx.core.content.FileProvider
import com.infomaniak.core.auth.models.user.Card
import com.infomaniak.core.common.cancellable
import com.infomaniak.core.network.networking.HttpClient
import com.infomaniak.core.network.utils.await
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.Request
import java.io.File

private const val MAX_AVATAR_SIZE = 5 * 1024 * 1024 // 5 MB

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But you can keep this one.

private val ILLEGAL_FILE_NAME_CHARACTERS = Regex("[\\\\/:*?\"<>|]+")

suspend fun Card.createShareFile(context: Context): File = withContext(Dispatchers.IO) {
val (avatarBase64, avatarMimeType) = getAvatarDataOrNull()

val fileName = "attachments_cache${firstName}_${lastName}.vcf"
val safeFileName = fileName.replace(ILLEGAL_FILE_NAME_CHARACTERS, "")

val directory = File(context.cacheDir, "attachments_cache").apply { mkdirs() }

File(directory, safeFileName).apply {
val vCardContent = makeVCardString(avatarBase64 = avatarBase64, avatarMimeType = avatarMimeType)
writeText(vCardContent)
}
}

private suspend fun Card.getAvatarDataOrNull(): Pair<String?, String?> {
val url = avatarUrl ?: return null to null

return runCatching {
val request = Request.Builder().url(url).build()

HttpClient.okHttpClient.newCall(request).await().use { response ->
val body = response.body
if (!response.isSuccessful) return@runCatching null to null

val contentLength = body.contentLength()
if (contentLength > MAX_AVATAR_SIZE || contentLength == (-1).toLong()) return@runCatching null to null

val mimeType = body.contentType()?.subtype?.uppercase()
val bytes = body.bytes()

if (bytes.size > MAX_AVATAR_SIZE) return@runCatching null to null

val base64 = Base64.encodeToString(bytes, Base64.NO_WRAP)
Comment thread
tevincent marked this conversation as resolved.

base64 to mimeType
}
}
.cancellable()
.getOrDefault(null to null)
}

suspend fun Activity.shareContactCard(card: Card) {
val file = card.createShareFile(this)
val authority = "${applicationContext.packageName}.core.contactcard.provider"
val uri = FileProvider.getUriForFile(this, authority, file)
val intent = Intent().apply {
action = Intent.ACTION_SEND
type = "text/vcard"
putExtra(Intent.EXTRA_STREAM, uri)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}

startActivity(Intent.createChooser(intent, getString(R.string.contactCardShareChooserTitle)))
}
Loading
Loading