From cefdbe1d083bbb7bd612260efa44b46b8fdf7808 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 26 Aug 2020 19:21:14 +0200 Subject: [PATCH] Add CheckNumberType in json to fix sending in room v6 --- .../network/parsing/CheckNumberType.kt | 66 +++++++++++++++++++ .../internal/worker/WorkerParamsFactory.kt | 15 ++++- 2 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt new file mode 100644 index 0000000000..d4ceca2006 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.network.parsing + +import androidx.annotation.Nullable +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter + +import com.squareup.moshi.Moshi +import java.io.IOException +import java.lang.reflect.Type +import java.math.BigDecimal + +/** + * This is used to check if NUMBER in json is integer or double, so we can preserve typing when serializing/deserializing in a row. + */ +interface CheckNumberType { + + companion object { + val JSON_ADAPTER_FACTORY = object : JsonAdapter.Factory { + @Nullable + override fun create(type: Type, annotations: Set?, moshi: Moshi): JsonAdapter<*>? { + if (type !== Any::class.java) { + return null + } + val delegate: JsonAdapter = moshi.nextAdapter(this, Any::class.java, emptySet()) + return object : JsonAdapter() { + @Nullable + @Throws(IOException::class) + override fun fromJson(reader: JsonReader): Any? { + return if (reader.peek() !== JsonReader.Token.NUMBER) { + delegate.fromJson(reader) + } else { + val numberAsString = reader.nextString() + val decimal = BigDecimal(numberAsString) + if (decimal.scale() <= 0) { + decimal.intValueExact() + } else { + decimal.toDouble() + } + } + } + + override fun toJson(writer: JsonWriter, value: Any?) { + delegate.toJson(writer, value) + } + } + } + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/WorkerParamsFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/WorkerParamsFactory.kt index 2b7cba0b0c..b162566403 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/WorkerParamsFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/WorkerParamsFactory.kt @@ -19,13 +19,23 @@ package org.matrix.android.sdk.internal.worker import androidx.work.Data import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.internal.network.parsing.CheckNumberType -object WorkerParamsFactory { +internal object WorkerParamsFactory { + + val moshi by lazy { + // We are adding the CheckNumberType as we are serializing/deserializing multiple time in a row + // and we lost typing information doing so. + // We don't want this check to be done on all adapters, so we just add it here. + MoshiProvider.providesMoshi() + .newBuilder() + .add(CheckNumberType.JSON_ADAPTER_FACTORY) + .build() + } const val KEY = "WORKER_PARAMS_JSON" inline fun toData(params: T): Data { - val moshi = MoshiProvider.providesMoshi() val adapter = moshi.adapter(T::class.java) val json = adapter.toJson(params) return Data.Builder().putString(KEY, json).build() @@ -36,7 +46,6 @@ object WorkerParamsFactory { return if (json == null) { null } else { - val moshi = MoshiProvider.providesMoshi() val adapter = moshi.adapter(T::class.java) adapter.fromJson(json) }