Remove compatibility code for pre-API 19 versions
This commit is contained in:
parent
ea13abb02d
commit
b5588a8d02
16 changed files with 16 additions and 402 deletions
|
@ -14,7 +14,6 @@ import com.fsck.k9.crypto.openPgpModule
|
|||
import com.fsck.k9.job.K9JobManager
|
||||
import com.fsck.k9.job.jobModule
|
||||
import com.fsck.k9.mail.internet.BinaryTempFileBody
|
||||
import com.fsck.k9.mail.ssl.LocalKeyStore
|
||||
import com.fsck.k9.mailstore.mailStoreModule
|
||||
import com.fsck.k9.message.extractors.extractorModule
|
||||
import com.fsck.k9.message.html.htmlModule
|
||||
|
@ -59,8 +58,6 @@ object Core : KoinComponent {
|
|||
StrictMode.enableDefaults()
|
||||
}
|
||||
|
||||
PRNGFixes.apply()
|
||||
|
||||
val packageName = context.packageName
|
||||
K9.Intents.init(packageName)
|
||||
}
|
||||
|
|
|
@ -1,290 +0,0 @@
|
|||
/*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will Google be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, as long as the origin is not misrepresented.
|
||||
*/
|
||||
|
||||
package com.fsck.k9;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Process;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.SecureRandomSpi;
|
||||
import java.security.Security;
|
||||
|
||||
/**
|
||||
* Fixes for the output of the default PRNG having low entropy.
|
||||
*
|
||||
* The fixes need to be applied via {@link #apply()} before any use of Java
|
||||
* Cryptography Architecture primitives. A good place to invoke them is in the
|
||||
* application's {@code onCreate}.
|
||||
*/
|
||||
public final class PRNGFixes {
|
||||
|
||||
private static final int VERSION_CODE_JELLY_BEAN = 16;
|
||||
private static final int VERSION_CODE_JELLY_BEAN_MR2 = 18;
|
||||
private static final byte[] BUILD_FINGERPRINT_AND_DEVICE_SERIAL =
|
||||
getBuildFingerprintAndDeviceSerial();
|
||||
|
||||
/** Hidden constructor to prevent instantiation. */
|
||||
private PRNGFixes() {}
|
||||
|
||||
/**
|
||||
* Applies all fixes.
|
||||
*
|
||||
* @throws SecurityException if a fix is needed but could not be applied.
|
||||
*/
|
||||
public static void apply() {
|
||||
applyOpenSSLFix();
|
||||
installLinuxPRNGSecureRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the fix for OpenSSL PRNG having low entropy. Does nothing if the
|
||||
* fix is not needed.
|
||||
*
|
||||
* @throws SecurityException if the fix is needed but could not be applied.
|
||||
*/
|
||||
private static void applyOpenSSLFix() throws SecurityException {
|
||||
if ((Build.VERSION.SDK_INT < VERSION_CODE_JELLY_BEAN)
|
||||
|| (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2)) {
|
||||
// No need to apply the fix
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Mix in the device- and invocation-specific seed.
|
||||
Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto")
|
||||
.getMethod("RAND_seed", byte[].class)
|
||||
.invoke(null, (Object) generateSeed());
|
||||
|
||||
// Mix output of Linux PRNG into OpenSSL's PRNG
|
||||
int bytesRead = (Integer) Class.forName(
|
||||
"org.apache.harmony.xnet.provider.jsse.NativeCrypto")
|
||||
.getMethod("RAND_load_file", String.class, long.class)
|
||||
.invoke(null, "/dev/urandom", 1024);
|
||||
if (bytesRead != 1024) {
|
||||
throw new IOException(
|
||||
"Unexpected number of bytes read from Linux PRNG: "
|
||||
+ bytesRead);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new SecurityException("Failed to seed OpenSSL PRNG", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs a Linux PRNG-backed {@code SecureRandom} implementation as the
|
||||
* default. Does nothing if the implementation is already the default or if
|
||||
* there is not need to install the implementation.
|
||||
*
|
||||
* @throws SecurityException if the fix is needed but could not be applied.
|
||||
*/
|
||||
private static void installLinuxPRNGSecureRandom()
|
||||
throws SecurityException {
|
||||
if (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2) {
|
||||
// No need to apply the fix
|
||||
return;
|
||||
}
|
||||
|
||||
// Install a Linux PRNG-based SecureRandom implementation as the
|
||||
// default, if not yet installed.
|
||||
Provider[] secureRandomProviders =
|
||||
Security.getProviders("SecureRandom.SHA1PRNG");
|
||||
if ((secureRandomProviders == null)
|
||||
|| (secureRandomProviders.length < 1)
|
||||
|| (!LinuxPRNGSecureRandomProvider.class.equals(
|
||||
secureRandomProviders[0].getClass()))) {
|
||||
Security.insertProviderAt(new LinuxPRNGSecureRandomProvider(), 1);
|
||||
}
|
||||
|
||||
// Assert that new SecureRandom() and
|
||||
// SecureRandom.getInstance("SHA1PRNG") return a SecureRandom backed
|
||||
// by the Linux PRNG-based SecureRandom implementation.
|
||||
SecureRandom rng1 = new SecureRandom();
|
||||
if (!LinuxPRNGSecureRandomProvider.class.equals(
|
||||
rng1.getProvider().getClass())) {
|
||||
throw new SecurityException(
|
||||
"new SecureRandom() backed by wrong Provider: "
|
||||
+ rng1.getProvider().getClass());
|
||||
}
|
||||
|
||||
SecureRandom rng2;
|
||||
try {
|
||||
rng2 = SecureRandom.getInstance("SHA1PRNG");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new SecurityException("SHA1PRNG not available", e);
|
||||
}
|
||||
if (!LinuxPRNGSecureRandomProvider.class.equals(
|
||||
rng2.getProvider().getClass())) {
|
||||
throw new SecurityException(
|
||||
"SecureRandom.getInstance(\"SHA1PRNG\") backed by wrong"
|
||||
+ " Provider: " + rng2.getProvider().getClass());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code Provider} of {@code SecureRandom} engines which pass through
|
||||
* all requests to the Linux PRNG.
|
||||
*/
|
||||
private static class LinuxPRNGSecureRandomProvider extends Provider {
|
||||
private static final long serialVersionUID = 6538669771360998378L;
|
||||
|
||||
public LinuxPRNGSecureRandomProvider() {
|
||||
super("LinuxPRNG",
|
||||
1.0,
|
||||
"A Linux-specific random number provider that uses"
|
||||
+ " /dev/urandom");
|
||||
// Although /dev/urandom is not a SHA-1 PRNG, some apps
|
||||
// explicitly request a SHA1PRNG SecureRandom and we thus need to
|
||||
// prevent them from getting the default implementation whose output
|
||||
// may have low entropy.
|
||||
put("SecureRandom.SHA1PRNG", LinuxPRNGSecureRandom.class.getName());
|
||||
put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link SecureRandomSpi} which passes all requests to the Linux PRNG
|
||||
* ({@code /dev/urandom}).
|
||||
*/
|
||||
public static class LinuxPRNGSecureRandom extends SecureRandomSpi {
|
||||
|
||||
/*
|
||||
* IMPLEMENTATION NOTE: Requests to generate bytes and to mix in a seed
|
||||
* are passed through to the Linux PRNG (/dev/urandom). Instances of
|
||||
* this class seed themselves by mixing in the current time, PID, UID,
|
||||
* build fingerprint, and hardware serial number (where available) into
|
||||
* Linux PRNG.
|
||||
*
|
||||
* Concurrency: Read requests to the underlying Linux PRNG are
|
||||
* serialized (on sLock) to ensure that multiple threads do not get
|
||||
* duplicated PRNG output.
|
||||
*/
|
||||
|
||||
private static final long serialVersionUID = 628140755730642770L;
|
||||
|
||||
private static final File URANDOM_FILE = new File("/dev/urandom");
|
||||
|
||||
private static final Object sLock = new Object();
|
||||
|
||||
/**
|
||||
* Input stream for reading from Linux PRNG or {@code null} if not yet
|
||||
* opened.
|
||||
*
|
||||
* @GuardedBy("sLock")
|
||||
*/
|
||||
private static DataInputStream sUrandomIn;
|
||||
|
||||
@Override
|
||||
protected void engineSetSeed(byte[] bytes) {
|
||||
// We use /dev/urandom so we don't need to worry about seeding
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineNextBytes(byte[] bytes) {
|
||||
try {
|
||||
DataInputStream in;
|
||||
synchronized (sLock) {
|
||||
in = getUrandomInputStream();
|
||||
}
|
||||
synchronized (in) {
|
||||
in.readFully(bytes);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new SecurityException(
|
||||
"Failed to read from " + URANDOM_FILE, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] engineGenerateSeed(int size) {
|
||||
byte[] seed = new byte[size];
|
||||
engineNextBytes(seed);
|
||||
return seed;
|
||||
}
|
||||
|
||||
private DataInputStream getUrandomInputStream() {
|
||||
synchronized (sLock) {
|
||||
if (sUrandomIn == null) {
|
||||
// NOTE: Consider inserting a BufferedInputStream between
|
||||
// DataInputStream and FileInputStream if you need higher
|
||||
// PRNG output performance and can live with future PRNG
|
||||
// output being pulled into this process prematurely.
|
||||
try {
|
||||
sUrandomIn = new DataInputStream(
|
||||
new FileInputStream(URANDOM_FILE));
|
||||
} catch (IOException e) {
|
||||
throw new SecurityException("Failed to open "
|
||||
+ URANDOM_FILE + " for reading", e);
|
||||
}
|
||||
}
|
||||
return sUrandomIn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a device- and invocation-specific seed to be mixed into the
|
||||
* Linux PRNG.
|
||||
*/
|
||||
private static byte[] generateSeed() {
|
||||
try {
|
||||
ByteArrayOutputStream seedBuffer = new ByteArrayOutputStream();
|
||||
DataOutputStream seedBufferOut =
|
||||
new DataOutputStream(seedBuffer);
|
||||
seedBufferOut.writeLong(System.currentTimeMillis());
|
||||
seedBufferOut.writeLong(System.nanoTime());
|
||||
seedBufferOut.writeInt(Process.myPid());
|
||||
seedBufferOut.writeInt(Process.myUid());
|
||||
seedBufferOut.write(BUILD_FINGERPRINT_AND_DEVICE_SERIAL);
|
||||
seedBufferOut.close();
|
||||
return seedBuffer.toByteArray();
|
||||
} catch (IOException e) {
|
||||
throw new SecurityException("Failed to generate seed", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hardware serial number of this device.
|
||||
*
|
||||
* @return serial number or {@code null} if not available.
|
||||
*/
|
||||
private static String getDeviceSerialNumber() {
|
||||
// We're using the Reflection API because Build.SERIAL is only available
|
||||
// since API Level 9 (Gingerbread, Android 2.3).
|
||||
try {
|
||||
return (String) Build.class.getField("SERIAL").get(null);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] getBuildFingerprintAndDeviceSerial() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
String fingerprint = Build.FINGERPRINT;
|
||||
if (fingerprint != null) {
|
||||
result.append(fingerprint);
|
||||
}
|
||||
String serial = getDeviceSerialNumber();
|
||||
if (serial != null) {
|
||||
result.append(serial);
|
||||
}
|
||||
|
||||
return result.toString().getBytes(Charset.forName("UTF-8"));
|
||||
}
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
package com.fsck.k9.helper;
|
||||
|
||||
|
||||
import android.os.Build.VERSION;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
|
@ -54,7 +52,7 @@ public class RetainFragment<T> extends Fragment {
|
|||
data = null;
|
||||
cleared = true;
|
||||
|
||||
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1 && fm.isDestroyed()) {
|
||||
if (fm.isDestroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
package com.fsck.k9.mailstore;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.os.Build;
|
||||
import timber.log.Timber;
|
||||
|
||||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.helper.FileHelper;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static java.lang.System.currentTimeMillis;
|
||||
|
||||
|
@ -502,15 +501,8 @@ public class LockableDatabase {
|
|||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
|
||||
private void deleteDatabase(File database) {
|
||||
boolean deleted;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
deleted = SQLiteDatabase.deleteDatabase(database);
|
||||
} else {
|
||||
deleted = database.delete();
|
||||
deleted |= new File(database.getPath() + "-journal").delete();
|
||||
}
|
||||
boolean deleted = SQLiteDatabase.deleteDatabase(database);
|
||||
if (!deleted) {
|
||||
Timber.i("LockableDatabase: deleteDatabase(): No files deleted.");
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import com.fsck.k9.NotificationSetting;
|
|||
import com.fsck.k9.controller.MessageReference;
|
||||
|
||||
import static com.fsck.k9.notification.NotificationHelper.NOTIFICATION_LED_BLINK_SLOW;
|
||||
import static com.fsck.k9.notification.NotificationController.platformSupportsExtendedNotifications;
|
||||
|
||||
|
||||
class DeviceNotifications extends BaseNotifications {
|
||||
|
@ -41,7 +40,7 @@ class DeviceNotifications extends BaseNotifications {
|
|||
int unreadMessageCount = notificationData.getUnreadMessageCount();
|
||||
|
||||
NotificationCompat.Builder builder;
|
||||
if (isPrivacyModeActive() || !platformSupportsExtendedNotifications()) {
|
||||
if (isPrivacyModeActive()) {
|
||||
builder = createSimpleSummaryNotification(account, unreadMessageCount);
|
||||
} else if (notificationData.isSingleMessageNotification()) {
|
||||
NotificationHolder holder = notificationData.getHolderForLatestNotification();
|
||||
|
|
|
@ -17,10 +17,6 @@ public class NotificationController {
|
|||
private final NewMailNotifications newMailNotifications;
|
||||
|
||||
|
||||
public static boolean platformSupportsExtendedNotifications() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
|
||||
}
|
||||
|
||||
public static boolean platformSupportsLockScreenNotifications() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
|
||||
}
|
||||
|
|
1
app/k9mail/proguard-rules.pro
vendored
1
app/k9mail/proguard-rules.pro
vendored
|
@ -18,7 +18,6 @@
|
|||
-dontwarn com.squareup.moshi.**
|
||||
|
||||
# Project specific rules
|
||||
-dontnote com.fsck.k9.PRNGFixes
|
||||
-dontnote com.fsck.k9.ui.messageview.**
|
||||
-dontnote com.fsck.k9.view.**
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ import android.content.IntentSender.SendIntentException;
|
|||
import android.content.res.Configuration;
|
||||
import android.content.res.TypedArray;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
|
@ -973,9 +972,6 @@ public class MessageList extends K9Activity implements MessageListFragmentListen
|
|||
} else if (id == R.id.copy || id == R.id.refile_copy) {
|
||||
messageViewFragment.onCopy();
|
||||
return true;
|
||||
} else if (id == R.id.select_text) {
|
||||
messageViewFragment.onSelectText();
|
||||
return true;
|
||||
} else if (id == R.id.show_headers || id == R.id.hide_headers) {
|
||||
messageViewFragment.onToggleAllHeadersView();
|
||||
updateMenu();
|
||||
|
@ -1052,7 +1048,6 @@ public class MessageList extends K9Activity implements MessageListFragmentListen
|
|||
menu.findItem(R.id.spam).setVisible(false);
|
||||
menu.findItem(R.id.refile).setVisible(false);
|
||||
menu.findItem(R.id.toggle_unread).setVisible(false);
|
||||
menu.findItem(R.id.select_text).setVisible(false);
|
||||
menu.findItem(R.id.toggle_message_view_theme).setVisible(false);
|
||||
menu.findItem(R.id.show_headers).setVisible(false);
|
||||
menu.findItem(R.id.hide_headers).setVisible(false);
|
||||
|
@ -1103,9 +1098,6 @@ public class MessageList extends K9Activity implements MessageListFragmentListen
|
|||
menu.findItem(R.id.toggle_unread).setIcon(ta.getDrawable(0));
|
||||
ta.recycle();
|
||||
|
||||
// Jellybean has built-in long press selection support
|
||||
menu.findItem(R.id.select_text).setVisible(Build.VERSION.SDK_INT < 16);
|
||||
|
||||
menu.findItem(R.id.delete).setVisible(K9.isMessageViewDeleteActionVisible());
|
||||
|
||||
/*
|
||||
|
|
|
@ -5,13 +5,11 @@ import java.util.ArrayList;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.ClipData;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
|
@ -338,20 +336,17 @@ public class AttachmentPresenter {
|
|||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
|
||||
private void addAttachmentsFromResultIntent(Intent data) {
|
||||
// TODO draftNeedsSaving = true
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
ClipData clipData = data.getClipData();
|
||||
if (clipData != null) {
|
||||
for (int i = 0, end = clipData.getItemCount(); i < end; i++) {
|
||||
Uri uri = clipData.getItemAt(i).getUri();
|
||||
if (uri != null) {
|
||||
addAttachment(uri);
|
||||
}
|
||||
ClipData clipData = data.getClipData();
|
||||
if (clipData != null) {
|
||||
for (int i = 0, end = clipData.getItemCount(); i < end; i++) {
|
||||
Uri uri = clipData.getItemAt(i).getUri();
|
||||
if (uri != null) {
|
||||
addAttachment(uri);
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Uri uri = data.getData();
|
||||
|
|
|
@ -9,7 +9,6 @@ import android.content.Intent;
|
|||
import android.database.Cursor;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Email;
|
||||
|
@ -25,7 +24,6 @@ import android.view.accessibility.AccessibilityNodeInfo;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.fsck.k9.ui.R;
|
||||
import com.fsck.k9.mail.Address;
|
||||
|
||||
|
||||
|
@ -179,13 +177,9 @@ public class ContactBadge extends ImageView implements OnClickListener {
|
|||
* @param address the address to look for a contact for.
|
||||
*/
|
||||
public void setContact(Address address) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||
Bundle extraContactInfo = new Bundle();
|
||||
extraContactInfo.putString(ContactsContract.Intents.Insert.NAME, address.getPersonal());
|
||||
assignContactFromEmail(address.getAddress(), true, extraContactInfo);
|
||||
} else {
|
||||
assignContactFromEmail(address.getAddress(), true);
|
||||
}
|
||||
Bundle extraContactInfo = new Bundle();
|
||||
extraContactInfo.putString(ContactsContract.Intents.Insert.NAME, address.getPersonal());
|
||||
assignContactFromEmail(address.getAddress(), true, extraContactInfo);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -415,11 +415,6 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
|
|||
onRefile(mAccount.getSpamFolder());
|
||||
}
|
||||
|
||||
public void onSelectText() {
|
||||
// FIXME
|
||||
// mMessageView.beginSelectingText();
|
||||
}
|
||||
|
||||
private void startRefileActivity(int activity) {
|
||||
Intent intent = new Intent(getActivity(), ChooseFolder.class);
|
||||
intent.putExtra(ChooseFolder.EXTRA_ACCOUNT, mAccount.getUuid());
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
package com.fsck.k9.ui.settings.general
|
||||
|
||||
import android.os.Bundle
|
||||
import android.support.v14.preference.MultiSelectListPreference
|
||||
import com.fsck.k9.ui.R
|
||||
import com.fsck.k9.notification.NotificationController
|
||||
import com.fsck.k9.ui.settings.remove
|
||||
import com.fsck.k9.ui.settings.removeEntry
|
||||
import com.fsck.k9.ui.withArguments
|
||||
import com.takisoft.fix.support.v7.preference.PreferenceFragmentCompat
|
||||
import org.koin.android.ext.android.inject
|
||||
|
@ -20,9 +18,7 @@ class GeneralSettingsFragment : PreferenceFragmentCompat() {
|
|||
setPreferencesFromResource(R.xml.general_settings, rootKey)
|
||||
|
||||
initializeStartInUnifiedInbox()
|
||||
initializeConfirmActions()
|
||||
initializeLockScreenNotificationVisibility()
|
||||
initializeNotificationQuickDelete()
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
|
@ -39,15 +35,6 @@ class GeneralSettingsFragment : PreferenceFragmentCompat() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun initializeConfirmActions() {
|
||||
val notificationActionsSupported = NotificationController.platformSupportsExtendedNotifications()
|
||||
if (!notificationActionsSupported) {
|
||||
(findPreference(PREFERENCE_CONFIRM_ACTIONS) as? MultiSelectListPreference)?.apply {
|
||||
removeEntry(CONFIRM_ACTION_DELETE_FROM_NOTIFICATION)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initializeLockScreenNotificationVisibility() {
|
||||
val lockScreenNotificationsSupported = NotificationController.platformSupportsLockScreenNotifications()
|
||||
if (!lockScreenNotificationsSupported) {
|
||||
|
@ -55,23 +42,13 @@ class GeneralSettingsFragment : PreferenceFragmentCompat() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun initializeNotificationQuickDelete() {
|
||||
val notificationActionsSupported = NotificationController.platformSupportsExtendedNotifications()
|
||||
if (!notificationActionsSupported) {
|
||||
findPreference(PREFERENCE_NOTIFICATION_QUICK_DELETE)?.apply { remove() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideSpecialAccounts() = dataStore.getBoolean(PREFERENCE_HIDE_SPECIAL_ACCOUNTS, false)
|
||||
|
||||
|
||||
companion object {
|
||||
private const val PREFERENCE_START_IN_UNIFIED_INBOX = "start_integrated_inbox"
|
||||
private const val PREFERENCE_HIDE_SPECIAL_ACCOUNTS = "hide_special_accounts"
|
||||
private const val PREFERENCE_CONFIRM_ACTIONS = "confirm_actions"
|
||||
private const val PREFERENCE_LOCK_SCREEN_NOTIFICATION_VISIBILITY = "lock_screen_notification_visibility"
|
||||
private const val PREFERENCE_NOTIFICATION_QUICK_DELETE = "notification_quick_delete"
|
||||
private const val CONFIRM_ACTION_DELETE_FROM_NOTIFICATION = "delete_notif"
|
||||
|
||||
fun create(rootKey: String? = null) = GeneralSettingsFragment().withArguments(
|
||||
PreferenceFragmentCompat.ARG_PREFERENCE_ROOT to rootKey)
|
||||
|
|
|
@ -227,12 +227,6 @@
|
|||
app:showAsAction="never"
|
||||
android:title="@string/expunge_action"/>
|
||||
|
||||
<!-- MessageView -->
|
||||
<item
|
||||
android:id="@+id/select_text"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/select_text_action"/>
|
||||
|
||||
<!-- MessageView -->
|
||||
<item
|
||||
android:id="@+id/toggle_message_view_theme"
|
||||
|
|
|
@ -159,7 +159,6 @@ Please submit bug reports, contribute new features and ask questions at
|
|||
<string name="flag_action">Add star</string>
|
||||
<string name="unflag_action">Remove star</string>
|
||||
<string name="copy_action">Copy</string>
|
||||
<string name="select_text_action">Select text</string>
|
||||
<string name="show_headers_action">Show headers</string>
|
||||
<string name="hide_headers_action">Hide headers</string>
|
||||
<plurals name="copy_address_to_clipboard">
|
||||
|
|
|
@ -218,8 +218,7 @@ public class DefaultTrustedSocketFactory implements TrustedSocketFactory {
|
|||
}
|
||||
|
||||
public static void setSniHost(SSLSocketFactory factory, SSLSocket socket, String hostname) {
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1 &&
|
||||
factory instanceof android.net.SSLCertificateSocketFactory) {
|
||||
if (factory instanceof android.net.SSLCertificateSocketFactory) {
|
||||
SSLCertificateSocketFactory sslCertificateSocketFactory = (SSLCertificateSocketFactory) factory;
|
||||
sslCertificateSocketFactory.setHostname(socket, hostname);
|
||||
} else {
|
||||
|
|
|
@ -15,7 +15,6 @@ import javax.net.ssl.X509ExtendedKeyManager;
|
|||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.security.KeyChain;
|
||||
import android.security.KeyChainException;
|
||||
|
||||
|
@ -31,17 +30,6 @@ import static com.fsck.k9.mail.CertificateValidationException.Reason.RetrievalFa
|
|||
* during the TLS handshake using the Android 4.0 KeyChain API.
|
||||
*/
|
||||
class KeyChainKeyManager extends X509ExtendedKeyManager {
|
||||
|
||||
private static PrivateKey sClientCertificateReferenceWorkaround;
|
||||
|
||||
|
||||
private static synchronized void savePrivateKeyReference(PrivateKey privateKey) {
|
||||
if (sClientCertificateReferenceWorkaround == null) {
|
||||
sClientCertificateReferenceWorkaround = privateKey;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final String mAlias;
|
||||
private final X509Certificate[] mChain;
|
||||
private final PrivateKey mPrivateKey;
|
||||
|
@ -93,16 +81,6 @@ class KeyChainKeyManager extends X509ExtendedKeyManager {
|
|||
throw new MessagingException("No private key found for: " + alias);
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to keep reference to the first private key retrieved so
|
||||
* it won't get garbage collected. If it will then the whole app
|
||||
* will crash on Android < 4.2 with "Fatal signal 11 code=1". See
|
||||
* https://code.google.com/p/android/issues/detail?id=62319
|
||||
*/
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
savePrivateKeyReference(privateKey);
|
||||
}
|
||||
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue