|
|
@@ -29,10 +29,6 @@ import android.widget.FrameLayout
|
|
|
import androidx.annotation.MenuRes
|
|
|
import androidx.appcompat.widget.PopupMenu
|
|
|
import androidx.core.content.ContextCompat
|
|
|
-import androidx.datastore.core.DataStore
|
|
|
-import androidx.datastore.preferences.core.Preferences
|
|
|
-import androidx.datastore.preferences.preferencesDataStore
|
|
|
-import androidx.lifecycle.MediatorLiveData
|
|
|
import androidx.lifecycle.MutableLiveData
|
|
|
import androidx.lifecycle.Observer
|
|
|
import androidx.lifecycle.liveData
|
|
|
@@ -40,7 +36,6 @@ import com.example.modifier.BuildConfig
|
|
|
import com.example.modifier.Global
|
|
|
import com.example.modifier.Global.backup
|
|
|
import com.example.modifier.Global.changeClashProfile
|
|
|
-import com.example.modifier.Global.load
|
|
|
import com.example.modifier.Global.resetAll
|
|
|
import com.example.modifier.Global.restartModifier
|
|
|
import com.example.modifier.Global.stopClash
|
|
|
@@ -54,7 +49,9 @@ import com.example.modifier.constants.CMD_RCS_SETTINGS_ACTIVITY
|
|
|
import com.example.modifier.constants.PACKAGE_GMS
|
|
|
import com.example.modifier.constants.PACKAGE_MESSAGING
|
|
|
import com.example.modifier.data.AppDatabase
|
|
|
+import com.example.modifier.data.AppPreferences
|
|
|
import com.example.modifier.data.AppPreferencesRepository
|
|
|
+import com.example.modifier.data.AppState
|
|
|
import com.example.modifier.data.AppStateRepository
|
|
|
import com.example.modifier.data.BackupItemDao
|
|
|
import com.example.modifier.databinding.FloatingWindowBinding
|
|
|
@@ -62,7 +59,7 @@ import com.example.modifier.enums.RcsConfigureState
|
|
|
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.ktorClient
|
|
|
import com.example.modifier.http.api.DeviceApi
|
|
|
import com.example.modifier.http.api.RcsNumberApi
|
|
|
import com.example.modifier.http.api.SysConfigApi
|
|
|
@@ -73,6 +70,7 @@ import com.example.modifier.http.response.SysConfigResponse
|
|
|
import com.example.modifier.model.InstallApkAction
|
|
|
import com.example.modifier.model.SocketCallback
|
|
|
import com.example.modifier.model.TaskAction
|
|
|
+import com.example.modifier.model.TaskConfig
|
|
|
import com.example.modifier.model.TaskExecutionResult
|
|
|
import com.example.modifier.model.TelephonyConfig
|
|
|
import com.example.modifier.serializer.Json
|
|
|
@@ -86,7 +84,6 @@ 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
|
|
|
@@ -101,6 +98,7 @@ import io.socket.emitter.Emitter
|
|
|
import kotlinx.coroutines.CoroutineScope
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
import kotlinx.coroutines.delay
|
|
|
+import kotlinx.coroutines.flow.StateFlow
|
|
|
import kotlinx.coroutines.isActive
|
|
|
import kotlinx.coroutines.launch
|
|
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
|
|
@@ -118,7 +116,6 @@ import java.time.temporal.ChronoUnit
|
|
|
import java.util.Optional
|
|
|
import java.util.Timer
|
|
|
import java.util.concurrent.atomic.AtomicReference
|
|
|
-import java.util.concurrent.locks.ReentrantLock
|
|
|
import kotlin.coroutines.resume
|
|
|
import kotlin.math.max
|
|
|
import kotlin.math.min
|
|
|
@@ -127,10 +124,6 @@ import kotlin.time.Duration.Companion.hours
|
|
|
import kotlin.time.Duration.Companion.minutes
|
|
|
import kotlin.time.Duration.Companion.seconds
|
|
|
|
|
|
-
|
|
|
-val Context.appPreferencesDataStore by preferencesDataStore(name = "${BuildConfig.APPLICATION_ID}.appPreferences")
|
|
|
-val Context.appStateDataStore by preferencesDataStore(name = "${BuildConfig.APPLICATION_ID}.appState")
|
|
|
-
|
|
|
@SuppressLint("SetTextI18n")
|
|
|
class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
companion object {
|
|
|
@@ -149,71 +142,10 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
private lateinit var mSocket: Socket
|
|
|
private lateinit var binding: FloatingWindowBinding
|
|
|
|
|
|
- val lock = ReentrantLock()
|
|
|
-
|
|
|
- private var canSend: Boolean
|
|
|
- get() {
|
|
|
- return getSharedPreferences(
|
|
|
- BuildConfig.APPLICATION_ID,
|
|
|
- MODE_PRIVATE
|
|
|
- ).getBoolean("canSend", false)
|
|
|
- }
|
|
|
- set(value) {
|
|
|
- getSharedPreferences(BuildConfig.APPLICATION_ID, MODE_PRIVATE).edit()
|
|
|
- .putBoolean("canSend", value).apply()
|
|
|
- reportDeviceStatues()
|
|
|
- }
|
|
|
-
|
|
|
- private var counter = 0
|
|
|
- private var cleanCount = 0
|
|
|
- private var lastSend = 0L
|
|
|
- private var rcsInterval = 0L
|
|
|
- private var requestNumberInterval = 0L
|
|
|
- private val running = MutableLiveData(false)
|
|
|
- private val requesting = MutableLiveData(false)
|
|
|
- private val preparing = MutableLiveData(false)
|
|
|
- private val checkingConnection = MutableLiveData(false)
|
|
|
private var currentTaskId = 0
|
|
|
-
|
|
|
- private var busy = MediatorLiveData<Boolean>().apply {
|
|
|
- addSource(running) {
|
|
|
- value = it || requesting.value!!
|
|
|
- }
|
|
|
- addSource(requesting) {
|
|
|
- value = it || running.value!!
|
|
|
- }
|
|
|
- addSource(preparing) {
|
|
|
- value = it || running.value!!
|
|
|
- }
|
|
|
- addSource(checkingConnection) {
|
|
|
- value = it || running.value!!
|
|
|
- }
|
|
|
- value =
|
|
|
- requesting.value!! || running.value!! || preparing.value!! || checkingConnection.value!!
|
|
|
- }
|
|
|
+ private var lastSend = 0L
|
|
|
|
|
|
private val rcsConfigureState = MutableLiveData(RcsConfigureState.CONFIGURED)
|
|
|
-
|
|
|
- private var sendCount: Int
|
|
|
- get() {
|
|
|
- return getSharedPreferences(BuildConfig.APPLICATION_ID, MODE_PRIVATE)
|
|
|
- .getInt("sendCount", 0)
|
|
|
- }
|
|
|
- set(value) {
|
|
|
- getSharedPreferences(BuildConfig.APPLICATION_ID, MODE_PRIVATE).edit()
|
|
|
- .putInt("sendCount", value).apply()
|
|
|
- }
|
|
|
-
|
|
|
- private var requestNumberCount: Int
|
|
|
- get() {
|
|
|
- return getSharedPreferences(BuildConfig.APPLICATION_ID, MODE_PRIVATE)
|
|
|
- .getInt("requestNumberCount", 0)
|
|
|
- }
|
|
|
- set(value) {
|
|
|
- getSharedPreferences(BuildConfig.APPLICATION_ID, MODE_PRIVATE).edit()
|
|
|
- .putInt("requestNumberCount", value).apply()
|
|
|
- }
|
|
|
-
|
|
|
private val logcat = liveData(Dispatchers.IO) {
|
|
|
try {
|
|
|
val logs = CircularFifoQueue<String>(128)
|
|
|
@@ -278,29 +210,26 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
AppDatabase.getDatabase(this).itemDao()
|
|
|
}
|
|
|
private val appPreferencesRepository: AppPreferencesRepository by lazy {
|
|
|
- AppPreferencesRepository(appPreferencesDataStore, this)
|
|
|
+ AppPreferencesRepository(this)
|
|
|
}
|
|
|
+ private lateinit var appPreferences: StateFlow<AppPreferences>
|
|
|
private val appStateRepository: AppStateRepository by lazy {
|
|
|
- AppStateRepository(appStateDataStore, this)
|
|
|
+ AppStateRepository(this)
|
|
|
}
|
|
|
-
|
|
|
+ private lateinit var appState: StateFlow<AppState>
|
|
|
private var requestMode = 1;
|
|
|
private var currentActivity = ""
|
|
|
|
|
|
fun connect() {
|
|
|
try {
|
|
|
- load()
|
|
|
- if (this@ModifierService::binding.isInitialized) {
|
|
|
- binding.swSend.text = Global.name
|
|
|
- }
|
|
|
if (this@ModifierService::mSocket.isInitialized) {
|
|
|
mSocket.disconnect()
|
|
|
}
|
|
|
mSocketOpts.query =
|
|
|
- "model=${Build.MODEL}&name=${Global.name}&id=${Utils.getUniqueID()}&version=${BuildConfig.VERSION_CODE}"
|
|
|
+ "model=${Build.MODEL}&name=${appPreferences.value.name}&id=${Utils.getUniqueID()}&version=${BuildConfig.VERSION_CODE}"
|
|
|
mSocketOpts.transports = arrayOf("websocket")
|
|
|
Log.i(TAG, "Connection query: ${mSocketOpts.query}")
|
|
|
- mSocket = IO.socket(Global.serverUrl, mSocketOpts)
|
|
|
+ mSocket = IO.socket(appPreferences.value.server, mSocketOpts)
|
|
|
mSocket.on("message", this@ModifierService)
|
|
|
mSocket.on(Socket.EVENT_CONNECT) {
|
|
|
Log.i(TAG, "Connected to server")
|
|
|
@@ -325,12 +254,13 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
override fun onCreate() {
|
|
|
super.onCreate()
|
|
|
Log.i(TAG, "Starting ModifierService")
|
|
|
CoroutineScope(Dispatchers.IO).launch {
|
|
|
- preparing.postValue(true)
|
|
|
+ appState = appStateRepository.getAppState()
|
|
|
+ appPreferences = appPreferencesRepository.getAppPreferences()
|
|
|
+ appStateRepository.updateRuntimeFlags(preparing = true)
|
|
|
val hasRoot = run checkRoot@{
|
|
|
repeat(30) {
|
|
|
if (hasRootAccess()) {
|
|
|
@@ -352,15 +282,16 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
if (Build.MODEL.startsWith("SM-F707") || Build.MODEL.startsWith("SM-F711")) {
|
|
|
Global.killPhoneProcess(force = false)
|
|
|
}
|
|
|
- preparing.postValue(false)
|
|
|
+ appStateRepository.updateRuntimeFlags(preparing = false)
|
|
|
+
|
|
|
+ connect()
|
|
|
+ val timer = Timer()
|
|
|
+ timer.schedule(object : java.util.TimerTask() {
|
|
|
+ override fun run() {
|
|
|
+ reportDeviceStatues()
|
|
|
+ }
|
|
|
+ }, 0, 3000)
|
|
|
}
|
|
|
- connect()
|
|
|
- val timer = Timer()
|
|
|
- timer.schedule(object : java.util.TimerTask() {
|
|
|
- override fun run() {
|
|
|
- reportDeviceStatues()
|
|
|
- }
|
|
|
- }, 0, 3000)
|
|
|
}
|
|
|
|
|
|
override fun onAccessibilityEvent(event: AccessibilityEvent) {
|
|
|
@@ -400,7 +331,17 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
val to = data.optString("to")
|
|
|
val body = data.optString("body")
|
|
|
CoroutineScope(Dispatchers.IO).launch {
|
|
|
- send(to, body, 2000)
|
|
|
+ send(
|
|
|
+ to, body, TaskConfig(
|
|
|
+ rcsWait = 3000,
|
|
|
+ rcsInterval = 1000,
|
|
|
+ cleanCount = 10,
|
|
|
+ requestNumberInterval = 50,
|
|
|
+ checkConnection = true,
|
|
|
+ useBackup = false,
|
|
|
+ endToEndEncryption = true
|
|
|
+ )
|
|
|
+ )
|
|
|
}
|
|
|
}
|
|
|
} else if ("task" == action) {
|
|
|
@@ -479,7 +420,7 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
}
|
|
|
|
|
|
private suspend fun runTask(taskAction: TaskAction) {
|
|
|
- if (checkingConnection.value!! || running.value!! || preparing.value!! || requesting.value!!) {
|
|
|
+ if (appState.value.busy) {
|
|
|
mSocket.emit(
|
|
|
"callback",
|
|
|
JSONObject(
|
|
|
@@ -496,15 +437,12 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
- val rcsWait = taskAction.data.config.rcsWait
|
|
|
- cleanCount = taskAction.data.config.cleanCount
|
|
|
- rcsInterval = taskAction.data.config.rcsInterval
|
|
|
- requestNumberInterval = taskAction.data.config.requestNumberInterval
|
|
|
+ val taskConfig = taskAction.data.config
|
|
|
currentTaskId = taskAction.data.taskId
|
|
|
requestMode = if (taskAction.data.config.useBackup) 2 else 1
|
|
|
|
|
|
if (taskAction.data.config.checkConnection) {
|
|
|
- checkingConnection.postValue(true)
|
|
|
+ appStateRepository.updateRuntimeFlags(checkingConnection = true)
|
|
|
if (!checkRcsAvailability()) {
|
|
|
mSocket.emit(
|
|
|
"callback",
|
|
|
@@ -519,13 +457,13 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
)
|
|
|
)
|
|
|
requestNumber()
|
|
|
- checkingConnection.postValue(false)
|
|
|
+ appStateRepository.updateRuntimeFlags(checkingConnection = false)
|
|
|
return
|
|
|
}
|
|
|
- checkingConnection.postValue(false)
|
|
|
+ appStateRepository.updateRuntimeFlags(checkingConnection = false)
|
|
|
}
|
|
|
|
|
|
- running.postValue(true)
|
|
|
+ appStateRepository.updateRuntimeFlags(running = true)
|
|
|
val success = ArrayList<Int>()
|
|
|
val fail = ArrayList<Int>()
|
|
|
for (i in 0 until taskAction.data.tasks.size) {
|
|
|
@@ -534,8 +472,7 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
if (send(
|
|
|
taskItem.number,
|
|
|
taskItem.message,
|
|
|
- rcsWait,
|
|
|
- taskAction.data.config.endToEndEncryption
|
|
|
+ taskConfig
|
|
|
)
|
|
|
) {
|
|
|
success.add(taskItem.id)
|
|
|
@@ -546,7 +483,6 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
Log.e(TAG, "runTaskError: ${e.message}", e)
|
|
|
fail.add(taskItem.id)
|
|
|
}
|
|
|
- updateCountUI()
|
|
|
}
|
|
|
shellRun(CMD_BACK)
|
|
|
mSocket.emit(
|
|
|
@@ -561,19 +497,19 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
)
|
|
|
)
|
|
|
)
|
|
|
- if (requestNumberInterval in 1..sendCount) {
|
|
|
+ if (taskConfig.requestNumberInterval in 1..appState.value.successNum) {
|
|
|
delay(3000)
|
|
|
requestNumber()
|
|
|
- } else if (cleanCount in 1..counter) {
|
|
|
+ } else if (taskConfig.cleanCount in 1..appState.value.executedNum) {
|
|
|
delay(3000)
|
|
|
Global.clearConv();
|
|
|
shellRun(CMD_MESSAGING_APP)
|
|
|
delay(3000)
|
|
|
- counter = 0
|
|
|
+ appStateRepository.resetExecutedNum()
|
|
|
} else {
|
|
|
delay(2000)
|
|
|
}
|
|
|
- running.postValue(false)
|
|
|
+ appStateRepository.updateRuntimeFlags(running = false)
|
|
|
} catch (e: Exception) {
|
|
|
Log.e(TAG, "runTaskError: ${e.message}", e)
|
|
|
mSocket.emit(
|
|
|
@@ -588,7 +524,7 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
)
|
|
|
)
|
|
|
)
|
|
|
- running.postValue(false)
|
|
|
+ appStateRepository.updateRuntimeFlags(running = false)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -605,8 +541,7 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
private suspend fun send(
|
|
|
to: String,
|
|
|
body: String,
|
|
|
- rcsWait: Long,
|
|
|
- endToEndEncryption: Boolean = false
|
|
|
+ taskConfig: TaskConfig
|
|
|
): Boolean {
|
|
|
Log.i(TAG, "Sending SMS to $to: $body")
|
|
|
startActivity(smsIntent(to, body))
|
|
|
@@ -615,14 +550,14 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
delay(1000)
|
|
|
var success = false
|
|
|
var traverseResult = TraverseResult()
|
|
|
- withTimeoutOrNull(rcsWait) {
|
|
|
+ withTimeoutOrNull(taskConfig.rcsWait) {
|
|
|
while (true) {
|
|
|
val root = rootInActiveWindow
|
|
|
traverseResult = TraverseResult()
|
|
|
traverseNode(root, traverseResult)
|
|
|
if (traverseResult.isRcsCapable) {
|
|
|
if (traverseResult.sendBtn != null) {
|
|
|
- if (endToEndEncryption) {
|
|
|
+ if (taskConfig.endToEndEncryption) {
|
|
|
if (traverseResult.encrypted) {
|
|
|
break
|
|
|
}
|
|
|
@@ -641,22 +576,21 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
Log.i(TAG, "Clicking send button")
|
|
|
|
|
|
val dt = System.currentTimeMillis() - lastSend
|
|
|
- if (rcsInterval > 0 && dt < rcsInterval) {
|
|
|
+ if (taskConfig.rcsInterval > 0 && dt < taskConfig.rcsInterval) {
|
|
|
Log.i(TAG, "Waiting for RCS interval")
|
|
|
- delay(rcsInterval - dt)
|
|
|
+ delay(taskConfig.rcsInterval - dt)
|
|
|
}
|
|
|
traverseResult.sendBtn!!.performAction(AccessibilityNodeInfo.ACTION_CLICK)
|
|
|
lastSend = System.currentTimeMillis()
|
|
|
success = true
|
|
|
- sendCount++
|
|
|
}
|
|
|
} else {
|
|
|
Log.i(TAG, "RCS not detected")
|
|
|
}
|
|
|
- counter++
|
|
|
+ appStateRepository.incrementExecutedNum(success)
|
|
|
Log.i(
|
|
|
TAG,
|
|
|
- "sendCount: $sendCount, Counter: $counter, cleanCount: $cleanCount, requestNumberInterval: $requestNumberInterval"
|
|
|
+ "executedNum: ${appState.value.executedNum}, successNum: ${appState.value.successNum}"
|
|
|
)
|
|
|
delay(1000)
|
|
|
return success
|
|
|
@@ -791,7 +725,6 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
val newContext = DynamicColors.wrapContextIfAvailable(applicationContext, R.style.AppTheme)
|
|
|
val inflater = LayoutInflater.from(newContext)
|
|
|
binding = FloatingWindowBinding.inflate(inflater, mLayout, true)
|
|
|
- binding.swSend.text = Global.name
|
|
|
binding.tvVersion.text = "v${BuildConfig.VERSION_CODE}"
|
|
|
windowManager.addView(mLayout, layoutParams)
|
|
|
|
|
|
@@ -841,40 +774,40 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
}
|
|
|
false
|
|
|
}
|
|
|
- binding.swSend.setOnTouchListener(touchListener)
|
|
|
|
|
|
- binding.swConnect.isChecked = true
|
|
|
- binding.swConnect.setOnCheckedChangeListener { buttonView: CompoundButton?, isChecked: Boolean ->
|
|
|
- if (isChecked) {
|
|
|
- connect()
|
|
|
- } else {
|
|
|
- if (this::mSocket.isInitialized) {
|
|
|
- mSocket.disconnect()
|
|
|
+ CoroutineScope(Dispatchers.Main).launch {
|
|
|
+ appState.collect {
|
|
|
+ binding.swSend.isChecked = it.send
|
|
|
+ binding.btnReq.isEnabled = !it.requesting
|
|
|
+ binding.tvCount.text = "${it.successNum} / ${it.executedNum}"
|
|
|
+ withContext(Dispatchers.IO) {
|
|
|
+ reportDeviceStatues()
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- binding.swSend.isChecked = canSend
|
|
|
+ CoroutineScope(Dispatchers.Main).launch {
|
|
|
+ appPreferences.collect {
|
|
|
+ binding.swSend.text = it.name
|
|
|
+ }
|
|
|
+ }
|
|
|
+ binding.swSend.setOnTouchListener(touchListener)
|
|
|
binding.swSend.setOnCheckedChangeListener { buttonView: CompoundButton?, isChecked: Boolean ->
|
|
|
- canSend = isChecked
|
|
|
+ CoroutineScope(Dispatchers.IO).launch {
|
|
|
+ appStateRepository.updateSend(isChecked)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
logcat.observeForever {
|
|
|
binding.tvLog.text = it
|
|
|
binding.scroll.fullScroll(View.FOCUS_DOWN)
|
|
|
}
|
|
|
- requesting.observeForever {
|
|
|
- binding.btnReq.isEnabled = !it
|
|
|
- }
|
|
|
|
|
|
binding.btnReq.setOnClickListener {
|
|
|
CoroutineScope(Dispatchers.IO).launch {
|
|
|
requestNumber(reset = false, noBackup = true)
|
|
|
}
|
|
|
}
|
|
|
-// binding.btnInspect.setOnClickListener {
|
|
|
-// traverseNode(rootInActiveWindow, TraverseResult())
|
|
|
-// }
|
|
|
+
|
|
|
binding.btnReset.setOnClickListener {
|
|
|
binding.btnReset.isEnabled = false
|
|
|
CoroutineScope(Dispatchers.IO).launch {
|
|
|
@@ -887,10 +820,6 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
binding.btnMore.setOnClickListener {
|
|
|
showMenu(newContext, binding.btnMore, R.menu.more)
|
|
|
}
|
|
|
- busy.observeForever {
|
|
|
- reportDeviceStatues()
|
|
|
- }
|
|
|
- updateCountUI()
|
|
|
}
|
|
|
|
|
|
private fun showMenu(context: Context, v: View, @MenuRes menuRes: Int) {
|
|
|
@@ -934,9 +863,11 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
}
|
|
|
|
|
|
R.id.reset_counter -> {
|
|
|
- sendCount = 0
|
|
|
- counter = 0
|
|
|
- updateCountUI()
|
|
|
+ CoroutineScope(Dispatchers.IO).launch {
|
|
|
+ appStateRepository.resetExecutedNum()
|
|
|
+ appStateRepository.resetSuccessNum()
|
|
|
+ appStateRepository.resetRequestedNum()
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -953,18 +884,14 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
popup.show()
|
|
|
}
|
|
|
|
|
|
- private fun updateCountUI() {
|
|
|
- binding.tvCount.text = "${sendCount} / ${counter}"
|
|
|
- }
|
|
|
-
|
|
|
private fun reportDeviceStatues() {
|
|
|
if (this::mSocket.isInitialized) {
|
|
|
val data = JSONObject()
|
|
|
try {
|
|
|
data.put("action", "updateDevice")
|
|
|
val dataObj = JSONObject()
|
|
|
- dataObj.put("canSend", canSend)
|
|
|
- dataObj.put("busy", busy.value)
|
|
|
+ dataObj.put("canSend", appState.value.send)
|
|
|
+ dataObj.put("busy", appState.value.busy)
|
|
|
dataObj.put("currentCountry", Global.telephonyConfig.country)
|
|
|
data.put("data", dataObj)
|
|
|
mSocket.emit("message", data)
|
|
|
@@ -1140,7 +1067,7 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
).let { it == RcsConfigureState.READY }
|
|
|
}
|
|
|
Log.i(TAG, "waitForRcsState: $resetSuccess")
|
|
|
- requestNumberCount = 0
|
|
|
+ appStateRepository.resetRequestedNum()
|
|
|
if (resetSuccess) {
|
|
|
delay(3000)
|
|
|
break
|
|
|
@@ -1200,7 +1127,7 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
).let { it == RcsConfigureState.READY }
|
|
|
}
|
|
|
Log.i(TAG, "waitForRcsState: $resetSuccess")
|
|
|
- requestNumberCount = 0
|
|
|
+ appStateRepository.resetRequestedNum()
|
|
|
if (resetSuccess) {
|
|
|
delay(3000)
|
|
|
break
|
|
|
@@ -1217,39 +1144,38 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
) {
|
|
|
val color = ContextCompat.getColorStateList(binding.root.context, R.color.btn_color)
|
|
|
binding.btnReq.backgroundTintList = color
|
|
|
- if (getSharedPreferences("settings", Context.MODE_PRIVATE)
|
|
|
- .getBoolean("do_not_request", false)
|
|
|
- ) {
|
|
|
+ if (appPreferences.value.preventRequest) {
|
|
|
return
|
|
|
}
|
|
|
- if (requesting.value!!) {
|
|
|
+ if (appState.value.requesting) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- requesting.postValue(true)
|
|
|
+ appStateRepository.updateRuntimeFlags(requesting = true)
|
|
|
|
|
|
if (Global.telephonyConfig.available == true) {
|
|
|
backup(
|
|
|
backupItemDao = backupItemDao,
|
|
|
type = "auto",
|
|
|
- sendCount = sendCount,
|
|
|
+ sendCount = appState.value.executedNum,
|
|
|
fresh = fresh
|
|
|
)
|
|
|
} else {
|
|
|
Global.clearConv();
|
|
|
}
|
|
|
|
|
|
- requestNumberCount++
|
|
|
+ appStateRepository.incrementRequestedNum()
|
|
|
var requestSuccess = false
|
|
|
var retry = 0
|
|
|
var needRest = reset
|
|
|
withTimeoutOrNull(1.hours) {
|
|
|
while (true) {
|
|
|
delay(200)
|
|
|
- needRest = needRest || retry > 2 || requestNumberCount > 5
|
|
|
+ needRest = needRest || retry > 2 || appState.value.requestedNum > 5
|
|
|
try {
|
|
|
- val device = KtorClient.get(DeviceApi.Id(id = Utils.getUniqueID()))
|
|
|
- .body<DeviceResponse>()
|
|
|
+ val device =
|
|
|
+ ktorClient(appPreferences.value.server).get(DeviceApi.Id(id = Utils.getUniqueID()))
|
|
|
+ .body<DeviceResponse>()
|
|
|
if (Global.isClashInstalled(applicationContext)) {
|
|
|
|
|
|
val prefs = getSharedPreferences("settings", Context.MODE_PRIVATE)
|
|
|
@@ -1291,10 +1217,7 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (needRest &&
|
|
|
- !getSharedPreferences("settings", Context.MODE_PRIVATE)
|
|
|
- .getBoolean("do_not_reset", false)
|
|
|
- ) {
|
|
|
+ if (needRest && !appPreferences.value.preventReset) {
|
|
|
reset()
|
|
|
retry = 0
|
|
|
needRest = false
|
|
|
@@ -1312,7 +1235,7 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
if (!TextUtils.isEmpty(device.pinCountry)) {
|
|
|
req.country = device.pinCountry
|
|
|
}
|
|
|
- val response = KtorClient.put(
|
|
|
+ val response = ktorClient(appPreferences.value.server).put(
|
|
|
RcsNumberApi()
|
|
|
) {
|
|
|
contentType(ContentType.Application.Json)
|
|
|
@@ -1385,7 +1308,7 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
|
|
|
launch {
|
|
|
try {
|
|
|
- KtorClient.post(
|
|
|
+ ktorClient(appPreferences.value.server).post(
|
|
|
RcsNumberApi.Id.OtpState(
|
|
|
RcsNumberApi.Id(
|
|
|
RcsNumberApi(),
|
|
|
@@ -1406,8 +1329,9 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
withTimeoutOrNull(60.seconds) {
|
|
|
while (true) {
|
|
|
try {
|
|
|
- rcsNumber = KtorClient.get(RcsNumberApi.Id(id = rcsNumber.id))
|
|
|
- .body<RcsNumberResponse>()
|
|
|
+ rcsNumber =
|
|
|
+ ktorClient(appPreferences.value.server).get(RcsNumberApi.Id(id = rcsNumber.id))
|
|
|
+ .body<RcsNumberResponse>()
|
|
|
Log.i(TAG, "wait for otp response: $rcsNumber")
|
|
|
if (rcsNumber.status == RcsNumberResponse.STATUS_SUCCESS || rcsNumber.status == RcsNumberResponse.STATUS_EXPIRED) {
|
|
|
break
|
|
|
@@ -1468,7 +1392,7 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
} else {
|
|
|
launch {
|
|
|
try {
|
|
|
- KtorClient.post(
|
|
|
+ ktorClient(appPreferences.value.server).post(
|
|
|
RcsNumberApi.Id.Configured(
|
|
|
RcsNumberApi.Id(
|
|
|
RcsNumberApi(),
|
|
|
@@ -1496,22 +1420,22 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
if (requestSuccess) {
|
|
|
Global.telephonyConfig.available = true
|
|
|
Global.save()
|
|
|
- sendCount = 0
|
|
|
- counter = 0
|
|
|
+ appStateRepository.resetSuccessNum()
|
|
|
+ appStateRepository.resetExecutedNum()
|
|
|
Log.i(TAG, "requestNumber success")
|
|
|
delay(5000)
|
|
|
shellRun(PACKAGE_MESSAGING.kill(), "sleep 1", CMD_MESSAGING_APP)
|
|
|
delay(2000)
|
|
|
} else {
|
|
|
Log.e(TAG, "requestNumber failed")
|
|
|
- canSend = false
|
|
|
+ appStateRepository.updateSend(false)
|
|
|
withContext(Dispatchers.Main) {
|
|
|
binding.swSend.isChecked = false
|
|
|
binding.btnReq.backgroundTintList =
|
|
|
ContextCompat.getColorStateList(binding.root.context, R.color.btn_color_error)
|
|
|
}
|
|
|
}
|
|
|
- requesting.postValue(false)
|
|
|
+ appStateRepository.updateRuntimeFlags(requesting = false)
|
|
|
}
|
|
|
|
|
|
private suspend fun checkRcsConnectivity(): Boolean = run checkRcsConnection@{
|
|
|
@@ -1537,7 +1461,7 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
}
|
|
|
|
|
|
suspend fun checkRcsAvailability(): Boolean {
|
|
|
- checkingConnection.postValue(true)
|
|
|
+ appStateRepository.updateRuntimeFlags(checkingConnection = true)
|
|
|
val availability = run checkAvailability@{
|
|
|
val rcsConnected = checkRcsConnectivity()
|
|
|
if (!rcsConnected) {
|
|
|
@@ -1548,7 +1472,7 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
val checkRcsAvailabilityNumbers = mutableListOf<String>()
|
|
|
withTimeoutOrNull(60.seconds) {
|
|
|
try {
|
|
|
- config = KtorClient.get(
|
|
|
+ config = ktorClient(appPreferences.value.server).get(
|
|
|
SysConfigApi.Id(
|
|
|
SysConfigApi(),
|
|
|
"check_availability_numbers"
|
|
|
@@ -1592,7 +1516,7 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
}
|
|
|
false
|
|
|
}
|
|
|
- checkingConnection.postValue(false)
|
|
|
+ appStateRepository.updateRuntimeFlags(checkingConnection = false)
|
|
|
return availability
|
|
|
}
|
|
|
|