diff --git a/app/src/androidTest/java/com/filestech/notes_tech/ui/secure/SansClassificationDeTexteTest.kt b/app/src/androidTest/java/com/filestech/notes_tech/ui/secure/SansClassificationDeTexteTest.kt index 1790b01..26a471d 100644 --- a/app/src/androidTest/java/com/filestech/notes_tech/ui/secure/SansClassificationDeTexteTest.kt +++ b/app/src/androidTest/java/com/filestech/notes_tech/ui/secure/SansClassificationDeTexteTest.kt @@ -5,6 +5,8 @@ import android.view.textclassifier.TextClassification import android.view.textclassifier.TextClassificationContext import android.view.textclassifier.TextClassificationManager import android.view.textclassifier.TextClassifier +import androidx.compose.foundation.ComposeFoundationFlags +import androidx.compose.foundation.ExperimentalFoundationApi import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -91,6 +93,17 @@ class SansClassificationDeTexteTest { assertThat(application.textClassifier).isNotSameInstanceAs(TextClassifier.NO_OP) } + /** + * Compose must list no other app's text action, on any version: package visibility is granted + * per app. See [sansActionsDeTexteDesAutresApps]. + */ + @OptIn(ExperimentalFoundationApi::class) + @Test + fun compose_lists_no_other_app_text_action() { + gestionnaireDeLActivite() // the activity has run its onCreate + assertThat(ComposeFoundationFlags.isSmartSelectionEnabled).isFalse() + } + private fun gestionnaireDeLActivite(): TextClassificationManager { var gestionnaire: TextClassificationManager? = null scene!!.onActivity { gestionnaire = it.getSystemService(TextClassificationManager::class.java) } diff --git a/app/src/main/java/com/filestech/notes_tech/ui/MainActivity.kt b/app/src/main/java/com/filestech/notes_tech/ui/MainActivity.kt index 869ad56..ea01508 100644 --- a/app/src/main/java/com/filestech/notes_tech/ui/MainActivity.kt +++ b/app/src/main/java/com/filestech/notes_tech/ui/MainActivity.kt @@ -46,6 +46,7 @@ import com.filestech.notes_tech.ui.panic.RecouvrementDePanique import com.filestech.notes_tech.ui.panic.activityPanicViewModel import com.filestech.notes_tech.ui.secure.LocalSecureWindow import com.filestech.notes_tech.ui.secure.SecureWindowController +import com.filestech.notes_tech.ui.secure.sansActionsDeTexteDesAutresApps import com.filestech.notes_tech.ui.secure.sansClassificationDeTexte import com.filestech.notes_tech.ui.share.PartagesRecus import com.filestech.notes_tech.ui.splash.SplashScreen @@ -108,6 +109,8 @@ class MainActivity : FragmentActivity() { // 🔴 Before the first field exists: the selection toolbar's "Translate" sent the selected text // of a note to another app (3.1.1) — see `sansClassificationDeTexte`. sansClassificationDeTexte() + // Same toolbar, other door: other apps' text actions — editing entries only. + sansActionsDeTexteDesAutresApps() enableEdgeToEdge() setContent { CompositionLocalProvider( diff --git a/app/src/main/java/com/filestech/notes_tech/ui/secure/SansClassificationDeTexte.kt b/app/src/main/java/com/filestech/notes_tech/ui/secure/SansClassificationDeTexte.kt index 0b82b2c..5987f08 100644 --- a/app/src/main/java/com/filestech/notes_tech/ui/secure/SansClassificationDeTexte.kt +++ b/app/src/main/java/com/filestech/notes_tech/ui/secure/SansClassificationDeTexte.kt @@ -4,6 +4,8 @@ import android.app.Activity import android.os.Build import android.view.textclassifier.TextClassificationManager import android.view.textclassifier.TextClassifier +import androidx.compose.foundation.ComposeFoundationFlags +import androidx.compose.foundation.ExperimentalFoundationApi /** * 🔴 **No text classifier in this app** — 3.1.1, measured on 2026-10-29. @@ -33,3 +35,25 @@ internal fun Activity.sansClassificationDeTexte() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return getSystemService(TextClassificationManager::class.java)?.setTextClassifier(TextClassifier.NO_OP) } + +/** + * 🔴 **No other app's text action in Compose's selection toolbar** — measured on 2026-10-31. + * + * Compose foundation 1.12 adds to that toolbar one entry per app that declares `ACTION_PROCESS_TEXT` + * and that this app can see (`ProcessText_android`, read in the bytecode) — any app may declare one, + * under any name, and one tap hands it the selected text, in the title, search and vault fields + * alike. Removing the `` for it (audit of 2026-09-26) is not enough: before Android 11 there + * is no package visibility, every app is listed, a translator among them; from 11 on, visibility is + * granted per WHOLE app, and any app another `` of the manifest reaches is listed with all + * its text actions. + * + * [ComposeFoundationFlags.isSmartSelectionEnabled] set to `false` takes those entries — and smart + * selection, already off with the classifier — out of every Compose toolbar of the process, on every + * version: Compose's fields keep editing only, as the body's native field already does + * ([com.filestech.notes_tech.ui.editor.MenuDuChampDuCorps]). What is lost: + * reading aloud from the toolbar, still reachable through its own accessibility shortcut. + */ +@OptIn(ExperimentalFoundationApi::class) +internal fun sansActionsDeTexteDesAutresApps() { + ComposeFoundationFlags.isSmartSelectionEnabled = false +}