x1ongzhu 1 年之前
父节点
当前提交
80673be54d

+ 2 - 0
app/build.gradle

@@ -115,6 +115,7 @@ dependencies {
     implementation libs.ktor.client.okhttp
     implementation libs.ktor.client.content.negotiation
     implementation libs.ktor.client.resources
+    implementation libs.ktor.client.logging
     implementation libs.ktor.serialization.kotlinx.json
     implementation libs.kotlinx.serialization.json
     implementation(libs.room.runtime)
@@ -143,4 +144,5 @@ dependencies {
     implementation 'com.google.code.gson:gson:2.10.1'
     implementation 'org.apache.commons:commons-lang3:3.14.0'
     implementation 'commons-io:commons-io:2.16.1'
+    implementation 'org.slf4j:slf4j-android:1.7.36'
 }

+ 9 - 0
app/src/main/java/com/example/modifier/data/MessageLogData.kt

@@ -0,0 +1,9 @@
+package com.example.modifier.data
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+
+class MessageLogData : MutableLiveData<String>() {
+
+
+}

+ 36 - 29
app/src/main/java/com/example/modifier/http/KtorClient.kt

@@ -5,16 +5,32 @@ import com.example.modifier.http.response.ErrorResponse
 import io.ktor.client.HttpClient
 import io.ktor.client.call.body
 import io.ktor.client.engine.okhttp.OkHttp
+import io.ktor.client.network.sockets.ConnectTimeoutException
+import io.ktor.client.network.sockets.SocketTimeoutException
 import io.ktor.client.plugins.ClientRequestException
+import io.ktor.client.plugins.HttpRequestRetry
+import io.ktor.client.plugins.HttpRequestTimeoutException
 import io.ktor.client.plugins.HttpResponseValidator
+import io.ktor.client.plugins.HttpSend
 import io.ktor.client.plugins.HttpTimeout
 import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
 import io.ktor.client.plugins.defaultRequest
+import io.ktor.client.plugins.logging.LogLevel
+import io.ktor.client.plugins.logging.Logging
 import io.ktor.client.plugins.resources.Resources
+import io.ktor.client.utils.unwrapCancellationException
 import io.ktor.serialization.kotlinx.json.json
+import kotlinx.coroutines.CancellationException
 import kotlinx.serialization.ExperimentalSerializationApi
 import kotlinx.serialization.json.Json
 
+private fun Throwable.isTimeoutException(): Boolean {
+    val exception = unwrapCancellationException()
+    return exception is HttpRequestTimeoutException ||
+            exception is ConnectTimeoutException ||
+            exception is SocketTimeoutException
+}
+
 @OptIn(ExperimentalSerializationApi::class)
 val KtorClient = HttpClient(OkHttp) {
     defaultRequest {
@@ -23,41 +39,32 @@ val KtorClient = HttpClient(OkHttp) {
             if (it) Global.serverUrl else "${Global.serverUrl}/"
         })
     }
-    install(HttpTimeout) {
-        requestTimeoutMillis = 180000
-        connectTimeoutMillis = 180000
-        socketTimeoutMillis = 180000
+    install(HttpSend) {
+        maxSendCount = 200
     }
-    install(Resources)
-    install(ContentNegotiation) {
-        json(Json {
-            prettyPrint = true
-            isLenient = true
-            ignoreUnknownKeys = true
-            explicitNulls = false
-        })
+    install(Logging) {
+        level = LogLevel.INFO
     }
-    HttpResponseValidator {
-        validateResponse { response ->
-            if (response.status.value !in 200..299) {
-                val error = response.body<ErrorResponse>()
-                throw ClientRequestException(response, error.message ?: "Unknown error")
+    install(HttpRequestRetry) {
+        maxRetries = 3
+        retryOnExceptionIf { _, cause ->
+            when {
+                cause.isTimeoutException() -> true
+                cause is CancellationException -> false
+                else -> true
+            }
+        }
+        retryIf { _, response ->
+            response.status.value.let {
+                when (it) {
+                    425, 429, 502, 503, 504 -> true
+                    else -> false
+                }
             }
         }
-    }
-}
-
-val KtorClient1 = HttpClient(OkHttp) {
-    defaultRequest {
-        Global.load()
-        url(Global.serverUrl.endsWith("/").let {
-            if (it) Global.serverUrl else "${Global.serverUrl}/"
-        })
     }
     install(HttpTimeout) {
-        requestTimeoutMillis = 5000
-        connectTimeoutMillis = 5000
-        socketTimeoutMillis = 5000
+        requestTimeoutMillis = 30 * 1000
     }
     install(Resources)
     install(ContentNegotiation) {

+ 47 - 53
app/src/main/java/com/example/modifier/service/ModifierService.kt

@@ -61,13 +61,11 @@ import com.example.modifier.enums.RcsConnectionStatus
 import com.example.modifier.extension.kill
 import com.example.modifier.hasRootAccess
 import com.example.modifier.http.KtorClient
-import com.example.modifier.http.KtorClient1
 import com.example.modifier.http.api.DeviceApi
 import com.example.modifier.http.api.RcsNumberApi
 import com.example.modifier.http.api.SysConfigApi
 import com.example.modifier.http.request.RcsNumberRequest
 import com.example.modifier.http.response.DeviceResponse
-import com.example.modifier.http.response.ErrorResponse
 import com.example.modifier.http.response.RcsNumberResponse
 import com.example.modifier.http.response.SysConfigResponse
 import com.example.modifier.model.InstallApkAction
@@ -81,12 +79,13 @@ import com.google.android.material.color.DynamicColors
 import io.ktor.client.HttpClient
 import io.ktor.client.call.body
 import io.ktor.client.engine.okhttp.OkHttp
-import io.ktor.client.plugins.ClientRequestException
 import io.ktor.client.plugins.HttpResponseValidator
 import io.ktor.client.plugins.ServerResponseException
 import io.ktor.client.plugins.resources.get
 import io.ktor.client.plugins.resources.post
 import io.ktor.client.plugins.resources.put
+import io.ktor.client.plugins.retry
+import io.ktor.client.plugins.timeout
 import io.ktor.client.request.prepareGet
 import io.ktor.client.request.setBody
 import io.ktor.http.ContentType
@@ -1283,6 +1282,9 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
                     ) {
                         contentType(ContentType.Application.Json)
                         setBody(req)
+                        timeout {
+                            requestTimeoutMillis = 60 * 1000
+                        }
                     }
                     var rcsNumber = response.body<RcsNumberResponse>()
                     Log.i(TAG, "requestNumber response: $rcsNumber")
@@ -1346,22 +1348,17 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
                     }
 
                     launch {
-                        run OtpState@{
-                            repeat(3) {
-                                try {
-                                    KtorClient.post(
-                                        RcsNumberApi.Id.OtpState(
-                                            RcsNumberApi.Id(
-                                                RcsNumberApi(),
-                                                rcsNumber.id
-                                            )
-                                        )
+                        try {
+                            KtorClient.post(
+                                RcsNumberApi.Id.OtpState(
+                                    RcsNumberApi.Id(
+                                        RcsNumberApi(),
+                                        rcsNumber.id
                                     )
-                                    return@OtpState
-                                } catch (e: Exception) {
-                                    Log.e(TAG, "Send OtpState Error: ${e.message}", e)
-                                }
-                            }
+                                )
+                            )
+                        } catch (e: Exception) {
+                            Log.e(TAG, "Send OtpState Error: ${e.message}", e)
                         }
                     }
 
@@ -1434,26 +1431,21 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
                             continue
                         } else {
                             launch {
-                                run ConfiguredState@{
-                                    repeat(3) {
-                                        try {
-                                            KtorClient.post(
-                                                RcsNumberApi.Id.Configured(
-                                                    RcsNumberApi.Id(
-                                                        RcsNumberApi(),
-                                                        rcsNumber.id
-                                                    )
-                                                )
-                                            )
-                                            return@ConfiguredState
-                                        } catch (e: Exception) {
-                                            Log.e(
-                                                TAG,
-                                                "Send ConfiguredState Error: ${e.message}",
-                                                e
+                                try {
+                                    KtorClient.post(
+                                        RcsNumberApi.Id.Configured(
+                                            RcsNumberApi.Id(
+                                                RcsNumberApi(),
+                                                rcsNumber.id
                                             )
-                                        }
-                                    }
+                                        )
+                                    )
+                                } catch (e: Exception) {
+                                    Log.e(
+                                        TAG,
+                                        "Send ConfiguredState Error: ${e.message}",
+                                        e
+                                    )
                                 }
                             }
                             requestSuccess = true
@@ -1519,26 +1511,28 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
             var config: SysConfigResponse
             val checkRcsAvailabilityNumbers = mutableListOf<String>()
             withTimeoutOrNull(60.seconds) {
-                while (true) {
-                    try {
-                        config = KtorClient.get(
-                            SysConfigApi.Id(
-                                SysConfigApi(),
-                                "check_availability_numbers"
-                            )
+                try {
+                    config = KtorClient.get(
+                        SysConfigApi.Id(
+                            SysConfigApi(),
+                            "check_availability_numbers"
                         )
-                            .body<SysConfigResponse>()
-                        Log.i(TAG, "sysConfig response: $config")
-                        checkRcsAvailabilityNumbers.addAll(
-                            config.value.split(",").map { it.trim() })
-                        break
-                    } catch (exception: Exception) {
-                        Log.e(TAG, "sysConfig Error: ${exception.message}", exception)
-                    }
-                    delay(1.seconds)
+                    )
+                        .body<SysConfigResponse>()
+                    Log.i(TAG, "sysConfig response: $config")
+                    checkRcsAvailabilityNumbers.addAll(
+                        config.value.split(",").map { it.trim() })
+
+                } catch (exception: Exception) {
+                    Log.e(TAG, "sysConfig Error: ${exception.message}", exception)
                 }
             }
 
+            if (checkRcsAvailabilityNumbers.isEmpty()) {
+                Log.e(TAG, "checkRcsAvailabilityNumbers is empty")
+                return true
+            }
+
             checkRcsAvailabilityNumbers.forEach {
                 startActivity(smsIntent(it, ""))
                 val s = withTimeoutOrNull(5.seconds) {

+ 22 - 0
app/src/main/java/com/example/modifier/ui/settings/SettingsFragment.kt

@@ -35,19 +35,25 @@ import com.example.modifier.http.api.RcsNumberApi
 import com.example.modifier.http.request.RcsNumberRequest
 import com.example.modifier.http.response.RcsNumberResponse
 import com.example.modifier.model.TelephonyConfig
+import com.example.modifier.service.ModifierService
+import com.example.modifier.service.ModifierService.Companion
 import com.example.modifier.service.ModifierService.Companion.instance
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import io.ktor.client.call.body
 import io.ktor.client.plugins.resources.put
+import io.ktor.client.plugins.retry
 import io.ktor.client.request.setBody
 import io.ktor.client.statement.HttpResponse
 import io.ktor.client.statement.bodyAsText
 import io.ktor.http.ContentType
 import io.ktor.http.contentType
+import io.ktor.http.isSuccess
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
+import kotlinx.coroutines.withTimeout
+import kotlinx.coroutines.withTimeoutOrNull
 import org.apache.commons.lang3.RandomStringUtils
 import org.apache.commons.lang3.StringUtils
 import org.apache.commons.validator.routines.UrlValidator
@@ -316,6 +322,22 @@ class SettingsFragment : Fragment() {
         }
         lifecycleScope.launch {
             loadConfigs()
+            try {
+                delay(5000)
+                val req = RcsNumberRequest(
+                    deviceId = Utils.getUniqueID()
+                )
+                val response = KtorClient.put(
+                    RcsNumberApi()
+                ) {
+                    contentType(ContentType.Application.Json)
+                    setBody(req)
+                }
+                var rcsNumber = response.body<RcsNumberResponse>()
+                Log.i("xxx", "requestNumber response: $rcsNumber")
+            } catch (e: Exception) {
+                Log.e("xxx", "requestNumber error: $e")
+            }
         }
 
         return binding.root

+ 1 - 0
gradle/libs.versions.toml

@@ -65,6 +65,7 @@ ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref =
 ktor-client-okhttp = { group = "io.ktor", name = "ktor-client-okhttp", version.ref = "ktor" }
 ktor-client-content-negotiation = { group = "io.ktor", name = "ktor-client-content-negotiation", version.ref = "ktor" }
 ktor-client-resources = { group = "io.ktor", name = "ktor-client-resources", version.ref = "ktor" }
+ktor-client-logging = { group = "io.ktor", name = "ktor-client-logging", version.ref = "ktor" }
 ktor-serialization-kotlinx-json = { group = "io.ktor", name = "ktor-serialization-kotlinx-json", version.ref = "ktor" }
 material = { group = "com.google.android.material", name = "material", version.ref = "material" }
 activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }