|
@@ -34,8 +34,6 @@ import com.example.modifier.BuildConfig
|
|
|
import com.example.modifier.CMD_BACK
|
|
import com.example.modifier.CMD_BACK
|
|
|
import com.example.modifier.CMD_CONVERSATION_LIST_ACTIVITY
|
|
import com.example.modifier.CMD_CONVERSATION_LIST_ACTIVITY
|
|
|
import com.example.modifier.CMD_HOME
|
|
import com.example.modifier.CMD_HOME
|
|
|
-import com.example.modifier.CMD_MESSAGING_APP
|
|
|
|
|
-import com.example.modifier.CMD_MSG_SETTINGS_ACTIVITY
|
|
|
|
|
import com.example.modifier.CMD_RCS_SETTINGS_ACTIVITY
|
|
import com.example.modifier.CMD_RCS_SETTINGS_ACTIVITY
|
|
|
import com.example.modifier.Global
|
|
import com.example.modifier.Global
|
|
|
import com.example.modifier.Global.load
|
|
import com.example.modifier.Global.load
|
|
@@ -45,12 +43,16 @@ import com.example.modifier.TraverseResult
|
|
|
import com.example.modifier.Utils
|
|
import com.example.modifier.Utils
|
|
|
import com.example.modifier.databinding.FloatingWindowBinding
|
|
import com.example.modifier.databinding.FloatingWindowBinding
|
|
|
import com.example.modifier.enums.RcsConfigureState
|
|
import com.example.modifier.enums.RcsConfigureState
|
|
|
|
|
+import com.example.modifier.enums.RcsConnectionStatus
|
|
|
import com.example.modifier.http.KtorClient
|
|
import com.example.modifier.http.KtorClient
|
|
|
import com.example.modifier.http.api.RcsNumberApi
|
|
import com.example.modifier.http.api.RcsNumberApi
|
|
|
import com.example.modifier.http.api.SysConfigApi
|
|
import com.example.modifier.http.api.SysConfigApi
|
|
|
import com.example.modifier.http.request.RcsNumberRequest
|
|
import com.example.modifier.http.request.RcsNumberRequest
|
|
|
import com.example.modifier.http.response.RcsNumberResponse
|
|
import com.example.modifier.http.response.RcsNumberResponse
|
|
|
import com.example.modifier.http.response.SysConfigResponse
|
|
import com.example.modifier.http.response.SysConfigResponse
|
|
|
|
|
+import com.example.modifier.model.SocketCallback
|
|
|
|
|
+import com.example.modifier.model.TaskAction
|
|
|
|
|
+import com.example.modifier.model.TaskExecutionResult
|
|
|
import com.example.modifier.model.TelephonyConfig
|
|
import com.example.modifier.model.TelephonyConfig
|
|
|
import com.google.android.material.color.DynamicColors
|
|
import com.google.android.material.color.DynamicColors
|
|
|
import io.ktor.client.call.body
|
|
import io.ktor.client.call.body
|
|
@@ -71,16 +73,13 @@ import kotlinx.coroutines.runBlocking
|
|
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
|
|
import kotlinx.coroutines.withContext
|
|
import kotlinx.coroutines.withContext
|
|
|
import kotlinx.coroutines.withTimeoutOrNull
|
|
import kotlinx.coroutines.withTimeoutOrNull
|
|
|
|
|
+import kotlinx.serialization.encodeToString
|
|
|
|
|
+import kotlinx.serialization.json.Json
|
|
|
import org.apache.commons.collections4.queue.CircularFifoQueue
|
|
import org.apache.commons.collections4.queue.CircularFifoQueue
|
|
|
import org.apache.commons.lang3.RandomStringUtils
|
|
import org.apache.commons.lang3.RandomStringUtils
|
|
|
-import org.apache.commons.lang3.StringUtils
|
|
|
|
|
-import org.json.JSONArray
|
|
|
|
|
import org.json.JSONException
|
|
import org.json.JSONException
|
|
|
import org.json.JSONObject
|
|
import org.json.JSONObject
|
|
|
import java.util.Optional
|
|
import java.util.Optional
|
|
|
-import java.util.concurrent.ScheduledExecutorService
|
|
|
|
|
-import java.util.concurrent.ScheduledThreadPoolExecutor
|
|
|
|
|
-import java.util.concurrent.TimeUnit
|
|
|
|
|
import java.util.concurrent.atomic.AtomicReference
|
|
import java.util.concurrent.atomic.AtomicReference
|
|
|
import kotlin.coroutines.resume
|
|
import kotlin.coroutines.resume
|
|
|
import kotlin.math.max
|
|
import kotlin.math.max
|
|
@@ -105,7 +104,6 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private val handler = Handler(Looper.getMainLooper())
|
|
private val handler = Handler(Looper.getMainLooper())
|
|
|
- private val mExecutor: ScheduledExecutorService = ScheduledThreadPoolExecutor(8)
|
|
|
|
|
|
|
|
|
|
private val mSocketOpts = IO.Options()
|
|
private val mSocketOpts = IO.Options()
|
|
|
private lateinit var mSocket: Socket
|
|
private lateinit var mSocket: Socket
|
|
@@ -127,9 +125,11 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
private var cleanCount = 0
|
|
private var cleanCount = 0
|
|
|
private var lastSend = 0L
|
|
private var lastSend = 0L
|
|
|
private var rcsInterval = 0L
|
|
private var rcsInterval = 0L
|
|
|
- private var requestNumberInterval = 0
|
|
|
|
|
|
|
+ private var requestNumberInterval = 0L
|
|
|
private val running = MutableLiveData(false)
|
|
private val running = MutableLiveData(false)
|
|
|
private val requesting = MutableLiveData(false)
|
|
private val requesting = MutableLiveData(false)
|
|
|
|
|
+ private val preparing = MutableLiveData(false)
|
|
|
|
|
+ private val checkingConnection = MutableLiveData(false)
|
|
|
private var currentTaskId = 0
|
|
private var currentTaskId = 0
|
|
|
|
|
|
|
|
private var busy = MediatorLiveData<Boolean>().apply {
|
|
private var busy = MediatorLiveData<Boolean>().apply {
|
|
@@ -139,7 +139,14 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
addSource(requesting) {
|
|
addSource(requesting) {
|
|
|
value = it || running.value!!
|
|
value = it || running.value!!
|
|
|
}
|
|
}
|
|
|
- value = requesting.value!! || running.value!!
|
|
|
|
|
|
|
+ addSource(preparing) {
|
|
|
|
|
+ value = it || running.value!!
|
|
|
|
|
+ }
|
|
|
|
|
+ addSource(checkingConnection) {
|
|
|
|
|
+ value = it || running.value!!
|
|
|
|
|
+ }
|
|
|
|
|
+ value =
|
|
|
|
|
+ requesting.value!! || running.value!! || preparing.value!! || checkingConnection.value!!
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private val rcsConfigureState = MutableLiveData(RcsConfigureState.CONFIGURED)
|
|
private val rcsConfigureState = MutableLiveData(RcsConfigureState.CONFIGURED)
|
|
@@ -286,69 +293,80 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
if (data != null) {
|
|
if (data != null) {
|
|
|
val to = data.optString("to")
|
|
val to = data.optString("to")
|
|
|
val body = data.optString("body")
|
|
val body = data.optString("body")
|
|
|
- send(to, body, 2000)
|
|
|
|
|
|
|
+ CoroutineScope(Dispatchers.IO).launch {
|
|
|
|
|
+ send(to, body, 2000)
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
} else if ("task" == action) {
|
|
} else if ("task" == action) {
|
|
|
- val data = json.optJSONObject("data")
|
|
|
|
|
- val id = json.optString("id")
|
|
|
|
|
- if (data != null && StringUtils.isNoneBlank(id)) {
|
|
|
|
|
- runTask(id, data)
|
|
|
|
|
|
|
+ val taskAction = Json.decodeFromString<TaskAction>(json.toString())
|
|
|
|
|
+
|
|
|
|
|
+ CoroutineScope(Dispatchers.IO).launch {
|
|
|
|
|
+ runTask(taskAction)
|
|
|
}
|
|
}
|
|
|
- } else if ("changeNumber" == action) {
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private fun runTask(id: String, data: JSONObject) {
|
|
|
|
|
- val config = data.optJSONObject("config")
|
|
|
|
|
- config!!
|
|
|
|
|
- val rcsWait = config.optLong("rcsWait", 2000)
|
|
|
|
|
- cleanCount = config.optInt("cleanCount", 20)
|
|
|
|
|
- rcsInterval = config.optLong("rcsInterval", 0)
|
|
|
|
|
- requestNumberInterval = config.optInt("requestNumberInterval", 0)
|
|
|
|
|
- val tasks = data.optJSONArray("tasks")!!
|
|
|
|
|
- currentTaskId = data.optInt("taskId", 0)
|
|
|
|
|
- mExecutor.submit {
|
|
|
|
|
- running.postValue(true)
|
|
|
|
|
-
|
|
|
|
|
- val success = JSONArray()
|
|
|
|
|
- val fail = JSONArray()
|
|
|
|
|
- for (i in 0 until tasks.length()) {
|
|
|
|
|
- val task = tasks.optJSONObject(i)
|
|
|
|
|
- val to = task.optString("number")
|
|
|
|
|
- val body = task.optString("message")
|
|
|
|
|
- val taskId = task.optInt("id")
|
|
|
|
|
- try {
|
|
|
|
|
- if (send(to, body, rcsWait)) {
|
|
|
|
|
- success.put(taskId)
|
|
|
|
|
- } else {
|
|
|
|
|
- fail.put(taskId)
|
|
|
|
|
- }
|
|
|
|
|
- } catch (e: Exception) {
|
|
|
|
|
- e.printStackTrace()
|
|
|
|
|
- fail.put(taskId)
|
|
|
|
|
|
|
+ private suspend fun runTask(taskAction: TaskAction) {
|
|
|
|
|
+ val rcsWait = taskAction.data.config.rcsWait
|
|
|
|
|
+ cleanCount = taskAction.data.config.cleanCount
|
|
|
|
|
+ rcsInterval = taskAction.data.config.rcsInterval
|
|
|
|
|
+ requestNumberInterval = taskAction.data.config.requestNumberInterval
|
|
|
|
|
+ currentTaskId = taskAction.data.taskId
|
|
|
|
|
+
|
|
|
|
|
+ if (taskAction.data.config.checkConnection && !checkRcsAvailability()) {
|
|
|
|
|
+ mSocket.emit(
|
|
|
|
|
+ "callback",
|
|
|
|
|
+ JSONObject(
|
|
|
|
|
+ Json.encodeToString(
|
|
|
|
|
+ SocketCallback<String>(
|
|
|
|
|
+ id = taskAction.id,
|
|
|
|
|
+ status = -1,
|
|
|
|
|
+ error = "RCS not available"
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+ requestNumber()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ running.postValue(true)
|
|
|
|
|
+ val success = ArrayList<Int>()
|
|
|
|
|
+ val fail = ArrayList<Int>()
|
|
|
|
|
+ for (i in 0 until taskAction.data.tasks.size) {
|
|
|
|
|
+ val taskItem = taskAction.data.tasks[i]
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (send(taskItem.number, taskItem.message, rcsWait)) {
|
|
|
|
|
+ success.add(taskItem.id)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ fail.add(taskItem.id)
|
|
|
}
|
|
}
|
|
|
|
|
+ } catch (e: Exception) {
|
|
|
|
|
+ Log.e(TAG, "runTaskError: ${e.message}", e)
|
|
|
|
|
+ fail.add(taskItem.id)
|
|
|
}
|
|
}
|
|
|
- val res = JSONObject()
|
|
|
|
|
- try {
|
|
|
|
|
- res.put("id", id)
|
|
|
|
|
- res.put("status", 0)
|
|
|
|
|
- res.put(
|
|
|
|
|
- "data", JSONObject()
|
|
|
|
|
- .put("success", success)
|
|
|
|
|
- .put("fail", fail)
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ mSocket.emit(
|
|
|
|
|
+ "callback",
|
|
|
|
|
+ JSONObject(
|
|
|
|
|
+ Json.encodeToString(
|
|
|
|
|
+ SocketCallback(
|
|
|
|
|
+ id = taskAction.id,
|
|
|
|
|
+ status = 0,
|
|
|
|
|
+ data = TaskExecutionResult(success, fail)
|
|
|
|
|
+ )
|
|
|
)
|
|
)
|
|
|
- } catch (e: JSONException) {
|
|
|
|
|
- }
|
|
|
|
|
- mSocket.emit("callback", res)
|
|
|
|
|
- if (requestNumberInterval in 1..sendCount) {
|
|
|
|
|
- runBlocking {
|
|
|
|
|
- requestNumber()
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+ if (requestNumberInterval in 1..sendCount) {
|
|
|
|
|
+ runBlocking {
|
|
|
|
|
+ requestNumber()
|
|
|
}
|
|
}
|
|
|
- running.postValue(false)
|
|
|
|
|
}
|
|
}
|
|
|
|
|
+ running.postValue(false)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private fun smsIntent(to: String, body: String): Intent {
|
|
private fun smsIntent(to: String, body: String): Intent {
|
|
@@ -357,66 +375,57 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
intent.putExtra("sms_body", body)
|
|
intent.putExtra("sms_body", body)
|
|
|
intent.putExtra("exit_on_sent", true)
|
|
intent.putExtra("exit_on_sent", true)
|
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
|
|
|
+ intent.setPackage("com.google.android.apps.messaging")
|
|
|
return intent
|
|
return intent
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private fun send(to: String, body: String, rcsWait: Long): Boolean {
|
|
|
|
|
|
|
+ private suspend fun send(to: String, body: String, rcsWait: Long): Boolean {
|
|
|
Log.i(TAG, "Sending SMS to $to: $body")
|
|
Log.i(TAG, "Sending SMS to $to: $body")
|
|
|
startActivity(smsIntent(to, body))
|
|
startActivity(smsIntent(to, body))
|
|
|
try {
|
|
try {
|
|
|
Log.i(TAG, "Command executed successfully, waiting for app to open...")
|
|
Log.i(TAG, "Command executed successfully, waiting for app to open...")
|
|
|
- val f = mExecutor.schedule<Boolean>(
|
|
|
|
|
- {
|
|
|
|
|
- var success = false
|
|
|
|
|
- val ts = System.currentTimeMillis()
|
|
|
|
|
- while (System.currentTimeMillis() - ts < rcsWait) {
|
|
|
|
|
- val root = rootInActiveWindow
|
|
|
|
|
- val traverseResult = TraverseResult()
|
|
|
|
|
- traverseNode(root, traverseResult)
|
|
|
|
|
- if (traverseResult.isRcsCapable) {
|
|
|
|
|
- if (traverseResult.sendBtn == null) {
|
|
|
|
|
- Log.i(TAG, "Send button not found")
|
|
|
|
|
- } else {
|
|
|
|
|
- Log.i(TAG, "Clicking send button")
|
|
|
|
|
|
|
+ delay(1000)
|
|
|
|
|
+ var success = false
|
|
|
|
|
+ withTimeoutOrNull(rcsWait) {
|
|
|
|
|
+ while (true) {
|
|
|
|
|
+ val root = rootInActiveWindow
|
|
|
|
|
+ val traverseResult = TraverseResult()
|
|
|
|
|
+ traverseNode(root, traverseResult)
|
|
|
|
|
+ if (traverseResult.isRcsCapable) {
|
|
|
|
|
+ if (traverseResult.sendBtn == null) {
|
|
|
|
|
+ Log.i(TAG, "Send button not found")
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Log.i(TAG, "Clicking send button")
|
|
|
|
|
|
|
|
- val dt = System.currentTimeMillis() - lastSend
|
|
|
|
|
- if (rcsInterval > 0 && dt < rcsInterval) {
|
|
|
|
|
- Log.i(TAG, "Waiting for RCS interval")
|
|
|
|
|
- Thread.sleep(rcsInterval - dt)
|
|
|
|
|
- }
|
|
|
|
|
- traverseResult.sendBtn.performAction(AccessibilityNodeInfo.ACTION_CLICK)
|
|
|
|
|
- lastSend = System.currentTimeMillis()
|
|
|
|
|
- success = true
|
|
|
|
|
- sendCount++
|
|
|
|
|
- break
|
|
|
|
|
|
|
+ val dt = System.currentTimeMillis() - lastSend
|
|
|
|
|
+ if (rcsInterval > 0 && dt < rcsInterval) {
|
|
|
|
|
+ Log.i(TAG, "Waiting for RCS interval")
|
|
|
|
|
+ delay(rcsInterval - dt)
|
|
|
}
|
|
}
|
|
|
- } else {
|
|
|
|
|
- Log.i(TAG, "RCS not detected")
|
|
|
|
|
- }
|
|
|
|
|
- try {
|
|
|
|
|
- Thread.sleep(500)
|
|
|
|
|
- } catch (e: InterruptedException) {
|
|
|
|
|
- e.printStackTrace()
|
|
|
|
|
|
|
+ traverseResult.sendBtn!!.performAction(AccessibilityNodeInfo.ACTION_CLICK)
|
|
|
|
|
+ lastSend = System.currentTimeMillis()
|
|
|
|
|
+ success = true
|
|
|
|
|
+ sendCount++
|
|
|
|
|
+ break
|
|
|
}
|
|
}
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Log.i(TAG, "RCS not detected")
|
|
|
}
|
|
}
|
|
|
- counter++
|
|
|
|
|
- Log.i(
|
|
|
|
|
- TAG,
|
|
|
|
|
- "sendCount: $sendCount, Counter: $counter, cleanCount: $cleanCount, requestNumberInterval: $requestNumberInterval"
|
|
|
|
|
- )
|
|
|
|
|
- if (cleanCount in 1..counter) {
|
|
|
|
|
- counter = 0
|
|
|
|
|
- Thread.sleep(2000)
|
|
|
|
|
- Global.clearConv();
|
|
|
|
|
- Thread.sleep(2000)
|
|
|
|
|
- }
|
|
|
|
|
- success
|
|
|
|
|
- }, 1000, TimeUnit.MILLISECONDS
|
|
|
|
|
|
|
+ delay(200)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ counter++
|
|
|
|
|
+ Log.i(
|
|
|
|
|
+ TAG,
|
|
|
|
|
+ "sendCount: $sendCount, Counter: $counter, cleanCount: $cleanCount, requestNumberInterval: $requestNumberInterval"
|
|
|
)
|
|
)
|
|
|
- synchronized(f) {
|
|
|
|
|
- Log.i(TAG, "Waiting for task to complete...")
|
|
|
|
|
- return f.get()
|
|
|
|
|
|
|
+ if (cleanCount in 1..counter) {
|
|
|
|
|
+ counter = 0
|
|
|
|
|
+ delay(2000)
|
|
|
|
|
+ Global.clearConv();
|
|
|
|
|
+ delay(2000)
|
|
|
}
|
|
}
|
|
|
|
|
+ return success
|
|
|
} catch (e: Exception) {
|
|
} catch (e: Exception) {
|
|
|
e.printStackTrace()
|
|
e.printStackTrace()
|
|
|
}
|
|
}
|
|
@@ -467,7 +476,7 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
|
|
|
|
|
if ("com.google.android.apps.messaging:id/rcs_sim_status_status_text" == id) {
|
|
if ("com.google.android.apps.messaging:id/rcs_sim_status_status_text" == id) {
|
|
|
if (text.lowercase().contains("connected") || text.lowercase().contains("已连接")) {
|
|
if (text.lowercase().contains("connected") || text.lowercase().contains("已连接")) {
|
|
|
- result.isRcsConnected = true
|
|
|
|
|
|
|
+ result.rcsConnectionStatus = RcsConnectionStatus.CONNECTED
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -585,6 +594,11 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
binding.btnInspect.setOnClickListener {
|
|
binding.btnInspect.setOnClickListener {
|
|
|
|
|
+ CoroutineScope(Dispatchers.IO).launch {
|
|
|
|
|
+ traverseNode(rootInActiveWindow, TraverseResult())
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ binding.btnCheck.setOnClickListener {
|
|
|
CoroutineScope(Dispatchers.IO).launch {
|
|
CoroutineScope(Dispatchers.IO).launch {
|
|
|
checkRcsAvailability()
|
|
checkRcsAvailability()
|
|
|
}
|
|
}
|
|
@@ -643,6 +657,11 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private suspend fun requestNumber() {
|
|
private suspend fun requestNumber() {
|
|
|
|
|
+ if (getSharedPreferences("settings", Context.MODE_PRIVATE)
|
|
|
|
|
+ .getBoolean("do_not_request", false)
|
|
|
|
|
+ ) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
requestNumberCount++
|
|
requestNumberCount++
|
|
|
requesting.postValue(true)
|
|
requesting.postValue(true)
|
|
|
val result = withTimeoutOrNull(1.hours) {
|
|
val result = withTimeoutOrNull(1.hours) {
|
|
@@ -730,7 +749,7 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
continue
|
|
continue
|
|
|
}
|
|
}
|
|
|
val rect = Rect()
|
|
val rect = Rect()
|
|
|
- res.rcsSwitch.getBoundsInScreen(rect)
|
|
|
|
|
|
|
+ res.rcsSwitch!!.getBoundsInScreen(rect)
|
|
|
Utils.runAsRoot(
|
|
Utils.runAsRoot(
|
|
|
"input tap ${rect.centerX()} ${rect.centerY()}",
|
|
"input tap ${rect.centerX()} ${rect.centerY()}",
|
|
|
"sleep 1",
|
|
"sleep 1",
|
|
@@ -843,72 +862,85 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
suspend fun checkRcsAvailability(): Boolean {
|
|
suspend fun checkRcsAvailability(): Boolean {
|
|
|
- var rcsConnected = false
|
|
|
|
|
- repeat(3) {
|
|
|
|
|
- Utils.runAsRoot(
|
|
|
|
|
- CMD_CONVERSATION_LIST_ACTIVITY,
|
|
|
|
|
- "sleep 2",
|
|
|
|
|
- CMD_RCS_SETTINGS_ACTIVITY,
|
|
|
|
|
- "sleep 1",
|
|
|
|
|
- )
|
|
|
|
|
- val res = TraverseResult()
|
|
|
|
|
- traverseNode(rootInActiveWindow, res)
|
|
|
|
|
- if (res.isRcsConnected) {
|
|
|
|
|
- rcsConnected = true
|
|
|
|
|
- return@repeat
|
|
|
|
|
- }
|
|
|
|
|
- Utils.runAsRoot(CMD_HOME, "sleep 1")
|
|
|
|
|
- }
|
|
|
|
|
- if (!rcsConnected) {
|
|
|
|
|
- return false
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- var config: SysConfigResponse
|
|
|
|
|
- val checkRcsAvailabilityNumbers = mutableListOf<String>()
|
|
|
|
|
- withTimeoutOrNull(60.seconds) {
|
|
|
|
|
- while (true) {
|
|
|
|
|
- try {
|
|
|
|
|
- config = KtorClient.get(
|
|
|
|
|
- SysConfigApi.Id(
|
|
|
|
|
- SysConfigApi(),
|
|
|
|
|
- "check_availability_numbers"
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ checkingConnection.postValue(true)
|
|
|
|
|
+ val availability = run checkAvailability@{
|
|
|
|
|
+ val rcsConnected = run checkRcsConnection@{
|
|
|
|
|
+ repeat(3) {
|
|
|
|
|
+ Log.i(TAG, "Checking RCS status...")
|
|
|
|
|
+ Utils.runAsRoot(
|
|
|
|
|
+ CMD_CONVERSATION_LIST_ACTIVITY,
|
|
|
|
|
+ "sleep 1",
|
|
|
|
|
+ CMD_RCS_SETTINGS_ACTIVITY,
|
|
|
|
|
+ "sleep 1",
|
|
|
)
|
|
)
|
|
|
- .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)
|
|
|
|
|
|
|
+ val res = TraverseResult()
|
|
|
|
|
+ traverseNode(rootInActiveWindow, res)
|
|
|
|
|
+ if (res.rcsConnectionStatus == RcsConnectionStatus.CONNECTED) {
|
|
|
|
|
+ Log.i(TAG, "RCS is connected")
|
|
|
|
|
+ Utils.runAsRoot(CMD_BACK)
|
|
|
|
|
+ return@checkRcsConnection true
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Log.i(TAG, "RCS not connected, retrying...")
|
|
|
|
|
+ }
|
|
|
|
|
+ Utils.runAsRoot(CMD_BACK, "sleep ${it * 2}")
|
|
|
}
|
|
}
|
|
|
- delay(1.seconds)
|
|
|
|
|
|
|
+ false
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!rcsConnected) {
|
|
|
|
|
+ return@checkAvailability false
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- checkRcsAvailabilityNumbers.forEach {
|
|
|
|
|
- startActivity(smsIntent(it, ""))
|
|
|
|
|
- val s = withTimeoutOrNull(3.seconds) {
|
|
|
|
|
|
|
+ var config: SysConfigResponse
|
|
|
|
|
+ val checkRcsAvailabilityNumbers = mutableListOf<String>()
|
|
|
|
|
+ withTimeoutOrNull(60.seconds) {
|
|
|
while (true) {
|
|
while (true) {
|
|
|
- val root = rootInActiveWindow
|
|
|
|
|
- val traverseResult = TraverseResult()
|
|
|
|
|
- traverseNode(root, traverseResult)
|
|
|
|
|
- if (traverseResult.isRcsCapable) {
|
|
|
|
|
- return@withTimeoutOrNull true
|
|
|
|
|
- } else {
|
|
|
|
|
- Log.i(TAG, "RCS not detected")
|
|
|
|
|
- }
|
|
|
|
|
try {
|
|
try {
|
|
|
- delay(200)
|
|
|
|
|
- } catch (e: InterruptedException) {
|
|
|
|
|
- e.printStackTrace()
|
|
|
|
|
|
|
+ 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)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- if (s == true) {
|
|
|
|
|
- Log.i(TAG, "checkRcsAvailability: $it success")
|
|
|
|
|
- return true
|
|
|
|
|
|
|
+
|
|
|
|
|
+ checkRcsAvailabilityNumbers.forEach {
|
|
|
|
|
+ startActivity(smsIntent(it, ""))
|
|
|
|
|
+ val s = withTimeoutOrNull(3.seconds) {
|
|
|
|
|
+ while (true) {
|
|
|
|
|
+ val root = rootInActiveWindow
|
|
|
|
|
+ val traverseResult = TraverseResult()
|
|
|
|
|
+ traverseNode(root, traverseResult)
|
|
|
|
|
+ if (traverseResult.isRcsCapable) {
|
|
|
|
|
+ return@withTimeoutOrNull true
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Log.i(TAG, "RCS not detected")
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ delay(200)
|
|
|
|
|
+ } catch (e: InterruptedException) {
|
|
|
|
|
+ e.printStackTrace()
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (s == true) {
|
|
|
|
|
+ Log.i(TAG, "checkRcsAvailability: $it success")
|
|
|
|
|
+ delay(1000)
|
|
|
|
|
+ return@checkAvailability true
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+ false
|
|
|
}
|
|
}
|
|
|
- return false
|
|
|
|
|
|
|
+ checkingConnection.postValue(false)
|
|
|
|
|
+ return availability
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|