From 79e4a435dab4cbf58b7e6c6e12275e8879dbd3ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Be=C5=88o?= Date: Sun, 24 Jul 2022 16:53:33 +0200 Subject: [PATCH 1/4] Add privacy setting to disable personalized learning by the keyboard --- changelog.d/6633.feature | 1 + library/ui-strings/src/main/res/values/strings.xml | 3 +++ .../app/features/home/room/detail/TimelineFragment.kt | 2 ++ .../home/room/detail/composer/ComposerEditText.kt | 9 +++++++++ .../im/vector/app/features/settings/VectorPreferences.kt | 7 +++++++ .../main/res/xml/vector_settings_security_privacy.xml | 6 ++++++ 6 files changed, 28 insertions(+) create mode 100644 changelog.d/6633.feature diff --git a/changelog.d/6633.feature b/changelog.d/6633.feature new file mode 100644 index 0000000000..b52e9d95bc --- /dev/null +++ b/changelog.d/6633.feature @@ -0,0 +1 @@ +Add privacy setting to disable personalized learning by the keyboard diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index d8f6222acf..4f1917f0df 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -2578,6 +2578,9 @@ Prevent screenshots of the application Enabling this setting adds the FLAG_SECURE to all Activities. Restart the application for the change to take effect. + Incognito keyboard + Request that the keyboard should not update any personalized data such as typing history and dictionary based on what the user typed. Some keyboards may not respect this setting. + Could not save media file Set a new account password… diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index bba607eeb4..0a8ae775a9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -1536,6 +1536,8 @@ class TimelineFragment : observerUserTyping() + composerEditText.setUseIncognitoKeyboard(vectorPreferences.useIncognitoKeyboard()) + if (vectorPreferences.sendMessageWithEnter()) { // imeOptions="actionSend" only works with single line, so we remove multiline inputType composerEditText.inputType = composerEditText.inputType and EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE.inv() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt index c751053cdf..6f09d25869 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt @@ -79,6 +79,11 @@ class ComposerEditText @JvmOverloads constructor( return ic } + /** Set whether the keyboard should disable personalized learning. */ + fun setUseIncognitoKeyboard(useIncognitoKeyboard: Boolean) { + imeOptions = if (useIncognitoKeyboard) imeOptions or INCOGNITO_KEYBOARD_IME else imeOptions and INCOGNITO_KEYBOARD_IME.inv() + } + init { addTextChangedListener( object : SimpleTextWatcher() { @@ -116,4 +121,8 @@ class ComposerEditText @JvmOverloads constructor( } ) } + + companion object { + const val INCOGNITO_KEYBOARD_IME = EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING + } } diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt index 16d3210b45..b7812b9ebb 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt @@ -87,6 +87,7 @@ class VectorPreferences @Inject constructor( const val SETTINGS_INTEGRATION_MANAGER_UI_URL_KEY = "SETTINGS_INTEGRATION_MANAGER_UI_URL_KEY" const val SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY = "SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY" const val SETTINGS_PERSISTED_SPACE_BACKSTACK = "SETTINGS_PERSISTED_SPACE_BACKSTACK" + const val SETTINGS_SECURITY_INCOGNITO_KEYBOARD_PREFERENCE_KEY = "SETTINGS_SECURITY_INCOGNITO_KEYBOARD_PREFERENCE_KEY" const val SETTINGS_CRYPTOGRAPHY_HS_ADMIN_DISABLED_E2E_DEFAULT = "SETTINGS_CRYPTOGRAPHY_HS_ADMIN_DISABLED_E2E_DEFAULT" // const val SETTINGS_SECURE_BACKUP_RESET_PREFERENCE_KEY = "SETTINGS_SECURE_BACKUP_RESET_PREFERENCE_KEY" @@ -288,6 +289,7 @@ class VectorPreferences @Inject constructor( SETTINGS_USE_RAGE_SHAKE_KEY, SETTINGS_SECURITY_USE_FLAG_SECURE, + SETTINGS_SECURITY_INCOGNITO_KEYBOARD_PREFERENCE_KEY, ShortcutsHandler.SHARED_PREF_KEY, ) @@ -969,6 +971,11 @@ class VectorPreferences @Inject constructor( return defaultPrefs.getBoolean(SETTINGS_SECURITY_USE_FLAG_SECURE, false) } + /** Whether the keyboard should disable personalized learning. */ + fun useIncognitoKeyboard(): Boolean { + return defaultPrefs.getBoolean(SETTINGS_SECURITY_INCOGNITO_KEYBOARD_PREFERENCE_KEY, false) + } + /** * The user enable protecting app access with pin code. * Currently we use the pin code store to know if the pin is enabled, so this is not used diff --git a/vector/src/main/res/xml/vector_settings_security_privacy.xml b/vector/src/main/res/xml/vector_settings_security_privacy.xml index 1e8997e9c8..78e1ba42a8 100644 --- a/vector/src/main/res/xml/vector_settings_security_privacy.xml +++ b/vector/src/main/res/xml/vector_settings_security_privacy.xml @@ -141,6 +141,12 @@ android:summary="@string/settings_security_application_protection_summary" android:title="@string/settings_security_application_protection_title" /> + + Date: Sun, 25 Sep 2022 13:56:59 +0200 Subject: [PATCH 2/4] Improve summary text of Incognito Keyboard setting --- library/ui-strings/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 4f1917f0df..040510fba8 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -2579,7 +2579,7 @@ Enabling this setting adds the FLAG_SECURE to all Activities. Restart the application for the change to take effect. Incognito keyboard - Request that the keyboard should not update any personalized data such as typing history and dictionary based on what the user typed. Some keyboards may not respect this setting. + "Request that the keyboard should not update any personalized data such as typing history and dictionary based on what you've typed in conversations. Notice that some keyboards may not respect this setting." Could not save media file Set a new account password… From e5cf431cc70d9c8e6e2a75748bcd64207f7ff135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Be=C5=88o?= Date: Sun, 25 Sep 2022 14:42:07 +0200 Subject: [PATCH 3/4] Apply imeOptions to ComposerEditText without overriding previously set options --- .../home/room/detail/TimelineFragment.kt | 7 +------ .../room/detail/composer/ComposerEditText.kt | 21 ++++++++++++++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 0a8ae775a9..de2f9891e1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -1537,12 +1537,7 @@ class TimelineFragment : observerUserTyping() composerEditText.setUseIncognitoKeyboard(vectorPreferences.useIncognitoKeyboard()) - - if (vectorPreferences.sendMessageWithEnter()) { - // imeOptions="actionSend" only works with single line, so we remove multiline inputType - composerEditText.inputType = composerEditText.inputType and EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE.inv() - composerEditText.imeOptions = EditorInfo.IME_ACTION_SEND - } + composerEditText.setSendMessageWithEnter(vectorPreferences.sendMessageWithEnter()) composerEditText.setOnEditorActionListener { v, actionId, keyEvent -> val imeActionId = actionId and EditorInfo.IME_MASK_ACTION diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt index 6f09d25869..911261d46f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt @@ -81,7 +81,22 @@ class ComposerEditText @JvmOverloads constructor( /** Set whether the keyboard should disable personalized learning. */ fun setUseIncognitoKeyboard(useIncognitoKeyboard: Boolean) { - imeOptions = if (useIncognitoKeyboard) imeOptions or INCOGNITO_KEYBOARD_IME else imeOptions and INCOGNITO_KEYBOARD_IME.inv() + imeOptions = if (useIncognitoKeyboard) { + imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING + } else { + imeOptions and EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING.inv() + } + } + + /** Set whether enter should send the message or add a new line. */ + fun setSendMessageWithEnter(sendMessageWithEnter: Boolean) { + if (sendMessageWithEnter) { + inputType = inputType and EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE.inv() + imeOptions = imeOptions or EditorInfo.IME_ACTION_SEND + } else { + inputType = inputType or EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE + imeOptions = imeOptions and EditorInfo.IME_ACTION_SEND.inv() + } } init { @@ -121,8 +136,4 @@ class ComposerEditText @JvmOverloads constructor( } ) } - - companion object { - const val INCOGNITO_KEYBOARD_IME = EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING - } } From 079a2f53514f4270e530f980dd14058186ed8188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Be=C5=88o?= Date: Sun, 25 Sep 2022 14:56:20 +0200 Subject: [PATCH 4/4] Hide Incognito Keyboard setting on unsupported devices --- .../features/home/room/detail/TimelineFragment.kt | 4 +++- .../home/room/detail/composer/ComposerEditText.kt | 3 +++ .../VectorSettingsSecurityPrivacyFragment.kt | 12 ++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index de2f9891e1..853d8918a4 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -1536,7 +1536,9 @@ class TimelineFragment : observerUserTyping() - composerEditText.setUseIncognitoKeyboard(vectorPreferences.useIncognitoKeyboard()) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + composerEditText.setUseIncognitoKeyboard(vectorPreferences.useIncognitoKeyboard()) + } composerEditText.setSendMessageWithEnter(vectorPreferences.sendMessageWithEnter()) composerEditText.setOnEditorActionListener { v, actionId, keyEvent -> diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt index 911261d46f..9e88882866 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt @@ -20,10 +20,12 @@ package im.vector.app.features.home.room.detail.composer import android.content.ClipData import android.content.Context import android.net.Uri +import android.os.Build import android.text.Editable import android.util.AttributeSet import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputConnection +import androidx.annotation.RequiresApi import androidx.appcompat.widget.AppCompatEditText import androidx.core.view.OnReceiveContentListener import androidx.core.view.ViewCompat @@ -80,6 +82,7 @@ class ComposerEditText @JvmOverloads constructor( } /** Set whether the keyboard should disable personalized learning. */ + @RequiresApi(Build.VERSION_CODES.O) fun setUseIncognitoKeyboard(useIncognitoKeyboard: Boolean) { imeOptions = if (useIncognitoKeyboard) { imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt index 5cbdf114a5..87f5af67eb 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -20,6 +20,7 @@ package im.vector.app.features.settings import android.app.Activity import android.content.Intent import android.net.Uri +import android.os.Build import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -160,6 +161,10 @@ class VectorSettingsSecurityPrivacyFragment : findPreference("SETTINGS_USER_ANALYTICS_CONSENT_KEY")!! } + private val incognitoKeyboardPref by lazy { + findPreference(VectorPreferences.SETTINGS_SECURITY_INCOGNITO_KEYBOARD_PREFERENCE_KEY)!! + } + override fun onCreateRecyclerView(inflater: LayoutInflater, parent: ViewGroup, savedInstanceState: Bundle?): RecyclerView { return super.onCreateRecyclerView(inflater, parent, savedInstanceState).also { // Insert animation are really annoying the first time the list is shown @@ -275,6 +280,9 @@ class VectorSettingsSecurityPrivacyFragment : // Analytics setUpAnalytics() + // Incognito Keyboard + setUpIncognitoKeyboard() + // Pin code openPinCodeSettingsPref.setOnPreferenceClickListener { openPinCodePreferenceScreen() @@ -337,6 +345,10 @@ class VectorSettingsSecurityPrivacyFragment : } } + private fun setUpIncognitoKeyboard() { + incognitoKeyboardPref.isVisible = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + } + // Todo this should be refactored and use same state as 4S section private fun refreshXSigningStatus() { val crossSigningKeys = session.cryptoService().crossSigningService().getMyCrossSigningKeys()