Merge pull request #6019 from k9mail/simplify_imap_compression_setting

Simplify IMAP compression setting
This commit is contained in:
cketti 2022-04-20 17:06:46 +02:00 committed by GitHub
commit 9dc86ba522
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 107 additions and 203 deletions

View file

@ -2,11 +2,9 @@ package com.fsck.k9
import com.fsck.k9.backend.api.SyncConfig.ExpungePolicy import com.fsck.k9.backend.api.SyncConfig.ExpungePolicy
import com.fsck.k9.mail.Address import com.fsck.k9.mail.Address
import com.fsck.k9.mail.NetworkType
import com.fsck.k9.mail.ServerSettings import com.fsck.k9.mail.ServerSettings
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
import java.util.concurrent.ConcurrentHashMap
/** /**
* Account stores all of the settings for a single account defined by the user. Each account is defined by a UUID. * Account stores all of the settings for a single account defined by the user. Each account is defined by a UUID.
@ -225,7 +223,10 @@ class Account(override val uuid: String) : BaseAccount {
@set:Synchronized @set:Synchronized
var idleRefreshMinutes = 0 var idleRefreshMinutes = 0
private val compressionMap: MutableMap<NetworkType, Boolean> = ConcurrentHashMap() @get:JvmName("useCompression")
@get:Synchronized
@set:Synchronized
var useCompression = true
@get:Synchronized @get:Synchronized
@set:Synchronized @set:Synchronized
@ -500,20 +501,6 @@ class Account(override val uuid: String) : BaseAccount {
this.sortAscending[sortType] = sortAscending this.sortAscending[sortType] = sortAscending
} }
@Synchronized
fun setCompression(networkType: NetworkType, useCompression: Boolean) {
compressionMap[networkType] = useCompression
}
@Synchronized
fun useCompression(networkType: NetworkType): Boolean {
return compressionMap[networkType] ?: return true
}
fun getCompressionMap(): Map<NetworkType, Boolean> {
return compressionMap.toMap()
}
@Synchronized @Synchronized
fun replaceIdentities(identities: List<Identity>) { fun replaceIdentities(identities: List<Identity>) {
this.identities = identities.toMutableList() this.identities = identities.toMutableList()

View file

@ -15,7 +15,6 @@ import com.fsck.k9.Account.ShowPictures
import com.fsck.k9.Account.SortType import com.fsck.k9.Account.SortType
import com.fsck.k9.Account.SpecialFolderSelection import com.fsck.k9.Account.SpecialFolderSelection
import com.fsck.k9.helper.Utility import com.fsck.k9.helper.Utility
import com.fsck.k9.mail.NetworkType
import com.fsck.k9.mailstore.StorageManager import com.fsck.k9.mailstore.StorageManager
import com.fsck.k9.preferences.Storage import com.fsck.k9.preferences.Storage
import com.fsck.k9.preferences.StorageEditor import com.fsck.k9.preferences.StorageEditor
@ -120,10 +119,7 @@ class AccountPreferenceSerializer(
isDefaultQuotedTextShown = storage.getBoolean("$accountUuid.defaultQuotedTextShown", DEFAULT_QUOTED_TEXT_SHOWN) isDefaultQuotedTextShown = storage.getBoolean("$accountUuid.defaultQuotedTextShown", DEFAULT_QUOTED_TEXT_SHOWN)
isReplyAfterQuote = storage.getBoolean("$accountUuid.replyAfterQuote", DEFAULT_REPLY_AFTER_QUOTE) isReplyAfterQuote = storage.getBoolean("$accountUuid.replyAfterQuote", DEFAULT_REPLY_AFTER_QUOTE)
isStripSignature = storage.getBoolean("$accountUuid.stripSignature", DEFAULT_STRIP_SIGNATURE) isStripSignature = storage.getBoolean("$accountUuid.stripSignature", DEFAULT_STRIP_SIGNATURE)
for (type in NetworkType.values()) { useCompression = storage.getBoolean("$accountUuid.useCompression", true)
val useCompression = storage.getBoolean("$accountUuid.useCompression.$type", true)
setCompression(type, useCompression)
}
importedAutoExpandFolder = storage.getString("$accountUuid.autoExpandFolderName", null) importedAutoExpandFolder = storage.getString("$accountUuid.autoExpandFolderName", null)
@ -334,13 +330,7 @@ class AccountPreferenceSerializer(
editor.putLong("$accountUuid.lastFolderListRefreshTime", lastFolderListRefreshTime) editor.putLong("$accountUuid.lastFolderListRefreshTime", lastFolderListRefreshTime)
editor.putBoolean("$accountUuid.isFinishedSetup", isFinishedSetup) editor.putBoolean("$accountUuid.isFinishedSetup", isFinishedSetup)
val compressionMap = getCompressionMap() editor.putBoolean("$accountUuid.useCompression", useCompression)
for (type in NetworkType.values()) {
val useCompression = compressionMap[type]
if (useCompression != null) {
editor.putBoolean("$accountUuid.useCompression.$type", useCompression)
}
}
} }
saveIdentities(account, storage, editor) saveIdentities(account, storage, editor)
@ -456,10 +446,8 @@ class AccountPreferenceSerializer(
editor.remove("$accountUuid.lastSyncTime") editor.remove("$accountUuid.lastSyncTime")
editor.remove("$accountUuid.lastFolderListRefreshTime") editor.remove("$accountUuid.lastFolderListRefreshTime")
editor.remove("$accountUuid.isFinishedSetup") editor.remove("$accountUuid.isFinishedSetup")
editor.remove("$accountUuid.useCompression")
for (type in NetworkType.values()) {
editor.remove("$accountUuid.useCompression." + type.name)
}
deleteIdentities(account, storage, editor) deleteIdentities(account, storage, editor)
// TODO: Remove preference settings that may exist for individual folders in the account. // TODO: Remove preference settings that may exist for individual folders in the account.
} }

View file

@ -207,13 +207,16 @@ public class AccountSettingsDescriptions {
new V(53, new StringSetting(null)) new V(53, new StringSetting(null))
)); ));
s.put("useCompression.MOBILE", Settings.versions( s.put("useCompression.MOBILE", Settings.versions(
new V(1, new BooleanSetting(true)) new V(1, new BooleanSetting(true)),
new V(81, null)
)); ));
s.put("useCompression.OTHER", Settings.versions( s.put("useCompression.OTHER", Settings.versions(
new V(1, new BooleanSetting(true)) new V(1, new BooleanSetting(true)),
new V(81, null)
)); ));
s.put("useCompression.WIFI", Settings.versions( s.put("useCompression.WIFI", Settings.versions(
new V(1, new BooleanSetting(true)) new V(1, new BooleanSetting(true)),
new V(81, null)
)); ));
s.put("vibrate", Settings.versions( s.put("vibrate", Settings.versions(
new V(1, new BooleanSetting(false)) new V(1, new BooleanSetting(false))
@ -270,6 +273,9 @@ public class AccountSettingsDescriptions {
s.put("notificationLight", Settings.versions( s.put("notificationLight", Settings.versions(
new V(80, new EnumSetting<>(NotificationLight.class, NotificationLight.Disabled)) new V(80, new EnumSetting<>(NotificationLight.class, NotificationLight.Disabled))
)); ));
s.put("useCompression", Settings.versions(
new V(81, new BooleanSetting(true))
));
// note that there is no setting for openPgpProvider, because this will have to be set up together // note that there is no setting for openPgpProvider, because this will have to be set up together
// with the actual provider after import anyways. // with the actual provider after import anyways.
@ -280,6 +286,7 @@ public class AccountSettingsDescriptions {
u.put(54, new SettingsUpgraderV54()); u.put(54, new SettingsUpgraderV54());
u.put(74, new SettingsUpgraderV74()); u.put(74, new SettingsUpgraderV74());
u.put(80, new SettingsUpgraderV80()); u.put(80, new SettingsUpgraderV80());
u.put(81, new SettingsUpgraderV81());
UPGRADERS = Collections.unmodifiableMap(u); UPGRADERS = Collections.unmodifiableMap(u);
} }
@ -546,4 +553,22 @@ public class AccountSettingsDescriptions {
return SetsKt.setOf("led", "ledColor"); return SetsKt.setOf("led", "ledColor");
} }
} }
/**
* Rewrite the per-network type IMAP compression settings to a single setting.
*/
private static class SettingsUpgraderV81 implements SettingsUpgrader {
@Override
public Set<String> upgrade(Map<String, Object> settings) {
Boolean useCompressionWifi = (Boolean) settings.get("useCompression.WIFI");
Boolean useCompressionMobile = (Boolean) settings.get("useCompression.MOBILE");
Boolean useCompressionOther = (Boolean) settings.get("useCompression.OTHER");
boolean useCompression = useCompressionWifi != null && useCompressionMobile != null &&
useCompressionOther != null && useCompressionWifi && useCompressionMobile && useCompressionOther;
settings.put("useCompression", useCompression);
return SetsKt.setOf("useCompression.WIFI", "useCompression.MOBILE", "useCompression.OTHER");
}
}
} }

View file

@ -36,7 +36,7 @@ public class Settings {
* *
* @see SettingsExporter * @see SettingsExporter
*/ */
public static final int VERSION = 80; public static final int VERSION = 81;
static Map<String, Object> validate(int version, Map<String, TreeMap<Integer, SettingsDescription>> settings, static Map<String, Object> validate(int version, Map<String, TreeMap<Integer, SettingsDescription>> settings,
Map<String, String> importedSettings, boolean useDefaultValues) { Map<String, String> importedSettings, boolean useDefaultValues) {

View file

@ -1,13 +1,10 @@
package com.fsck.k9.backends package com.fsck.k9.backends
import android.content.Context
import android.net.ConnectivityManager
import com.fsck.k9.Account import com.fsck.k9.Account
import com.fsck.k9.backend.BackendFactory import com.fsck.k9.backend.BackendFactory
import com.fsck.k9.backend.api.Backend import com.fsck.k9.backend.api.Backend
import com.fsck.k9.backend.imap.ImapBackend import com.fsck.k9.backend.imap.ImapBackend
import com.fsck.k9.backend.imap.ImapPushConfigProvider import com.fsck.k9.backend.imap.ImapPushConfigProvider
import com.fsck.k9.mail.NetworkType
import com.fsck.k9.mail.oauth.OAuth2TokenProvider import com.fsck.k9.mail.oauth.OAuth2TokenProvider
import com.fsck.k9.mail.power.PowerManager import com.fsck.k9.mail.power.PowerManager
import com.fsck.k9.mail.ssl.TrustedSocketFactory import com.fsck.k9.mail.ssl.TrustedSocketFactory
@ -22,7 +19,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
class ImapBackendFactory( class ImapBackendFactory(
private val context: Context,
private val accountManager: AccountManager, private val accountManager: AccountManager,
private val powerManager: PowerManager, private val powerManager: PowerManager,
private val idleRefreshManager: IdleRefreshManager, private val idleRefreshManager: IdleRefreshManager,
@ -54,7 +50,6 @@ class ImapBackendFactory(
account.incomingServerSettings, account.incomingServerSettings,
config, config,
trustedSocketFactory, trustedSocketFactory,
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager,
oAuth2TokenProvider oAuth2TokenProvider
) )
} }
@ -66,7 +61,7 @@ class ImapBackendFactory(
override fun isSubscribedFoldersOnly() = account.isSubscribedFoldersOnly override fun isSubscribedFoldersOnly() = account.isSubscribedFoldersOnly
override fun useCompression(type: NetworkType) = account.useCompression(type) override fun useCompression() = account.useCompression
} }
} }

View file

@ -20,7 +20,6 @@ val backendsModule = module {
} }
single { single {
ImapBackendFactory( ImapBackendFactory(
context = get(),
accountManager = get(), accountManager = get(),
powerManager = get(), powerManager = get(),
idleRefreshManager = get(), idleRefreshManager = get(),

View file

@ -21,7 +21,7 @@ import timber.log.Timber;
public class K9StoragePersister implements StoragePersister { public class K9StoragePersister implements StoragePersister {
private static final int DB_VERSION = 17; private static final int DB_VERSION = 18;
private static final String DB_NAME = "preferences_storage"; private static final String DB_NAME = "preferences_storage";
private final Context context; private final Context context;

View file

@ -0,0 +1,36 @@
package com.fsck.k9.preferences.migrations
import android.database.sqlite.SQLiteDatabase
/**
* Rewrite the per-network type IMAP compression settings to a single setting.
*/
class StorageMigrationTo18(
private val db: SQLiteDatabase,
private val migrationsHelper: StorageMigrationsHelper
) {
fun rewriteImapCompressionSettings() {
val accountUuidsListValue = migrationsHelper.readValue(db, "accountUuids")
if (accountUuidsListValue == null || accountUuidsListValue.isEmpty()) {
return
}
val accountUuids = accountUuidsListValue.split(",")
for (accountUuid in accountUuids) {
rewriteImapCompressionSetting(accountUuid)
}
}
private fun rewriteImapCompressionSetting(accountUuid: String) {
val useCompressionWifi = migrationsHelper.readValue(db, "$accountUuid.useCompression.WIFI").toBoolean()
val useCompressionMobile = migrationsHelper.readValue(db, "$accountUuid.useCompression.MOBILE").toBoolean()
val useCompressionOther = migrationsHelper.readValue(db, "$accountUuid.useCompression.OTHER").toBoolean()
val useCompression = useCompressionWifi && useCompressionMobile && useCompressionOther
migrationsHelper.writeValue(db, "$accountUuid.useCompression", useCompression.toString())
migrationsHelper.writeValue(db, "$accountUuid.useCompression.WIFI", null)
migrationsHelper.writeValue(db, "$accountUuid.useCompression.MOBILE", null)
migrationsHelper.writeValue(db, "$accountUuid.useCompression.OTHER", null)
}
}

View file

@ -23,5 +23,6 @@ internal object StorageMigrations {
if (oldVersion < 15) StorageMigrationTo15(db, migrationsHelper).rewriteIdleRefreshInterval() if (oldVersion < 15) StorageMigrationTo15(db, migrationsHelper).rewriteIdleRefreshInterval()
if (oldVersion < 16) StorageMigrationTo16(db, migrationsHelper).changeDefaultRegisteredNameColor() if (oldVersion < 16) StorageMigrationTo16(db, migrationsHelper).changeDefaultRegisteredNameColor()
if (oldVersion < 17) StorageMigrationTo17(db, migrationsHelper).rewriteNotificationLightSettings() if (oldVersion < 17) StorageMigrationTo17(db, migrationsHelper).rewriteNotificationLightSettings()
if (oldVersion < 18) StorageMigrationTo18(db, migrationsHelper).rewriteImapCompressionSettings()
} }
} }

View file

@ -31,13 +31,10 @@ import com.fsck.k9.helper.EmailHelper;
import com.fsck.k9.setup.ServerNameSuggester; import com.fsck.k9.setup.ServerNameSuggester;
import com.fsck.k9.ui.base.K9Activity; import com.fsck.k9.ui.base.K9Activity;
import com.fsck.k9.activity.setup.AccountSetupCheckSettings.CheckDirection; import com.fsck.k9.activity.setup.AccountSetupCheckSettings.CheckDirection;
import com.fsck.k9.controller.MessagingController;
import com.fsck.k9.helper.Utility; import com.fsck.k9.helper.Utility;
import com.fsck.k9.job.K9JobManager;
import com.fsck.k9.mail.AuthType; import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ConnectionSecurity; import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.MailServerDirection; import com.fsck.k9.mail.MailServerDirection;
import com.fsck.k9.mail.NetworkType;
import com.fsck.k9.mail.ServerSettings; import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mail.store.imap.ImapStoreSettings; import com.fsck.k9.mail.store.imap.ImapStoreSettings;
import com.fsck.k9.mail.store.webdav.WebDavStoreSettings; import com.fsck.k9.mail.store.webdav.WebDavStoreSettings;
@ -63,8 +60,6 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
private static final String STATE_SECURITY_TYPE_POSITION = "stateSecurityTypePosition"; private static final String STATE_SECURITY_TYPE_POSITION = "stateSecurityTypePosition";
private static final String STATE_AUTH_TYPE_POSITION = "authTypePosition"; private static final String STATE_AUTH_TYPE_POSITION = "authTypePosition";
private final MessagingController messagingController = DI.get(MessagingController.class);
private final K9JobManager jobManager = DI.get(K9JobManager.class);
private final AccountCreator accountCreator = DI.get(AccountCreator.class); private final AccountCreator accountCreator = DI.get(AccountCreator.class);
private final ServerNameSuggester serverNameSuggester = DI.get(ServerNameSuggester.class); private final ServerNameSuggester serverNameSuggester = DI.get(ServerNameSuggester.class);
@ -89,9 +84,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
private Button mNextButton; private Button mNextButton;
private Account mAccount; private Account mAccount;
private boolean mMakeDefault; private boolean mMakeDefault;
private CheckBox mCompressionMobile; private CheckBox useCompressionCheckBox;
private CheckBox mCompressionWifi;
private CheckBox mCompressionOther;
private CheckBox mSubscribedFoldersOnly; private CheckBox mSubscribedFoldersOnly;
private AuthTypeAdapter mAuthTypeAdapter; private AuthTypeAdapter mAuthTypeAdapter;
private ConnectionSecurity[] mConnectionSecurityChoices = ConnectionSecurity.values(); private ConnectionSecurity[] mConnectionSecurityChoices = ConnectionSecurity.values();
@ -138,9 +131,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
mWebdavAuthPathView = findViewById(R.id.webdav_auth_path); mWebdavAuthPathView = findViewById(R.id.webdav_auth_path);
mWebdavMailboxPathView = findViewById(R.id.webdav_mailbox_path); mWebdavMailboxPathView = findViewById(R.id.webdav_mailbox_path);
mNextButton = findViewById(R.id.next); mNextButton = findViewById(R.id.next);
mCompressionMobile = findViewById(R.id.compression_mobile); useCompressionCheckBox = findViewById(R.id.use_compression);
mCompressionWifi = findViewById(R.id.compression_wifi);
mCompressionOther = findViewById(R.id.compression_other);
mSubscribedFoldersOnly = findViewById(R.id.subscribed_folders_only); mSubscribedFoldersOnly = findViewById(R.id.subscribed_folders_only);
mAllowClientCertificateView = findViewById(R.id.account_allow_client_certificate); mAllowClientCertificateView = findViewById(R.id.account_allow_client_certificate);
@ -222,8 +213,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
findViewById(R.id.webdav_mailbox_alias_section).setVisibility(View.GONE); findViewById(R.id.webdav_mailbox_alias_section).setVisibility(View.GONE);
findViewById(R.id.webdav_owa_path_section).setVisibility(View.GONE); findViewById(R.id.webdav_owa_path_section).setVisibility(View.GONE);
findViewById(R.id.webdav_auth_path_section).setVisibility(View.GONE); findViewById(R.id.webdav_auth_path_section).setVisibility(View.GONE);
findViewById(R.id.compression_section).setVisibility(View.GONE); useCompressionCheckBox.setVisibility(View.GONE);
findViewById(R.id.compression_label).setVisibility(View.GONE);
mSubscribedFoldersOnly.setVisibility(View.GONE); mSubscribedFoldersOnly.setVisibility(View.GONE);
} else if (settings.type.equals(Protocols.IMAP)) { } else if (settings.type.equals(Protocols.IMAP)) {
serverLayoutView.setHint(getString(R.string.account_setup_incoming_imap_server_label)); serverLayoutView.setHint(getString(R.string.account_setup_incoming_imap_server_label));
@ -254,8 +244,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
findViewById(R.id.imap_path_prefix_section).setVisibility(View.GONE); findViewById(R.id.imap_path_prefix_section).setVisibility(View.GONE);
findViewById(R.id.account_auth_type_label).setVisibility(View.GONE); findViewById(R.id.account_auth_type_label).setVisibility(View.GONE);
findViewById(R.id.account_auth_type).setVisibility(View.GONE); findViewById(R.id.account_auth_type).setVisibility(View.GONE);
findViewById(R.id.compression_section).setVisibility(View.GONE); useCompressionCheckBox.setVisibility(View.GONE);
findViewById(R.id.compression_label).setVisibility(View.GONE);
mSubscribedFoldersOnly.setVisibility(View.GONE); mSubscribedFoldersOnly.setVisibility(View.GONE);
String path = WebDavStoreSettings.getPath(settings); String path = WebDavStoreSettings.getPath(settings);
@ -305,9 +294,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
updateAuthPlainTextFromSecurityType(settings.connectionSecurity); updateAuthPlainTextFromSecurityType(settings.connectionSecurity);
updateViewFromSecurity(); updateViewFromSecurity();
mCompressionMobile.setChecked(mAccount.useCompression(NetworkType.MOBILE)); useCompressionCheckBox.setChecked(mAccount.useCompression());
mCompressionWifi.setChecked(mAccount.useCompression(NetworkType.WIFI));
mCompressionOther.setChecked(mAccount.useCompression(NetworkType.OTHER));
if (settings.host != null) { if (settings.host != null) {
mServerView.setText(settings.host); mServerView.setText(settings.host);
@ -614,9 +601,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
mAccount.setIncomingServerSettings(settings); mAccount.setIncomingServerSettings(settings);
mAccount.setCompression(NetworkType.MOBILE, mCompressionMobile.isChecked()); mAccount.setUseCompression(useCompressionCheckBox.isChecked());
mAccount.setCompression(NetworkType.WIFI, mCompressionWifi.isChecked());
mAccount.setCompression(NetworkType.OTHER, mCompressionOther.isChecked());
mAccount.setSubscribedFoldersOnly(mSubscribedFoldersOnly.isChecked()); mAccount.setSubscribedFoldersOnly(mSubscribedFoldersOnly.isChecked());
AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.INCOMING); AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.INCOMING);

View file

@ -247,43 +247,11 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
</LinearLayout> </LinearLayout>
<TextView <CheckBox
android:id="@+id/compression_label" android:id="@+id/use_compression"
android:text="@string/account_setup_incoming_compression_label"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_marginTop="6dp" android:text="@string/account_setup_incoming_use_compression" />
style="@style/InputLabel"/>
<LinearLayout
android:id="@+id/compression_section"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox
android:id="@+id/compression_mobile"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/account_setup_incoming_mobile_label"
/>
<CheckBox
android:id="@+id/compression_wifi"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/account_setup_incoming_wifi_label"
android:contentDescription="@string/account_setup_incoming_compression_label"
/>
<CheckBox
android:id="@+id/compression_other"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/account_setup_incoming_other_label"
android:contentDescription="@string/account_setup_incoming_compression_label"
/>
</LinearLayout>
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -376,10 +376,7 @@ Please submit bug reports, contribute new features and ask questions at
<string name="account_setup_incoming_delete_policy_delete_label">Delete from server</string> <string name="account_setup_incoming_delete_policy_delete_label">Delete from server</string>
<string name="account_setup_incoming_delete_policy_markread_label">Mark as read on server</string> <string name="account_setup_incoming_delete_policy_markread_label">Mark as read on server</string>
<string name="account_setup_incoming_compression_label">Use compression on network:</string> <string name="account_setup_incoming_use_compression">Use compression</string>
<string name="account_setup_incoming_mobile_label">Mobile</string>
<string name="account_setup_incoming_wifi_label">Wi-Fi</string>
<string name="account_setup_incoming_other_label">Other</string>
<string name="account_setup_expunge_policy_label">Erase deleted messages on server</string> <string name="account_setup_expunge_policy_label">Erase deleted messages on server</string>
<string name="account_setup_expunge_policy_immediately">Immediately</string> <string name="account_setup_expunge_policy_immediately">Immediately</string>

View file

@ -1,25 +0,0 @@
package com.fsck.k9.mail;
import android.net.ConnectivityManager;
/**
* Enum for some of
* https://developer.android.com/reference/android/net/ConnectivityManager.html#TYPE_MOBILE etc.
*/
public enum NetworkType {
WIFI,
MOBILE,
OTHER;
public static NetworkType fromConnectivityManagerType(int type){
switch (type) {
case ConnectivityManager.TYPE_MOBILE:
return MOBILE;
case ConnectivityManager.TYPE_WIFI:
return WIFI;
default:
return OTHER;
}
}
}

View file

@ -2,7 +2,7 @@ package com.fsck.k9.mail.store.imap;
import com.fsck.k9.mail.AuthType; import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ConnectionSecurity; import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.NetworkType;
/** /**
* Settings source for IMAP. Implemented in order to remove coupling between {@link ImapStore} and {@link ImapConnection}. * Settings source for IMAP. Implemented in order to remove coupling between {@link ImapStore} and {@link ImapConnection}.
@ -22,7 +22,7 @@ interface ImapSettings {
String getClientCertificateAlias(); String getClientCertificateAlias();
boolean useCompression(NetworkType type); boolean useCompression();
String getPathPrefix(); String getPathPrefix();

View file

@ -1,6 +1,5 @@
package com.fsck.k9.mail.store.imap package com.fsck.k9.mail.store.imap
import android.net.ConnectivityManager
import com.fsck.k9.mail.MessagingException import com.fsck.k9.mail.MessagingException
import com.fsck.k9.mail.ServerSettings import com.fsck.k9.mail.ServerSettings
import com.fsck.k9.mail.oauth.OAuth2TokenProvider import com.fsck.k9.mail.oauth.OAuth2TokenProvider
@ -22,10 +21,9 @@ interface ImapStore {
serverSettings: ServerSettings, serverSettings: ServerSettings,
config: ImapStoreConfig, config: ImapStoreConfig,
trustedSocketFactory: TrustedSocketFactory, trustedSocketFactory: TrustedSocketFactory,
connectivityManager: ConnectivityManager,
oauthTokenProvider: OAuth2TokenProvider? oauthTokenProvider: OAuth2TokenProvider?
): ImapStore { ): ImapStore {
return RealImapStore(serverSettings, config, trustedSocketFactory, connectivityManager, oauthTokenProvider) return RealImapStore(serverSettings, config, trustedSocketFactory, oauthTokenProvider)
} }
} }
} }

View file

@ -1,9 +1,7 @@
package com.fsck.k9.mail.store.imap package com.fsck.k9.mail.store.imap
import com.fsck.k9.mail.NetworkType
interface ImapStoreConfig { interface ImapStoreConfig {
val logLabel: String val logLabel: String
fun isSubscribedFoldersOnly(): Boolean fun isSubscribedFoldersOnly(): Boolean
fun useCompression(type: NetworkType): Boolean fun useCompression(): Boolean
} }

View file

@ -27,16 +27,12 @@ import java.util.regex.Pattern;
import java.util.zip.Inflater; import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream; import java.util.zip.InflaterInputStream;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import com.fsck.k9.mail.Authentication; import com.fsck.k9.mail.Authentication;
import com.fsck.k9.mail.AuthenticationFailedException; import com.fsck.k9.mail.AuthenticationFailedException;
import com.fsck.k9.mail.CertificateValidationException; import com.fsck.k9.mail.CertificateValidationException;
import com.fsck.k9.mail.ConnectionSecurity; import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.K9MailLib; import com.fsck.k9.mail.K9MailLib;
import com.fsck.k9.mail.MessagingException; import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.NetworkType;
import com.fsck.k9.mail.filter.Base64; import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.filter.PeekableInputStream; import com.fsck.k9.mail.filter.PeekableInputStream;
import com.fsck.k9.mail.oauth.OAuth2TokenProvider; import com.fsck.k9.mail.oauth.OAuth2TokenProvider;
@ -77,7 +73,6 @@ class RealImapConnection implements ImapConnection {
private static final int LENGTH_LIMIT_WITH_CONDSTORE = 8172; private static final int LENGTH_LIMIT_WITH_CONDSTORE = 8172;
private final ConnectivityManager connectivityManager;
private final OAuth2TokenProvider oauthTokenProvider; private final OAuth2TokenProvider oauthTokenProvider;
private final TrustedSocketFactory socketFactory; private final TrustedSocketFactory socketFactory;
private final int socketConnectTimeout; private final int socketConnectTimeout;
@ -97,10 +92,9 @@ class RealImapConnection implements ImapConnection {
public RealImapConnection(ImapSettings settings, TrustedSocketFactory socketFactory, public RealImapConnection(ImapSettings settings, TrustedSocketFactory socketFactory,
ConnectivityManager connectivityManager, OAuth2TokenProvider oauthTokenProvider, int connectionGeneration) { OAuth2TokenProvider oauthTokenProvider, int connectionGeneration) {
this.settings = settings; this.settings = settings;
this.socketFactory = socketFactory; this.socketFactory = socketFactory;
this.connectivityManager = connectivityManager;
this.oauthTokenProvider = oauthTokenProvider; this.oauthTokenProvider = oauthTokenProvider;
this.socketConnectTimeout = SOCKET_CONNECT_TIMEOUT; this.socketConnectTimeout = SOCKET_CONNECT_TIMEOUT;
this.socketReadTimeout = SOCKET_READ_TIMEOUT; this.socketReadTimeout = SOCKET_READ_TIMEOUT;
@ -108,12 +102,10 @@ class RealImapConnection implements ImapConnection {
} }
public RealImapConnection(ImapSettings settings, TrustedSocketFactory socketFactory, public RealImapConnection(ImapSettings settings, TrustedSocketFactory socketFactory,
ConnectivityManager connectivityManager, OAuth2TokenProvider oauthTokenProvider, OAuth2TokenProvider oauthTokenProvider, int socketConnectTimeout, int socketReadTimeout,
int socketConnectTimeout, int socketReadTimeout,
int connectionGeneration) { int connectionGeneration) {
this.settings = settings; this.settings = settings;
this.socketFactory = socketFactory; this.socketFactory = socketFactory;
this.connectivityManager = connectivityManager;
this.oauthTokenProvider = oauthTokenProvider; this.oauthTokenProvider = oauthTokenProvider;
this.socketConnectTimeout = socketConnectTimeout; this.socketConnectTimeout = socketConnectTimeout;
this.socketReadTimeout = socketReadTimeout; this.socketReadTimeout = socketReadTimeout;
@ -577,32 +569,11 @@ class RealImapConnection implements ImapConnection {
} }
private void enableCompressionIfRequested() throws IOException, MessagingException { private void enableCompressionIfRequested() throws IOException, MessagingException {
if (hasCapability(Capabilities.COMPRESS_DEFLATE) && shouldEnableCompression()) { if (hasCapability(Capabilities.COMPRESS_DEFLATE) && settings.useCompression()) {
enableCompression(); enableCompression();
} }
} }
private boolean shouldEnableCompression() {
boolean useCompression = true;
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null) {
int type = networkInfo.getType();
if (K9MailLib.isDebug()) {
Timber.d("On network type %s", type);
}
NetworkType networkType = NetworkType.fromConnectivityManagerType(type);
useCompression = settings.useCompression(networkType);
}
if (K9MailLib.isDebug()) {
Timber.d("useCompression: %b", useCompression);
}
return useCompression;
}
private void enableCompression() throws IOException, MessagingException { private void enableCompression() throws IOException, MessagingException {
try { try {
executeSimpleCommand(Commands.COMPRESS_DEFLATE); executeSimpleCommand(Commands.COMPRESS_DEFLATE);

View file

@ -13,7 +13,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import android.net.ConnectivityManager;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.fsck.k9.mail.AuthType; import com.fsck.k9.mail.AuthType;
@ -21,7 +20,6 @@ import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.Flag; import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.FolderType; import com.fsck.k9.mail.FolderType;
import com.fsck.k9.mail.MessagingException; import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.NetworkType;
import com.fsck.k9.mail.ServerSettings; import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mail.oauth.OAuth2TokenProvider; import com.fsck.k9.mail.oauth.OAuth2TokenProvider;
import com.fsck.k9.mail.ssl.TrustedSocketFactory; import com.fsck.k9.mail.ssl.TrustedSocketFactory;
@ -38,7 +36,6 @@ class RealImapStore implements ImapStore, ImapConnectionManager, InternalImapSto
private final ImapStoreConfig config; private final ImapStoreConfig config;
private final TrustedSocketFactory trustedSocketFactory; private final TrustedSocketFactory trustedSocketFactory;
private Set<Flag> permanentFlagsIndex = EnumSet.noneOf(Flag.class); private Set<Flag> permanentFlagsIndex = EnumSet.noneOf(Flag.class);
private ConnectivityManager connectivityManager;
private OAuth2TokenProvider oauthTokenProvider; private OAuth2TokenProvider oauthTokenProvider;
private String host; private String host;
@ -57,8 +54,7 @@ class RealImapStore implements ImapStore, ImapConnectionManager, InternalImapSto
public RealImapStore(ServerSettings serverSettings, ImapStoreConfig config, public RealImapStore(ServerSettings serverSettings, ImapStoreConfig config,
TrustedSocketFactory trustedSocketFactory, ConnectivityManager connectivityManager, TrustedSocketFactory trustedSocketFactory, OAuth2TokenProvider oauthTokenProvider) {
OAuth2TokenProvider oauthTokenProvider) {
this.config = config; this.config = config;
this.trustedSocketFactory = trustedSocketFactory; this.trustedSocketFactory = trustedSocketFactory;
@ -66,7 +62,6 @@ class RealImapStore implements ImapStore, ImapConnectionManager, InternalImapSto
port = serverSettings.port; port = serverSettings.port;
connectionSecurity = serverSettings.connectionSecurity; connectionSecurity = serverSettings.connectionSecurity;
this.connectivityManager = connectivityManager;
this.oauthTokenProvider = oauthTokenProvider; this.oauthTokenProvider = oauthTokenProvider;
authType = serverSettings.authenticationType; authType = serverSettings.authenticationType;
@ -327,7 +322,6 @@ class RealImapStore implements ImapStore, ImapConnectionManager, InternalImapSto
return new RealImapConnection( return new RealImapConnection(
new StoreImapSettings(), new StoreImapSettings(),
trustedSocketFactory, trustedSocketFactory,
connectivityManager,
oauthTokenProvider, oauthTokenProvider,
connectionGeneration); connectionGeneration);
} }
@ -382,8 +376,8 @@ class RealImapStore implements ImapStore, ImapConnectionManager, InternalImapSto
} }
@Override @Override
public boolean useCompression(final NetworkType type) { public boolean useCompression() {
return config.useCompression(type); return config.useCompression();
} }
@Override @Override

View file

@ -6,7 +6,6 @@ import java.net.UnknownHostException;
import java.util.List; import java.util.List;
import android.app.Activity; import android.app.Activity;
import android.net.ConnectivityManager;
import com.fsck.k9.mail.AuthType; import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.AuthenticationFailedException; import com.fsck.k9.mail.AuthenticationFailedException;
@ -33,7 +32,6 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
@RunWith(K9LibRobolectricTestRunner.class) @RunWith(K9LibRobolectricTestRunner.class)
@ -53,14 +51,12 @@ public class RealImapConnectionTest {
private TrustedSocketFactory socketFactory; private TrustedSocketFactory socketFactory;
private ConnectivityManager connectivityManager;
private OAuth2TokenProvider oAuth2TokenProvider; private OAuth2TokenProvider oAuth2TokenProvider;
private SimpleImapSettings settings; private SimpleImapSettings settings;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
connectivityManager = mock(ConnectivityManager.class);
oAuth2TokenProvider = createOAuth2TokenProvider(); oAuth2TokenProvider = createOAuth2TokenProvider();
socketFactory = TestTrustedSocketFactory.newInstance(); socketFactory = TestTrustedSocketFactory.newInstance();
@ -619,8 +615,7 @@ public class RealImapConnectionTest {
public void open_withConnectionError_shouldThrow() throws Exception { public void open_withConnectionError_shouldThrow() throws Exception {
settings.setHost("127.1.2.3"); settings.setHost("127.1.2.3");
settings.setPort(143); settings.setPort(143);
ImapConnection imapConnection = createImapConnection( ImapConnection imapConnection = createImapConnection(settings, socketFactory, oAuth2TokenProvider);
settings, socketFactory, connectivityManager, oAuth2TokenProvider);
try { try {
imapConnection.open(); imapConnection.open();
@ -635,8 +630,7 @@ public class RealImapConnectionTest {
public void open_withInvalidHostname_shouldThrow() throws Exception { public void open_withInvalidHostname_shouldThrow() throws Exception {
settings.setHost("host name"); settings.setHost("host name");
settings.setPort(143); settings.setPort(143);
ImapConnection imapConnection = createImapConnection( ImapConnection imapConnection = createImapConnection(settings, socketFactory, oAuth2TokenProvider);
settings, socketFactory, connectivityManager, oAuth2TokenProvider);
try { try {
imapConnection.open(); imapConnection.open();
@ -826,8 +820,7 @@ public class RealImapConnectionTest {
@Test @Test
public void isConnected_withoutPreviousOpen_shouldReturnFalse() throws Exception { public void isConnected_withoutPreviousOpen_shouldReturnFalse() throws Exception {
ImapConnection imapConnection = createImapConnection( ImapConnection imapConnection = createImapConnection(settings, socketFactory, oAuth2TokenProvider);
settings, socketFactory, connectivityManager, oAuth2TokenProvider);
boolean result = imapConnection.isConnected(); boolean result = imapConnection.isConnected();
@ -863,8 +856,7 @@ public class RealImapConnectionTest {
@Test @Test
public void close_withoutOpen_shouldNotThrow() throws Exception { public void close_withoutOpen_shouldNotThrow() throws Exception {
ImapConnection imapConnection = createImapConnection( ImapConnection imapConnection = createImapConnection(settings, socketFactory, oAuth2TokenProvider);
settings, socketFactory, connectivityManager, oAuth2TokenProvider);
imapConnection.close(); imapConnection.close();
} }
@ -973,8 +965,8 @@ public class RealImapConnectionTest {
} }
private ImapConnection createImapConnection(ImapSettings settings, TrustedSocketFactory socketFactory, private ImapConnection createImapConnection(ImapSettings settings, TrustedSocketFactory socketFactory,
ConnectivityManager connectivityManager, OAuth2TokenProvider oAuth2TokenProvider) { OAuth2TokenProvider oAuth2TokenProvider) {
return new RealImapConnection(settings, socketFactory, connectivityManager, oAuth2TokenProvider, return new RealImapConnection(settings, socketFactory, oAuth2TokenProvider,
SOCKET_CONNECT_TIMEOUT, SOCKET_READ_TIMEOUT, 1); SOCKET_CONNECT_TIMEOUT, SOCKET_READ_TIMEOUT, 1);
} }
@ -982,7 +974,7 @@ public class RealImapConnectionTest {
server.start(); server.start();
settings.setHost(server.getHost()); settings.setHost(server.getHost());
settings.setPort(server.getPort()); settings.setPort(server.getPort());
return createImapConnection(settings, socketFactory, connectivityManager, oAuth2TokenProvider); return createImapConnection(settings, socketFactory, oAuth2TokenProvider);
} }
private ImapConnection simpleOpen(MockImapServer server) throws Exception { private ImapConnection simpleOpen(MockImapServer server) throws Exception {

View file

@ -12,8 +12,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import android.net.ConnectivityManager;
import com.fsck.k9.mail.AuthType; import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ConnectionSecurity; import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.FolderType; import com.fsck.k9.mail.FolderType;
@ -47,10 +45,9 @@ public class RealImapStoreTest {
public void setUp() throws Exception { public void setUp() throws Exception {
ServerSettings serverSettings = createServerSettings(); ServerSettings serverSettings = createServerSettings();
TrustedSocketFactory trustedSocketFactory = mock(TrustedSocketFactory.class); TrustedSocketFactory trustedSocketFactory = mock(TrustedSocketFactory.class);
ConnectivityManager connectivityManager = mock(ConnectivityManager.class);
OAuth2TokenProvider oauth2TokenProvider = mock(OAuth2TokenProvider.class); OAuth2TokenProvider oauth2TokenProvider = mock(OAuth2TokenProvider.class);
imapStore = new TestImapStore(serverSettings, config, trustedSocketFactory, connectivityManager, imapStore = new TestImapStore(serverSettings, config, trustedSocketFactory,
oauth2TokenProvider); oauth2TokenProvider);
} }
@ -463,9 +460,8 @@ public class RealImapStoreTest {
private String testCombinedPrefix; private String testCombinedPrefix;
public TestImapStore(ServerSettings serverSettings, ImapStoreConfig config, public TestImapStore(ServerSettings serverSettings, ImapStoreConfig config,
TrustedSocketFactory trustedSocketFactory, ConnectivityManager connectivityManager, TrustedSocketFactory trustedSocketFactory, OAuth2TokenProvider oauth2TokenProvider) {
OAuth2TokenProvider oauth2TokenProvider) { super(serverSettings, config, trustedSocketFactory, oauth2TokenProvider);
super(serverSettings, config, trustedSocketFactory, connectivityManager, oauth2TokenProvider);
} }
@Override @Override

View file

@ -3,7 +3,6 @@ package com.fsck.k9.mail.store.imap;
import com.fsck.k9.mail.AuthType; import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ConnectionSecurity; import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.NetworkType;
class SimpleImapSettings implements ImapSettings { class SimpleImapSettings implements ImapSettings {
@ -55,7 +54,7 @@ class SimpleImapSettings implements ImapSettings {
} }
@Override @Override
public boolean useCompression(NetworkType type) { public boolean useCompression() {
return useCompression; return useCompression;
} }