Add BundleCompat to fix getSerializable
This commit is contained in:
parent
32277205e5
commit
d6955d0520
5 changed files with 121 additions and 19 deletions
|
@ -26,6 +26,7 @@ import androidx.fragment.app.FragmentManager
|
||||||
import androidx.fragment.app.FragmentTransaction
|
import androidx.fragment.app.FragmentTransaction
|
||||||
import androidx.fragment.app.commit
|
import androidx.fragment.app.commit
|
||||||
import androidx.fragment.app.commitNow
|
import androidx.fragment.app.commitNow
|
||||||
|
import app.k9mail.core.android.common.compat.BundleCompat
|
||||||
import app.k9mail.core.android.common.contact.CachingRepository
|
import app.k9mail.core.android.common.contact.CachingRepository
|
||||||
import app.k9mail.core.android.common.contact.ContactRepository
|
import app.k9mail.core.android.common.contact.ContactRepository
|
||||||
import app.k9mail.feature.launcher.FeatureLauncherActivity
|
import app.k9mail.feature.launcher.FeatureLauncherActivity
|
||||||
|
@ -168,6 +169,7 @@ open class MessageList :
|
||||||
window.statusBarColor = Color.TRANSPARENT
|
window.statusBarColor = Color.TRANSPARENT
|
||||||
|
|
||||||
val rootLayout = findViewById<View>(R.id.drawerLayout)
|
val rootLayout = findViewById<View>(R.id.drawerLayout)
|
||||||
|
|
||||||
rootLayout.systemUiVisibility = rootLayout.systemUiVisibility or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
|
rootLayout.systemUiVisibility = rootLayout.systemUiVisibility or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||||
|
|
||||||
|
@ -301,8 +303,13 @@ open class MessageList :
|
||||||
}
|
}
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
val savedDisplayMode = savedInstanceState.getSerializable(STATE_DISPLAY_MODE) as DisplayMode
|
val savedDisplayMode = BundleCompat.getSerializable(
|
||||||
if (savedDisplayMode != DisplayMode.SPLIT_VIEW) {
|
savedInstanceState,
|
||||||
|
STATE_DISPLAY_MODE,
|
||||||
|
DisplayMode::class.java,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (savedDisplayMode != null && savedDisplayMode != DisplayMode.SPLIT_VIEW) {
|
||||||
displayMode = savedDisplayMode
|
displayMode = savedDisplayMode
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import android.widget.TextView
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||||
|
import app.k9mail.core.android.common.compat.BundleCompat
|
||||||
import com.fsck.k9.ui.R
|
import com.fsck.k9.ui.R
|
||||||
import com.fsck.k9.ui.base.loader.observeLoading
|
import com.fsck.k9.ui.base.loader.observeLoading
|
||||||
import de.cketti.changelog.ReleaseItem
|
import de.cketti.changelog.ReleaseItem
|
||||||
|
@ -20,7 +21,9 @@ import org.koin.core.parameter.parametersOf
|
||||||
*/
|
*/
|
||||||
class ChangelogFragment : Fragment() {
|
class ChangelogFragment : Fragment() {
|
||||||
private val viewModel: ChangelogViewModel by viewModel {
|
private val viewModel: ChangelogViewModel by viewModel {
|
||||||
val mode = arguments?.getSerializable(ARG_MODE) as? ChangeLogMode ?: error("Missing argument '$ARG_MODE'")
|
val mode = arguments?.let {
|
||||||
|
BundleCompat.getSerializable(it, ARG_MODE, ChangeLogMode::class.java)
|
||||||
|
} ?: error("Missing argument '$ARG_MODE'")
|
||||||
parametersOf(mode)
|
parametersOf(mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +88,7 @@ class ChangelogAdapter(releaseItems: List<ReleaseItem>) : RecyclerView.Adapter<V
|
||||||
viewHolder.versionName.text = context.getString(R.string.changelog_version_title, item.versionName)
|
viewHolder.versionName.text = context.getString(R.string.changelog_version_title, item.versionName)
|
||||||
viewHolder.versionDate.text = item.date
|
viewHolder.versionDate.text = item.date
|
||||||
}
|
}
|
||||||
|
|
||||||
is String -> {
|
is String -> {
|
||||||
val viewHolder = holder as ChangeItemViewHolder
|
val viewHolder = holder as ChangeItemViewHolder
|
||||||
viewHolder.changeText.text = item
|
viewHolder.changeText.text = item
|
||||||
|
|
|
@ -5,19 +5,13 @@ import java.util.Map;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import com.fsck.k9.DI;
|
import app.k9mail.core.android.common.compat.BundleCompat;
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
import com.fsck.k9.Account;
|
import com.fsck.k9.Account;
|
||||||
import com.fsck.k9.Account.MessageFormat;
|
import com.fsck.k9.Account.MessageFormat;
|
||||||
import com.fsck.k9.Account.QuoteStyle;
|
import com.fsck.k9.Account.QuoteStyle;
|
||||||
|
import com.fsck.k9.DI;
|
||||||
import com.fsck.k9.activity.MessageCompose;
|
import com.fsck.k9.activity.MessageCompose;
|
||||||
import com.fsck.k9.activity.MessageCompose.Action;
|
import com.fsck.k9.activity.MessageCompose.Action;
|
||||||
import com.fsck.k9.message.extractors.BodyTextExtractor;
|
|
||||||
import com.fsck.k9.message.html.HtmlConverter;
|
|
||||||
import com.fsck.k9.message.quote.HtmlQuoteCreator;
|
|
||||||
import com.fsck.k9.message.quote.TextQuoteCreator;
|
|
||||||
import com.fsck.k9.message.signature.HtmlSignatureRemover;
|
|
||||||
import com.fsck.k9.mail.MessagingException;
|
import com.fsck.k9.mail.MessagingException;
|
||||||
import com.fsck.k9.mail.Part;
|
import com.fsck.k9.mail.Part;
|
||||||
import com.fsck.k9.mail.internet.MessageExtractor;
|
import com.fsck.k9.mail.internet.MessageExtractor;
|
||||||
|
@ -25,11 +19,17 @@ import com.fsck.k9.mail.internet.MimeUtility;
|
||||||
import com.fsck.k9.mailstore.AttachmentResolver;
|
import com.fsck.k9.mailstore.AttachmentResolver;
|
||||||
import com.fsck.k9.mailstore.MessageViewInfo;
|
import com.fsck.k9.mailstore.MessageViewInfo;
|
||||||
import com.fsck.k9.message.IdentityField;
|
import com.fsck.k9.message.IdentityField;
|
||||||
import com.fsck.k9.message.quote.InsertableHtmlContent;
|
|
||||||
import com.fsck.k9.message.MessageBuilder;
|
import com.fsck.k9.message.MessageBuilder;
|
||||||
import com.fsck.k9.message.QuotedTextMode;
|
import com.fsck.k9.message.QuotedTextMode;
|
||||||
import com.fsck.k9.message.SimpleMessageFormat;
|
import com.fsck.k9.message.SimpleMessageFormat;
|
||||||
|
import com.fsck.k9.message.extractors.BodyTextExtractor;
|
||||||
|
import com.fsck.k9.message.html.HtmlConverter;
|
||||||
|
import com.fsck.k9.message.quote.HtmlQuoteCreator;
|
||||||
|
import com.fsck.k9.message.quote.InsertableHtmlContent;
|
||||||
|
import com.fsck.k9.message.quote.TextQuoteCreator;
|
||||||
|
import com.fsck.k9.message.signature.HtmlSignatureRemover;
|
||||||
import com.fsck.k9.message.signature.TextSignatureRemover;
|
import com.fsck.k9.message.signature.TextSignatureRemover;
|
||||||
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
||||||
public class QuotedMessagePresenter {
|
public class QuotedMessagePresenter {
|
||||||
|
@ -154,17 +154,31 @@ public class QuotedMessagePresenter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onRestoreInstanceState(Bundle savedInstanceState) {
|
public void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||||
quotedHtmlContent = (InsertableHtmlContent) savedInstanceState.getSerializable(STATE_KEY_HTML_QUOTE);
|
quotedHtmlContent = BundleCompat.INSTANCE.getSerializable(
|
||||||
|
savedInstanceState,
|
||||||
|
STATE_KEY_HTML_QUOTE,
|
||||||
|
InsertableHtmlContent.class
|
||||||
|
);
|
||||||
|
quotedTextFormat = BundleCompat.getSerializable(
|
||||||
|
savedInstanceState,
|
||||||
|
STATE_KEY_QUOTED_TEXT_FORMAT,
|
||||||
|
SimpleMessageFormat.class
|
||||||
|
);
|
||||||
|
|
||||||
|
forcePlainText = savedInstanceState.getBoolean(STATE_KEY_FORCE_PLAIN_TEXT);
|
||||||
|
|
||||||
|
showOrHideQuotedText(
|
||||||
|
BundleCompat.getSerializable(
|
||||||
|
savedInstanceState,
|
||||||
|
STATE_KEY_QUOTED_TEXT_MODE,
|
||||||
|
QuotedTextMode.class
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (quotedHtmlContent != null && quotedHtmlContent.getQuotedContent() != null) {
|
if (quotedHtmlContent != null && quotedHtmlContent.getQuotedContent() != null) {
|
||||||
// we don't have the part here, but inline-displayed images are cached by the webview
|
// we don't have the part here, but inline-displayed images are cached by the webview
|
||||||
view.setQuotedHtml(quotedHtmlContent.getQuotedContent(), null);
|
view.setQuotedHtml(quotedHtmlContent.getQuotedContent(), null);
|
||||||
}
|
}
|
||||||
quotedTextFormat = (SimpleMessageFormat) savedInstanceState.getSerializable(
|
|
||||||
STATE_KEY_QUOTED_TEXT_FORMAT);
|
|
||||||
forcePlainText = savedInstanceState.getBoolean(STATE_KEY_FORCE_PLAIN_TEXT);
|
|
||||||
|
|
||||||
showOrHideQuotedText(
|
|
||||||
(QuotedTextMode) savedInstanceState.getSerializable(STATE_KEY_QUOTED_TEXT_MODE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processMessageToForward(MessageViewInfo messageViewInfo) throws MessagingException {
|
public void processMessageToForward(MessageViewInfo messageViewInfo) throws MessagingException {
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package app.k9mail.core.android.common.compat
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
// This class resolves a deprecation warning and issue with the Bundle.getSerializable method
|
||||||
|
// Fixes https://issuetracker.google.com/issues/314250395
|
||||||
|
// Could be removed once releases in androidx.core.os.BundleCompat
|
||||||
|
object BundleCompat {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun <T : Serializable> getSerializable(bundle: Bundle, key: String?, clazz: Class<T>): T? = when {
|
||||||
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE -> bundle.getSerializable(key, clazz)
|
||||||
|
else -> {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
val serializable = bundle.getSerializable(key)
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
if (clazz.isInstance(serializable)) serializable as T else null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package app.k9mail.core.android.common.compat
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import assertk.assertThat
|
||||||
|
import assertk.assertions.isEqualTo
|
||||||
|
import java.io.Serializable
|
||||||
|
import kotlin.test.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.robolectric.RobolectricTestRunner
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner::class)
|
||||||
|
class BundleCompatTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getSerializable returns Serializable`() {
|
||||||
|
val bundle = Bundle()
|
||||||
|
val key = "keySerializable"
|
||||||
|
val serializable = TestSerializable("value")
|
||||||
|
val clazz = TestSerializable::class.java
|
||||||
|
bundle.putSerializable(key, serializable)
|
||||||
|
|
||||||
|
val result = BundleCompat.getSerializable(bundle, key, clazz)
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo(serializable)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getSerializable returns null when class mismatch`() {
|
||||||
|
val bundle = Bundle()
|
||||||
|
val key = "keySerializable"
|
||||||
|
val serializable = TestSerializable("value")
|
||||||
|
val clazz = OtherTestSerializable::class.java
|
||||||
|
bundle.putSerializable(key, serializable)
|
||||||
|
|
||||||
|
val result = BundleCompat.getSerializable(bundle, key, clazz)
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class TestSerializable(
|
||||||
|
val value: String,
|
||||||
|
) : Serializable {
|
||||||
|
companion object {
|
||||||
|
private const val serialVersionUID = 1L
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class OtherTestSerializable(
|
||||||
|
val value: String,
|
||||||
|
) : Serializable {
|
||||||
|
companion object {
|
||||||
|
private const val serialVersionUID = 2L
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue