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
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import android.provider.DocumentsContract
import android.provider.DocumentsProvider
import android.provider.Settings
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.edit
import androidx.core.net.toUri
import androidx.core.os.bundleOf
import com.infomaniak.core.common.cancellable
Expand Down Expand Up @@ -89,6 +90,10 @@ class CloudStorageProvider : DocumentsProvider() {
private val cloudScope = CoroutineScope(
CoroutineName("CloudStorage") + Executors.newSingleThreadExecutor().asCoroutineDispatcher()
)
private fun isProviderDisabled(): Boolean {
val ctx = context ?: return true
return isDisabled(ctx)
}

/**
* Indicates whether the current platform is Chrome OS.
Expand Down Expand Up @@ -176,6 +181,11 @@ class CloudStorageProvider : DocumentsProvider() {
override fun queryChildDocuments(parentDocumentId: String, projection: Array<out String>?, sortOrder: String?): Cursor {
val cursor = DocumentCursor(projection ?: DEFAULT_DOCUMENT_PROJECTION, isAutoCloseableJob = false)

if (isProviderDisabled()) {
cursor.extras = bundleOf(DocumentsContract.EXTRA_ERROR to (context?.getString(R.string.fileProviderExtensionError)))
return cursor
}

val uri = DocumentCursor.createUri(context, parentDocumentId)
val isNewJob = uri != oldQueryChildUri || needRefresh

Expand Down Expand Up @@ -285,6 +295,9 @@ class CloudStorageProvider : DocumentsProvider() {

override fun openDocument(documentId: String, mode: String, signal: CancellationSignal?): ParcelFileDescriptor? {
SentryLog.d(TAG, "openDocument(), id=$documentId, mode=$mode, signalIsCancelled: ${signal?.isCanceled}")
if (isProviderDisabled()) {
throw SecurityException("File provider disabled (kDrive is no longer available in the Files application and in third-party applications)")
}
val context = context ?: return null

fun getRemoteFile(localFile: File?, fileId: Int, driveId: Int): File? {
Expand Down Expand Up @@ -863,6 +876,8 @@ class CloudStorageProvider : DocumentsProvider() {
private const val DRIVE_SEPARATOR = "@"
private const val MY_SHARES_FOLDER_ID = -1
private const val SHARED_WITHME_FOLDER_ID = -2
private const val PREFS_NAME = "cloud_storage_provider"
private const val KEY_DISABLED = "disabled_by_app_lock"

private val SHARED_URI_REGEX = Regex("\\d+/-\\d+/.+$DRIVE_SEPARATOR\\d+/\\d+")

Expand Down Expand Up @@ -964,6 +979,15 @@ class CloudStorageProvider : DocumentsProvider() {
comeFromSharedWithMe(documentId)
)

fun isDisabled(context: Context): Boolean {
return context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE).getBoolean(KEY_DISABLED, false)
}

fun setDisabled(context: Context, disabled: Boolean) {
context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE).edit { putBoolean(KEY_DISABLED, disabled) }
notifyRootsChanged(context)
}

fun notifyRootsChanged(context: Context) {
val authority = context.getString(R.string.CLOUD_STORAGE_AUTHORITY)
val rootsUri = DocumentsContract.buildRootsUri(authority)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ import com.infomaniak.core.applock.AppLockManager
import com.infomaniak.core.twofactorauth.front.TwoFactorAuthApprovalAutoManagedBottomSheet
import com.infomaniak.core.twofactorauth.front.addComposeOverlay
import com.infomaniak.drive.R
import com.infomaniak.drive.data.documentprovider.CloudStorageProvider
import com.infomaniak.drive.data.models.AppSettings
import com.infomaniak.drive.databinding.ViewSwitchSettingsBinding
import com.infomaniak.drive.twoFactorAuthManager
import splitties.init.appCtx

class AppSecuritySettingsActivity : AppCompatActivity() {

Expand All @@ -54,7 +56,10 @@ class AppSecuritySettingsActivity : AppCompatActivity() {
// Reverse switch (before official parameter changed) by silent click
silentlyReverseSwitch(this) { shouldLock ->
AppSettings.appSecurityLock = shouldLock
if (shouldLock) AppLockManager.unlock()
if (shouldLock) {
CloudStorageProvider.setDisabled(appCtx, true)
AppLockManager.unlock()
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Infomaniak kDrive - Android
* Copyright (C) 2022-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.drive.ui.menu.settings

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.infomaniak.core.applock.AppLockManager
import com.infomaniak.core.fragmentnavigation.safelyNavigate
import com.infomaniak.core.legacy.utils.safeBinding
import com.infomaniak.drive.MatomoDrive.MatomoName
import com.infomaniak.drive.MatomoDrive.trackSettingsEvent
import com.infomaniak.drive.R
import com.infomaniak.drive.data.documentprovider.CloudStorageProvider
import com.infomaniak.drive.data.models.AppSettings
import com.infomaniak.drive.databinding.FragmentSettingsSecurityBinding
import com.infomaniak.drive.extensions.enableEdgeToEdge
import splitties.init.appCtx

class SecuritySettingsFragment : Fragment() {

private var binding: FragmentSettingsSecurityBinding by safeBinding()

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return FragmentSettingsSecurityBinding.inflate(inflater, container, false).also { binding = it }.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) = with(binding) {
super.onViewCreated(view, savedInstanceState)

toolbar.setNavigationOnClickListener {
findNavController().popBackStack()
}

appSecurity.apply {
if (AppLockManager.hasBiometrics()) {
isVisible = true
setOnClickListener {
trackSettingsEvent(MatomoName.LockApp)
safelyNavigate(R.id.appSecurityActivity)
}
} else {
isGone = true
}
}
contentProviderSwitch.isChecked = !CloudStorageProvider.isDisabled(appCtx)

contentProviderSwitch.setOnCheckedChangeListener { _, isChecked ->
CloudStorageProvider.setDisabled(appCtx, disabled = !isChecked)
}

binding.root.enableEdgeToEdge()
}

override fun onResume() = with(binding) {
super.onResume()
appSecurity.endText = getString(if (AppSettings.appSecurityLock) R.string.allActivated else R.string.allDisabled)
contentProviderSwitch.isChecked = !CloudStorageProvider.isDisabled(appCtx)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,12 @@ import androidx.activity.result.contract.ActivityResultContracts.StartActivityFo
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatDelegate
import androidx.collection.arrayMapOf
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.infomaniak.core.applock.AppLockManager
import com.infomaniak.core.auth.room.UserDatabase
import com.infomaniak.core.bugtracker.BugTrackerActivity
import com.infomaniak.core.bugtracker.BugTrackerActivityArgs
Expand Down Expand Up @@ -93,17 +91,7 @@ class SettingsFragment : Fragment() {
syncPicture.setOnClickListener { safelyNavigate(R.id.syncSettingsActivity) }
themeSettings.setOnClickListener { openThemeSettings() }
notifications.setOnClickListener { requireContext().openAppNotificationSettings() }
appSecurity.apply {
if (AppLockManager.hasBiometrics()) {
isVisible = true
setOnClickListener {
trackSettingsEvent(MatomoName.LockApp)
safelyNavigate(R.id.appSecurityActivity)
}
} else {
isGone = true
}
}
security.setOnClickListener { safelyNavigate(R.id.securitySettingsFragment) }

initFileSync()
about.setOnClickListener { safelyNavigate(R.id.aboutSettingsFragment) }
Expand Down Expand Up @@ -215,7 +203,6 @@ class SettingsFragment : Fragment() {
override fun onResume() = with(binding) {
super.onResume()
syncPicture.endText = getString(if (AccountUtils.isEnableAppSync()) R.string.allActivated else R.string.allDisabled)
appSecurity.endText = getString(if (AppSettings.appSecurityLock) R.string.allActivated else R.string.allDisabled)
setThemeSettingsValue()
}

Expand Down
7 changes: 3 additions & 4 deletions app/src/main/res/layout/fragment_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,11 @@
app:title="@string/notificationTitle" />

<com.infomaniak.drive.ui.menu.settings.ItemSettingView
android:id="@+id/appSecurity"
android:id="@+id/security"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:endText="@string/allDisabled"
app:itemAction="text"
app:title="@string/appSecurityTitle" />
app:itemAction="chevron"
app:title="Sécurité" />

<com.infomaniak.drive.ui.menu.settings.ItemSettingView
android:id="@+id/fileSync"
Expand Down
83 changes: 83 additions & 0 deletions app/src/main/res/layout/fragment_settings_security.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Infomaniak kDrive - 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/>.
-->
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="@dimen/appBarHeight"
android:touchscreenBlocksFocus="false">

<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
app:title="Sécurité">

<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:touchscreenBlocksFocus="false"
app:layout_collapseMode="pin" />

</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>

<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

<com.google.android.material.card.MaterialCardView
style="@style/CardViewInfomaniak"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/marginStandard">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@drawable/divider"
android:orientation="vertical"
android:showDividers="middle">

<com.infomaniak.drive.ui.menu.settings.ItemSettingView
android:id="@+id/appSecurity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:endText="@string/allDisabled"
app:itemAction="text"
app:title="@string/appSecurityTitle" />

<com.infomaniak.drive.ui.menu.settings.ItemSettingView
android:id="@+id/contentProviderSwitch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:itemAction="toggle"
app:title="@string/fileProviderExtensionTitle"
app:description="@string/fileProviderExtensionDescription" />

</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
10 changes: 10 additions & 0 deletions app/src/main/res/navigation/main_navigation.xml
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,9 @@
<action
android:id="@+id/action_settingsFragment_to_syncOfflineSelectBottomSheetDialog"
app:destination="@id/syncOfflineSelectBottomSheetDialog" />
<action
android:id="@+id/action_settingsFragment_to_securitySettingsFragment"
app:destination="@id/securitySettingsFragment" />
</fragment>

<activity
Expand All @@ -562,6 +565,13 @@
android:label="AppSecurityActivity"
tools:layout="@layout/view_switch_settings" />

<fragment
android:id="@+id/securitySettingsFragment"
android:name="com.infomaniak.drive.ui.menu.settings.SecuritySettingsFragment"
android:label="securitySettingsFragment"
tools:layout="@layout/fragment_settings_security">
</fragment>

<fragment
android:id="@+id/aboutSettingsFragment"
android:name="com.infomaniak.drive.ui.menu.settings.AboutSettingsFragment"
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-da/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,9 @@
</plurals>
<string name="fileListTitle">Filer</string>
<string name="filePermissionTitle">Vælg rettighed</string>
<string name="fileProviderExtensionDescription">Hvis denne indstilling deaktiveres, vil kDrive ikke længere være tilgængelig i Filer-applikationen og i tredjepartsapplikationer.</string>
<string name="fileProviderExtensionError">Du har deaktiveret visning af filer fra kDrive. Du kan aktivere det igen i appens indstillinger.</string>
<string name="fileProviderExtensionTitle">Vis i Filer</string>
<string name="fileShareAddMessage">Tilføj en besked til gæster (valgfrit)</string>
<string name="fileShareDetailsFileTitle">Deling og rettigheder for fil %s</string>
<string name="fileShareDetailsFolderTitle">Deling og rettigheder for mappe %s</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,9 @@
</plurals>
<string name="fileListTitle">Dateien</string>
<string name="filePermissionTitle">Recht auswählen</string>
<string name="fileProviderExtensionDescription">Wenn diese Option deaktiviert ist, ist kDrive in der Anwendung Dateien und in Anwendungen von Drittanbietern nicht mehr verfügbar.</string>
<string name="fileProviderExtensionError">Sie haben die Dateianzeige aus kDrive deaktiviert. Sie können sie in den App-Einstellungen wieder aktivieren.</string>
<string name="fileProviderExtensionTitle">Ansicht in Dateien</string>
<string name="fileShareAddMessage">Nachricht an Gäste hinzufügen (fakultativ)</string>
<string name="fileShareDetailsFileTitle">Freigabe und Rechte der Datei %s</string>
<string name="fileShareDetailsFolderTitle">Freigabe und Rechte des Ordners %s</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-el/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,9 @@
</plurals>
<string name="fileListTitle">Αρχεία</string>
<string name="filePermissionTitle">Επιλέξτε το δικαίωμα</string>
<string name="fileProviderExtensionDescription">Εάν αυτή η επιλογή απενεργοποιηθεί, το kDrive δεν θα είναι πλέον διαθέσιμο στην εφαρμογή Αρχεία και σε εφαρμογές τρίτων.</string>
<string name="fileProviderExtensionError">Έχετε απενεργοποιήσει την εμφάνιση αρχείων από το kDrive. Μπορείτε να την ενεργοποιήσετε ξανά στις ρυθμίσεις της εφαρμογής.</string>
<string name="fileProviderExtensionTitle">Εμφάνιση στα Αρχεία</string>
<string name="fileShareAddMessage">Προσθήκη μηνύματος για επισκέπτες (προαιρετικό)</string>
<string name="fileShareDetailsFileTitle">Κοινή χρήση και δικαιώματα του αρχείου %s</string>
<string name="fileShareDetailsFolderTitle">Κοινή χρήση και δικαιώματα του φακέλου %s</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,9 @@
</plurals>
<string name="fileListTitle">Archivos</string>
<string name="filePermissionTitle">Seleccionar el derecho</string>
<string name="fileProviderExtensionDescription">Si se desactiva esta opción, kDrive dejará de estar disponible en la aplicación Archivos y en las aplicaciones de terceros.</string>
<string name="fileProviderExtensionError">Ha desactivado la visualización de archivos desde kDrive. Puede volver a activarla en la configuración de la aplicación.</string>
<string name="fileProviderExtensionTitle">Ver en Archivos</string>
<string name="fileShareAddMessage">Añadir un mensaje para los invitados (opcional)</string>
<string name="fileShareDetailsFileTitle">Uso compartido y derechos del archivo %s</string>
<string name="fileShareDetailsFolderTitle">Uso compartido y derechos de la carpeta %s</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-fi/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,9 @@
</plurals>
<string name="fileListTitle">Tiedostot</string>
<string name="filePermissionTitle">Valitse oikeus</string>
<string name="fileProviderExtensionDescription">Jos tämä asetus on poistettu käytöstä, kDrive ei ole enää käytettävissä Tiedostot-sovelluksessa eikä kolmannen osapuolen sovelluksissa.</string>
<string name="fileProviderExtensionError">Olet ottanut tiedostojen näytön pois käytöstä kDrivesta. Voit ottaa sen uudelleen käyttöön sovelluksen asetuksissa.</string>
<string name="fileProviderExtensionTitle">Näytä Tiedostot-sovelluksessa</string>
<string name="fileShareAddMessage">Lisää viesti vieraille (valinnainen)</string>
<string name="fileShareDetailsFileTitle">Tiedoston %s jakaminen ja oikeudet</string>
<string name="fileShareDetailsFolderTitle">Kansion %s jakaminen ja oikeudet</string>
Expand Down
Loading
Loading