From c6e1862c14b9401a826cb5fa507156e84042a9bb Mon Sep 17 00:00:00 2001 From: Mariotaku Lee Date: Fri, 14 Apr 2017 18:46:14 +0800 Subject: [PATCH] improved robustness against shit data in dm fixed several crashes --- .../model/ParcelableMessageConversation.java | 94 +++++++++++++------ twidere/src/.google.commit-id | 2 +- .../activity/QuickSearchBarActivity.kt | 6 ++ ...ParcelableMessageConversationExtensions.kt | 6 +- .../twidere/fragment/DraftsFragment.kt | 1 + .../mariotaku/twidere/util/cache/JsonCache.kt | 9 +- 6 files changed, 85 insertions(+), 33 deletions(-) diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableMessageConversation.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableMessageConversation.java index 1331937b7..df9a9f08a 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableMessageConversation.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/model/ParcelableMessageConversation.java @@ -35,6 +35,7 @@ import com.hannesdorfmann.parcelableplease.annotation.ParcelableNoThanks; import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease; import org.mariotaku.commons.objectcursor.LoganSquareCursorFieldConverter; +import org.mariotaku.library.objectcursor.annotation.AfterCursorObjectCreated; import org.mariotaku.library.objectcursor.annotation.BeforeWriteContentValues; import org.mariotaku.library.objectcursor.annotation.CursorField; import org.mariotaku.library.objectcursor.annotation.CursorObject; @@ -189,30 +190,6 @@ public class ParcelableMessageConversation implements Parcelable { @ParcelableNoThanks InternalExtras internalConversationExtras; - - @OnPreJsonSerialize - void beforeJsonSerialize() { - internalMessageExtras = ParcelableMessage.InternalExtras.from(message_extras); - internalConversationExtras = InternalExtras.from(conversation_extras); - prepareParticipantKeys(); - } - - - @OnJsonParseComplete - void onJsonParseComplete() { - if (internalMessageExtras != null) { - message_extras = internalMessageExtras.getExtras(); - } - if (internalConversationExtras != null) { - conversation_extras = internalConversationExtras.getExtras(); - } - } - - @BeforeWriteContentValues - void beforeWriteContentValues(ContentValues values) throws IOException { - prepareParticipantKeys(); - } - @Override public String toString() { return "ParcelableMessageConversation{" + @@ -244,6 +221,64 @@ public class ParcelableMessageConversation implements Parcelable { '}'; } + + @OnPreJsonSerialize + void beforeJsonSerialize() { + internalMessageExtras = ParcelableMessage.InternalExtras.from(message_extras); + internalConversationExtras = InternalExtras.from(conversation_extras); + prepareParticipantKeys(); + } + + @OnJsonParseComplete + void onJsonParseComplete() { + if (internalMessageExtras != null) { + message_extras = internalMessageExtras.getExtras(); + } + if (internalConversationExtras != null) { + conversation_extras = internalConversationExtras.getExtras(); + } + if (participants != null) { + participants = removeNullParticipants(participants); + } + } + + @AfterCursorObjectCreated + void afterCursorObjectCreated() { + if (participants != null) { + participants = removeNullParticipants(participants); + } + } + + @BeforeWriteContentValues + void beforeWriteContentValues(ContentValues values) throws IOException { + if (participants != null) { + participants = removeNullParticipants(participants); + } + prepareParticipantKeys(); + } + + private void onParcelableCreated() { + if (participants != null) { + participants = removeNullParticipants(participants); + } + } + + private ParcelableUser[] removeNullParticipants(final ParcelableUser[] participants) { + int nullCount = 0; + for (final ParcelableUser user : participants) { + if (user == null) nullCount++; + } + if (nullCount == 0) return participants; + final int resultLength = participants.length - nullCount; + final ParcelableUser[] result = new ParcelableUser[resultLength]; + for (int i = 0, j = 0, l = participants.length; i < l; i++) { + final ParcelableUser user = participants[i]; + if (user == null) continue; + result[j++] = user; + } + return result; + } + private void prepareParticipantKeys() { // Ensure keys are ordered if (participants != null && participant_keys == null) { @@ -256,24 +291,24 @@ public class ParcelableMessageConversation implements Parcelable { Arrays.sort(participant_keys); } } - @StringDef({ConversationType.ONE_TO_ONE, ConversationType.GROUP}) @Retention(RetentionPolicy.SOURCE) public @interface ConversationType { String ONE_TO_ONE = "one_to_one"; String GROUP = "group"; - } + } @StringDef({ExtrasType.DEFAULT, ExtrasType.TWITTER_OFFICIAL}) @Retention(RetentionPolicy.SOURCE) public @interface ExtrasType { String DEFAULT = "default"; String TWITTER_OFFICIAL = "twitter_official"; + + } - - @JsonObject static class InternalExtras { + @JsonField(name = "twitter_official") TwitterOfficialConversationExtras twitterOfficial; @@ -287,13 +322,13 @@ public class ParcelableMessageConversation implements Parcelable { } return result; } - public ConversationExtras getExtras() { if (twitterOfficial != null) { return twitterOfficial; } return null; } + } @Override @@ -310,6 +345,7 @@ public class ParcelableMessageConversation implements Parcelable { public ParcelableMessageConversation createFromParcel(Parcel source) { ParcelableMessageConversation target = new ParcelableMessageConversation(); ParcelableMessageConversationParcelablePlease.readFromParcel(target, source); + target.onParcelableCreated(); return target; } diff --git a/twidere/src/.google.commit-id b/twidere/src/.google.commit-id index 7dfc3af2a..ac5413919 100644 --- a/twidere/src/.google.commit-id +++ b/twidere/src/.google.commit-id @@ -1 +1 @@ -54042eb537a2d7133b28350a33773882de5fe472 +495800fef7680a282e36ffa89ff57ae488aa1a98 diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/QuickSearchBarActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/QuickSearchBarActivity.kt index e61a39b6f..fe964ebb3 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/QuickSearchBarActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/QuickSearchBarActivity.kt @@ -192,6 +192,12 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks< startActivityForResult(scanIntent, REQUEST_SCAN_QR) } catch (e: ActivityNotFoundException) { // Ignore + Toast.makeText(this, R.string.message_toast_qr_scanner_not_supported, + Toast.LENGTH_SHORT).show() + } catch (e: SecurityException) { + // Goddamned SAMSUNG again!!! + Toast.makeText(this, R.string.message_toast_qr_scanner_not_supported, + Toast.LENGTH_SHORT).show() } } else { doSearch() diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/ParcelableMessageConversationExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/ParcelableMessageConversationExtensions.kt index ca979d921..cbe541415 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/ParcelableMessageConversationExtensions.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/ParcelableMessageConversationExtensions.kt @@ -115,7 +115,11 @@ fun ParcelableMessageConversation.getSummaryText(context: Context, manager: User fun ParcelableMessageConversation.addParticipants(users: Collection) { val participants = this.participants if (participants == null) { - this.participants = arrayOf(user) + if (user != null) { + this.participants = arrayOf(user) + } else { + this.participants = emptyArray() + } } else { val addingUsers = ArrayList() users.forEach { user -> diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/DraftsFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/DraftsFragment.kt index 3e573af20..394e20e53 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/DraftsFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/DraftsFragment.kt @@ -238,6 +238,7 @@ class DraftsFragment : BaseFragment(), LoaderCallbacks, OnItemClickList val status = extras.status ?: return false val intent = Intent(context, RetweetQuoteDialogActivity::class.java).apply { putExtra(EXTRA_STATUS, status) + putExtra(EXTRA_STATUS_ID, status.id) putExtra(EXTRA_ACCOUNT_KEY, draft.account_keys?.singleOrNull()) putExtra(EXTRA_TEXT, draft.text) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/cache/JsonCache.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/cache/JsonCache.kt index 7eb3f342b..54fe8f97b 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/cache/JsonCache.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/cache/JsonCache.kt @@ -38,8 +38,13 @@ class JsonCache(val cacheDir: File) { } fun getList(key: String, cls: Class): List? { - return cache?.get(key)?.getFile(0)?.inputStream()?.use { - JsonSerializer.parseList(it, cls) + val value = cache?.get(key) ?: return null + try { + return value.getFile(0)?.inputStream()?.use { + JsonSerializer.parseList(it, cls) + } + } catch (e: IOException) { + return null } }