x1ongzhu 1 rok temu
rodzic
commit
e7016b305a
22 zmienionych plików z 183 dodań i 215 usunięć
  1. 3 3
      app/src/main/java/com/example/modifier/Frida.kt
  2. 1 1
      app/src/main/java/com/example/modifier/MyApplication.kt
  3. 3 4
      app/src/main/java/com/example/modifier/adapter/BackupAdapter.kt
  4. 1 0
      app/src/main/java/com/example/modifier/enums/RequestNumberState.kt
  5. 2 1
      app/src/main/java/com/example/modifier/model/TaskConfig.kt
  6. 2 2
      app/src/main/java/com/example/modifier/receiver/MyReceiver.kt
  7. 0 2
      app/src/main/java/com/example/modifier/repo/AppStateRepository.kt
  8. 2 1
      app/src/main/java/com/example/modifier/repo/BackupRepository.kt
  9. 3 1
      app/src/main/java/com/example/modifier/repo/GoogleMessageStateRepository.kt
  10. 3 3
      app/src/main/java/com/example/modifier/repo/SpoofedSimInfoRepository.kt
  11. 26 83
      app/src/main/java/com/example/modifier/service/ModifierService.kt
  12. 1 1
      app/src/main/java/com/example/modifier/service/ScreenInspector.kt
  13. 5 5
      app/src/main/java/com/example/modifier/service/SocketClient.kt
  14. 62 52
      app/src/main/java/com/example/modifier/service/TaskRunner.kt
  15. 3 9
      app/src/main/java/com/example/modifier/ui/backup/BackupFragment.kt
  16. 5 11
      app/src/main/java/com/example/modifier/ui/login/LoginViewModel.kt
  17. 7 9
      app/src/main/java/com/example/modifier/ui/settings/SettingsFragment.kt
  18. 7 5
      app/src/main/java/com/example/modifier/ui/utils/UtilsFragment.kt
  19. 1 1
      app/src/main/java/com/example/modifier/utils/RcsHackTool.kt
  20. 5 3
      app/src/main/java/com/example/modifier/utils/Root.kt
  21. 10 8
      app/src/main/java/com/example/modifier/utils/System.kt
  22. 31 10
      app/src/main/res/layout/floating_window.xml

+ 3 - 3
app/src/main/java/com/example/modifier/Frida.kt

@@ -42,7 +42,7 @@ class Frida {
             withContext(Dispatchers.IO) {
             withContext(Dispatchers.IO) {
                 script = File.createTempFile("script", ".js")
                 script = File.createTempFile("script", ".js")
                 FileUtils.writeStringToFile(script, scriptContent, "UTF-8")
                 FileUtils.writeStringToFile(script, scriptContent, "UTF-8")
-                Log.i(com.example.modifier.TAG, "start: $binPath -p $pid  -s $script")
+                Log.i(com.example.modifier.baseTag, "start: $binPath -p $pid  -s $script")
 
 
                 p = Runtime.getRuntime().exec("su -M")
                 p = Runtime.getRuntime().exec("su -M")
                 p!!.outputStream.bufferedWriter().use {
                 p!!.outputStream.bufferedWriter().use {
@@ -60,7 +60,7 @@ class Frida {
                                 .bufferedReader()
                                 .bufferedReader()
                                 .useLines { lines ->
                                 .useLines { lines ->
                                     lines.forEach {
                                     lines.forEach {
-                                        Log.i(com.example.modifier.TAG, it)
+                                        Log.i(com.example.modifier.baseTag, it)
                                     }
                                     }
                                 }
                                 }
                         } catch (e: Exception) {
                         } catch (e: Exception) {
@@ -73,7 +73,7 @@ class Frida {
                                 .bufferedReader()
                                 .bufferedReader()
                                 .useLines { lines ->
                                 .useLines { lines ->
                                     lines.forEach {
                                     lines.forEach {
-                                        Log.e(com.example.modifier.TAG, it)
+                                        Log.e(com.example.modifier.baseTag, it)
                                     }
                                     }
                                 }
                                 }
                         } catch (e: Exception) {
                         } catch (e: Exception) {

+ 1 - 1
app/src/main/java/com/example/modifier/MyApplication.kt

@@ -5,7 +5,7 @@ import com.example.modifier.data.AppContainer
 import com.example.modifier.data.AppDataContainer
 import com.example.modifier.data.AppDataContainer
 import dagger.hilt.android.HiltAndroidApp
 import dagger.hilt.android.HiltAndroidApp
 
 
-const val TAG = "Modifier"
+const val baseTag = "Modifier"
 
 
 @HiltAndroidApp
 @HiltAndroidApp
 class MyApplication : Application() {
 class MyApplication : Application() {

+ 3 - 4
app/src/main/java/com/example/modifier/adapter/BackupAdapter.kt

@@ -11,11 +11,10 @@ import android.widget.Toast
 import androidx.appcompat.content.res.AppCompatResources
 import androidx.appcompat.content.res.AppCompatResources
 import androidx.recyclerview.widget.RecyclerView
 import androidx.recyclerview.widget.RecyclerView
 import com.example.modifier.R
 import com.example.modifier.R
-import com.example.modifier.TAG
+import com.example.modifier.baseTag
 import com.example.modifier.Utils
 import com.example.modifier.Utils
 import com.example.modifier.adapter.BackupAdapter.BackupViewHolder
 import com.example.modifier.adapter.BackupAdapter.BackupViewHolder
 import com.example.modifier.data.BackupItem
 import com.example.modifier.data.BackupItem
-import com.example.modifier.data.BackupItemDao
 import com.example.modifier.databinding.ItemBackupBinding
 import com.example.modifier.databinding.ItemBackupBinding
 import com.example.modifier.repo.BackupRepository
 import com.example.modifier.repo.BackupRepository
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
@@ -34,7 +33,7 @@ class BackupAdapter(
     private val backupRepository: BackupRepository
     private val backupRepository: BackupRepository
 ) :
 ) :
     RecyclerView.Adapter<BackupViewHolder>() {
     RecyclerView.Adapter<BackupViewHolder>() {
-
+    private val tag = "$baseTag/BackupAdapter"
 
 
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BackupViewHolder {
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BackupViewHolder {
         val binding = ItemBackupBinding.inflate(
         val binding = ItemBackupBinding.inflate(
@@ -47,7 +46,7 @@ class BackupAdapter(
 
 
     @SuppressLint("DefaultLocale")
     @SuppressLint("DefaultLocale")
     override fun onBindViewHolder(holder: BackupViewHolder, position: Int) {
     override fun onBindViewHolder(holder: BackupViewHolder, position: Int) {
-        Log.i("$TAG/BackupAdapter", "onBindViewHolder")
+        Log.i(tag, "onBindViewHolder")
         val backup = backups[position]
         val backup = backups[position]
         holder.binding.tvNumber.text = "+${backup.code} ${backup.number}"
         holder.binding.tvNumber.text = "+${backup.code} ${backup.number}"
         holder.binding.tvTime.text =
         holder.binding.tvTime.text =

+ 1 - 0
app/src/main/java/com/example/modifier/enums/RequestNumberState.kt

@@ -3,6 +3,7 @@ package com.example.modifier.enums
 enum class RequestNumberState {
 enum class RequestNumberState {
     IDLE,
     IDLE,
     RESET,
     RESET,
+    BACKUP,
     REQUEST,
     REQUEST,
     OTP_1,
     OTP_1,
     OTP_2,
     OTP_2,

+ 2 - 1
app/src/main/java/com/example/modifier/model/TaskConfig.kt

@@ -10,5 +10,6 @@ class TaskConfig(
     val requestNumberInterval: Long,
     val requestNumberInterval: Long,
     val checkConnection: Boolean,
     val checkConnection: Boolean,
     val useBackup: Boolean,
     val useBackup: Boolean,
-    val endToEndEncryption: Boolean = false,
+    val e2ee: Int = 0,
+    val e2eeTimeout: Long = 5000
 )
 )

+ 2 - 2
app/src/main/java/com/example/modifier/receiver/MyReceiver.kt

@@ -29,12 +29,12 @@ class MyReceiver : BroadcastReceiver() {
     private suspend fun clearBackup(context: Context) {
     private suspend fun clearBackup(context: Context) {
         val dao = AppDatabase.getDatabase(context).itemDao()
         val dao = AppDatabase.getDatabase(context).itemDao()
         dao.getAll().forEach {
         dao.getAll().forEach {
-            Log.i(com.example.modifier.TAG, "Deleting ${it.id}: ${it.path}")
+            Log.i(com.example.modifier.baseTag, "Deleting ${it.id}: ${it.path}")
             File(it.path).deleteRecursively()
             File(it.path).deleteRecursively()
             dao.delete(it)
             dao.delete(it)
         }
         }
         ContextCompat.getExternalFilesDirs(context, "backup")[0].listFiles()?.forEach {
         ContextCompat.getExternalFilesDirs(context, "backup")[0].listFiles()?.forEach {
-            Log.i(com.example.modifier.TAG, "clearBackup: Deleting ${it.absolutePath}")
+            Log.i(com.example.modifier.baseTag, "clearBackup: Deleting ${it.absolutePath}")
             shellRun("rm -rf ${it.absolutePath}")
             shellRun("rm -rf ${it.absolutePath}")
         }
         }
     }
     }

+ 0 - 2
app/src/main/java/com/example/modifier/repo/AppStateRepository.kt

@@ -6,8 +6,6 @@ import androidx.datastore.preferences.core.booleanPreferencesKey
 import androidx.datastore.preferences.core.edit
 import androidx.datastore.preferences.core.edit
 import androidx.datastore.preferences.core.intPreferencesKey
 import androidx.datastore.preferences.core.intPreferencesKey
 import androidx.datastore.preferences.preferencesDataStore
 import androidx.datastore.preferences.preferencesDataStore
-import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.asFlow
 import com.example.modifier.BuildConfig
 import com.example.modifier.BuildConfig
 import com.example.modifier.data.AppRuntimeFlags
 import com.example.modifier.data.AppRuntimeFlags
 import com.example.modifier.data.AppState
 import com.example.modifier.data.AppState

+ 2 - 1
app/src/main/java/com/example/modifier/repo/BackupRepository.kt

@@ -3,6 +3,7 @@ package com.example.modifier.repo
 import android.content.Context
 import android.content.Context
 import androidx.core.content.ContextCompat
 import androidx.core.content.ContextCompat
 import com.example.modifier.Utils
 import com.example.modifier.Utils
+import com.example.modifier.baseTag
 import com.example.modifier.constants.CMD_MESSAGING_APP
 import com.example.modifier.constants.CMD_MESSAGING_APP
 import com.example.modifier.constants.PACKAGE_GMS
 import com.example.modifier.constants.PACKAGE_GMS
 import com.example.modifier.constants.PACKAGE_GSF
 import com.example.modifier.constants.PACKAGE_GSF
@@ -29,7 +30,7 @@ class BackupRepository(
     private val dao: BackupItemDao,
     private val dao: BackupItemDao,
     private val spoofedSimInfoRepository: SpoofedSimInfoRepository
     private val spoofedSimInfoRepository: SpoofedSimInfoRepository
 ) {
 ) {
-
+    private val tag = "$baseTag/BackupRepository"
     suspend fun backup(
     suspend fun backup(
         spoofedSimInfo: SpoofedSimInfo,
         spoofedSimInfo: SpoofedSimInfo,
         type: String,
         type: String,

+ 3 - 1
app/src/main/java/com/example/modifier/repo/GoogleMessageStateRepository.kt

@@ -6,6 +6,7 @@ import android.os.Looper
 import android.util.Log
 import android.util.Log
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.Observer
 import androidx.lifecycle.Observer
+import com.example.modifier.baseTag
 import com.example.modifier.enums.RcsConfigureState
 import com.example.modifier.enums.RcsConfigureState
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.delay
@@ -18,6 +19,7 @@ import kotlin.coroutines.resume
 import kotlin.time.Duration
 import kotlin.time.Duration
 
 
 class GoogleMessageStateRepository(context: Context) {
 class GoogleMessageStateRepository(context: Context) {
+    private val tag = "$baseTag/GoogleMessageStateRepository"
     private val handler = Handler(Looper.getMainLooper())
     private val handler = Handler(Looper.getMainLooper())
     val logs = MutableLiveData<String>()
     val logs = MutableLiveData<String>()
     val rcsConfigureState = MutableLiveData(RcsConfigureState.CONFIGURED)
     val rcsConfigureState = MutableLiveData(RcsConfigureState.CONFIGURED)
@@ -102,7 +104,7 @@ class GoogleMessageStateRepository(context: Context) {
 
 
                     continuation.invokeOnCancellation {
                     continuation.invokeOnCancellation {
                         handler.post {
                         handler.post {
-                            Log.i(com.example.modifier.TAG, "removeObserver")
+                            Log.i( tag, "removeObserver")
                             rcsConfigureState.removeObserver(observer)
                             rcsConfigureState.removeObserver(observer)
                         }
                         }
                     }
                     }

+ 3 - 3
app/src/main/java/com/example/modifier/repo/SpoofedSimInfoRepository.kt

@@ -12,6 +12,7 @@ import androidx.datastore.preferences.core.stringPreferencesKey
 import androidx.datastore.preferences.preferencesDataStore
 import androidx.datastore.preferences.preferencesDataStore
 import com.example.modifier.BuildConfig
 import com.example.modifier.BuildConfig
 import com.example.modifier.Utils
 import com.example.modifier.Utils
+import com.example.modifier.baseTag
 import com.example.modifier.constants.PACKAGE_GMS
 import com.example.modifier.constants.PACKAGE_GMS
 import com.example.modifier.constants.PACKAGE_MESSAGING
 import com.example.modifier.constants.PACKAGE_MESSAGING
 import com.example.modifier.model.SpoofedSimInfo
 import com.example.modifier.model.SpoofedSimInfo
@@ -24,11 +25,9 @@ import com.example.modifier.utils.isOldVersion
 import com.example.modifier.utils.resumePackage
 import com.example.modifier.utils.resumePackage
 import com.example.modifier.utils.shellRun
 import com.example.modifier.utils.shellRun
 import com.example.modifier.utils.suspendPackage
 import com.example.modifier.utils.suspendPackage
-import com.google.gson.Gson
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.flow.stateIn
-import kotlinx.serialization.decodeFromString
 import org.apache.commons.io.FileUtils
 import org.apache.commons.io.FileUtils
 import java.io.File
 import java.io.File
 import kotlin.coroutines.coroutineContext
 import kotlin.coroutines.coroutineContext
@@ -36,6 +35,7 @@ import kotlin.coroutines.coroutineContext
 val Context.simInfoDataStore by preferencesDataStore(name = "${BuildConfig.APPLICATION_ID}.simInfo")
 val Context.simInfoDataStore by preferencesDataStore(name = "${BuildConfig.APPLICATION_ID}.simInfo")
 
 
 class SpoofedSimInfoRepository(private val context: Context) {
 class SpoofedSimInfoRepository(private val context: Context) {
+    private val tag = "$baseTag/SpoofedSimInfoRepository"
 
 
     private object PreferencesKeys {
     private object PreferencesKeys {
         val NUMBER = stringPreferencesKey("number")
         val NUMBER = stringPreferencesKey("number")
@@ -153,7 +153,7 @@ class SpoofedSimInfoRepository(private val context: Context) {
                     if (info != null) {
                     if (info != null) {
                         val mcc = info.mccString
                         val mcc = info.mccString
                         val mnc = info.mncString
                         val mnc = info.mncString
-                        Log.i(com.example.modifier.TAG, "mccmnc spoofed: $mcc$mnc")
+                        Log.i(tag, "mccmnc spoofed: $mcc$mnc")
                     }
                     }
                 }
                 }
             }
             }

+ 26 - 83
app/src/main/java/com/example/modifier/service/ModifierService.kt

@@ -2,14 +2,9 @@ package com.example.modifier.service
 
 
 import android.accessibilityservice.AccessibilityService
 import android.accessibilityservice.AccessibilityService
 import android.annotation.SuppressLint
 import android.annotation.SuppressLint
-import android.content.ComponentName
 import android.content.Context
 import android.content.Context
 import android.graphics.PixelFormat
 import android.graphics.PixelFormat
 import android.os.Build
 import android.os.Build
-import android.os.Handler
-import android.os.Looper
-import android.text.TextUtils
-import android.util.Base64
 import android.util.DisplayMetrics
 import android.util.DisplayMetrics
 import android.util.Log
 import android.util.Log
 import android.view.Gravity
 import android.view.Gravity
@@ -21,7 +16,6 @@ import android.view.View.OnTouchListener
 import android.view.View.VISIBLE
 import android.view.View.VISIBLE
 import android.view.WindowManager
 import android.view.WindowManager
 import android.view.accessibility.AccessibilityEvent
 import android.view.accessibility.AccessibilityEvent
-import android.view.accessibility.AccessibilityNodeInfo
 import android.widget.CompoundButton
 import android.widget.CompoundButton
 import android.widget.FrameLayout
 import android.widget.FrameLayout
 import androidx.annotation.MenuRes
 import androidx.annotation.MenuRes
@@ -29,109 +23,46 @@ import androidx.appcompat.widget.PopupMenu
 import androidx.core.content.ContextCompat
 import androidx.core.content.ContextCompat
 import com.example.modifier.BuildConfig
 import com.example.modifier.BuildConfig
 import com.example.modifier.R
 import com.example.modifier.R
-import com.example.modifier.TAG
+import com.example.modifier.baseTag
 import com.example.modifier.TraverseResult
 import com.example.modifier.TraverseResult
-import com.example.modifier.constants.CMD_BACK
-import com.example.modifier.constants.CMD_CONVERSATION_LIST_ACTIVITY
-import com.example.modifier.constants.CMD_MESSAGING_APP
-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.AppDatabase
 import com.example.modifier.data.AppPreferences
 import com.example.modifier.data.AppPreferences
-import com.example.modifier.repo.AppPreferencesRepository
 import com.example.modifier.data.AppState
 import com.example.modifier.data.AppState
-import com.example.modifier.repo.AppStateRepository
-import com.example.modifier.repo.GoogleMessageStateRepository
 import com.example.modifier.databinding.FloatingWindowBinding
 import com.example.modifier.databinding.FloatingWindowBinding
-import com.example.modifier.enums.RcsConfigureState
-import com.example.modifier.enums.RcsConnectionStatus
 import com.example.modifier.enums.RequestNumberState
 import com.example.modifier.enums.RequestNumberState
-import com.example.modifier.extension.kill
-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.ktorClient
-import com.example.modifier.http.request.RcsNumberRequest
-import com.example.modifier.http.response.DeviceResponse
-import com.example.modifier.http.response.RcsNumberResponse
-import com.example.modifier.http.response.SysConfigResponse
-import com.example.modifier.model.InstallApkAction
 import com.example.modifier.model.SpoofedSimInfo
 import com.example.modifier.model.SpoofedSimInfo
-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.repo.AppPreferencesRepository
+import com.example.modifier.repo.AppStateRepository
 import com.example.modifier.repo.BackupRepository
 import com.example.modifier.repo.BackupRepository
+import com.example.modifier.repo.GoogleMessageStateRepository
 import com.example.modifier.repo.SpoofedSimInfoRepository
 import com.example.modifier.repo.SpoofedSimInfoRepository
-import com.example.modifier.serializer.Json
-import com.example.modifier.utils.changeClashProfile
 import com.example.modifier.utils.clearConv
 import com.example.modifier.utils.clearConv
-import com.example.modifier.utils.genICCID
-import com.example.modifier.utils.genIMEI
-import com.example.modifier.utils.genIMSI
 import com.example.modifier.utils.hasRootAccess
 import com.example.modifier.utils.hasRootAccess
-import com.example.modifier.utils.isClashInstalled
-import com.example.modifier.utils.isOldVersion
 import com.example.modifier.utils.isRebooted
 import com.example.modifier.utils.isRebooted
 import com.example.modifier.utils.killPhoneProcess
 import com.example.modifier.utils.killPhoneProcess
 import com.example.modifier.utils.optimize
 import com.example.modifier.utils.optimize
-import com.example.modifier.utils.resetAll
 import com.example.modifier.utils.restartSelf
 import com.example.modifier.utils.restartSelf
 import com.example.modifier.utils.setBatteryLevel
 import com.example.modifier.utils.setBatteryLevel
-import com.example.modifier.utils.shellRun
-import com.example.modifier.utils.smsIntent
-import com.example.modifier.utils.spoofSmsIntent
-import com.example.modifier.utils.stopClash
 import com.example.modifier.utils.syncTime
 import com.example.modifier.utils.syncTime
-import com.example.modifier.utils.uniqueId
 import com.google.android.material.color.DynamicColors
 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.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.timeout
-import io.ktor.client.request.prepareGet
-import io.ktor.client.request.setBody
-import io.ktor.http.ContentType
-import io.ktor.http.contentType
-import io.ktor.utils.io.ByteReadChannel
-import io.ktor.utils.io.core.isEmpty
-import io.ktor.utils.io.core.readBytes
-import io.socket.client.IO
-import io.socket.client.Socket
-import io.socket.emitter.Emitter
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 import kotlinx.coroutines.withContext
-import kotlinx.coroutines.withTimeout
-import kotlinx.coroutines.withTimeoutOrNull
-import kotlinx.serialization.encodeToString
-import org.json.JSONException
-import org.json.JSONObject
-import java.io.File
-import java.time.LocalDateTime
-import java.time.temporal.ChronoUnit
 import java.util.Timer
 import java.util.Timer
 import java.util.TimerTask
 import java.util.TimerTask
 import java.util.concurrent.atomic.AtomicReference
 import java.util.concurrent.atomic.AtomicReference
-import kotlin.coroutines.coroutineContext
 import kotlin.math.max
 import kotlin.math.max
 import kotlin.math.min
 import kotlin.math.min
-import kotlin.time.Duration.Companion.hours
 import kotlin.time.Duration.Companion.minutes
 import kotlin.time.Duration.Companion.minutes
 import kotlin.time.Duration.Companion.seconds
 import kotlin.time.Duration.Companion.seconds
 
 
 @SuppressLint("SetTextI18n")
 @SuppressLint("SetTextI18n")
 class ModifierService : AccessibilityService() {
 class ModifierService : AccessibilityService() {
+    private val tag = "$baseTag/AccessibilityService"
+
     companion object {
     companion object {
         const val NAME: String = BuildConfig.APPLICATION_ID + ".service.ModifierService"
         const val NAME: String = BuildConfig.APPLICATION_ID + ".service.ModifierService"
 
 
@@ -165,13 +96,13 @@ class ModifierService : AccessibilityService() {
     override fun onAccessibilityEvent(event: AccessibilityEvent) {}
     override fun onAccessibilityEvent(event: AccessibilityEvent) {}
 
 
     override fun onInterrupt() {
     override fun onInterrupt() {
-        Log.e("$TAG/AccessibilityService", "onInterrupt")
+        Log.e(tag, "onInterrupt")
     }
     }
 
 
     @SuppressLint("ClickableViewAccessibility")
     @SuppressLint("ClickableViewAccessibility")
     override fun onServiceConnected() {
     override fun onServiceConnected() {
         super.onServiceConnected()
         super.onServiceConnected()
-        Log.i("$TAG/AccessibilityService", "onServiceConnected")
+        Log.i(tag, "onServiceConnected")
         instance = this
         instance = this
 
 
         val displayMetrics = DisplayMetrics()
         val displayMetrics = DisplayMetrics()
@@ -205,7 +136,7 @@ class ModifierService : AccessibilityService() {
         binding.root.post {
         binding.root.post {
             maxX = width - binding.root.measuredWidth
             maxX = width - binding.root.measuredWidth
             maxY = height - binding.root.measuredHeight
             maxY = height - binding.root.measuredHeight
-            Log.i(TAG, "measured: $maxX, $maxY")
+            Log.i(tag, "measured: $maxX, $maxY")
             layoutParams.x = maxX
             layoutParams.x = maxX
             windowManager.updateViewLayout(mLayout, layoutParams)
             windowManager.updateViewLayout(mLayout, layoutParams)
         }
         }
@@ -283,27 +214,32 @@ class ModifierService : AccessibilityService() {
 
 
                             RequestNumberState.RESET -> {
                             RequestNumberState.RESET -> {
                                 binding.tvStatus.visibility = VISIBLE
                                 binding.tvStatus.visibility = VISIBLE
-                                binding.tvStatus.text = "Resetting GMS"
+                                binding.tvStatus.text = "Reset GMS"
+                            }
+
+                            RequestNumberState.BACKUP -> {
+                                binding.tvStatus.visibility = VISIBLE
+                                binding.tvStatus.text = "backing up"
                             }
                             }
 
 
                             RequestNumberState.REQUEST -> {
                             RequestNumberState.REQUEST -> {
                                 binding.tvStatus.visibility = VISIBLE
                                 binding.tvStatus.visibility = VISIBLE
-                                binding.tvStatus.text = "Requesting Number"
+                                binding.tvStatus.text = "requesting number"
                             }
                             }
 
 
                             RequestNumberState.OTP_1 -> {
                             RequestNumberState.OTP_1 -> {
                                 binding.tvStatus.visibility = VISIBLE
                                 binding.tvStatus.visibility = VISIBLE
-                                binding.tvStatus.text = "Waiting for OTP Sent"
+                                binding.tvStatus.text = "waiting for OTP sent"
                             }
                             }
 
 
                             RequestNumberState.OTP_2 -> {
                             RequestNumberState.OTP_2 -> {
                                 binding.tvStatus.visibility = VISIBLE
                                 binding.tvStatus.visibility = VISIBLE
-                                binding.tvStatus.text = "Waiting for OTP Received"
+                                binding.tvStatus.text = "waiting for OTP received"
                             }
                             }
 
 
                             RequestNumberState.CONFIG -> {
                             RequestNumberState.CONFIG -> {
                                 binding.tvStatus.visibility = VISIBLE
                                 binding.tvStatus.visibility = VISIBLE
-                                binding.tvStatus.text = "Waiting for Configuration"
+                                binding.tvStatus.text = "waiting for configuration"
                             }
                             }
                         }
                         }
                     }
                     }
@@ -329,6 +265,13 @@ class ModifierService : AccessibilityService() {
                     )
                     )
                 }
                 }
             }
             }
+            launch {
+                spoofedSimInfo.collect {
+                    withContext(Dispatchers.Main) {
+                        binding.tvCountry.text = it.country
+                    }
+                }
+            }
 
 
             appStateRepository.updateRuntimeFlags(preparing = true)
             appStateRepository.updateRuntimeFlags(preparing = true)
             val hasRoot = run checkRoot@{
             val hasRoot = run checkRoot@{

+ 1 - 1
app/src/main/java/com/example/modifier/service/ScreenInspector.kt

@@ -24,7 +24,7 @@ class ScreenInspector(val context: AccessibilityService) {
             .orElse(null)
             .orElse(null)
         val id = node.viewIdResourceName
         val id = node.viewIdResourceName
 
 
-        Log.d(com.example.modifier.TAG, "Node: class=$className, text=$text, name=$name, id=$id")
+        Log.d(com.example.modifier.baseTag, "Node: class=$className, text=$text, name=$name, id=$id")
 
 
         if ("Compose:Draft:Send" == name) {
         if ("Compose:Draft:Send" == name) {
             result.sendBtn = node
             result.sendBtn = node

+ 5 - 5
app/src/main/java/com/example/modifier/service/SocketClient.kt

@@ -3,7 +3,7 @@ package com.example.modifier.service
 import android.os.Build
 import android.os.Build
 import android.util.Log
 import android.util.Log
 import com.example.modifier.BuildConfig
 import com.example.modifier.BuildConfig
-import com.example.modifier.TAG
+import com.example.modifier.baseTag
 import com.example.modifier.model.InstallApkAction
 import com.example.modifier.model.InstallApkAction
 import com.example.modifier.model.RunScriptAction
 import com.example.modifier.model.RunScriptAction
 import com.example.modifier.model.RunScriptResult
 import com.example.modifier.model.RunScriptResult
@@ -29,7 +29,7 @@ class SocketClient(
     private val name: String,
     private val name: String,
     private val taskRunner: TaskRunner
     private val taskRunner: TaskRunner
 ) : Emitter.Listener {
 ) : Emitter.Listener {
-    private val tag = "$TAG/SocketClient"
+    private val tag = "$baseTag/SocketClient"
     private val mSocketOpts: IO.Options = IO.Options()
     private val mSocketOpts: IO.Options = IO.Options()
     private val mSocket: Socket
     private val mSocket: Socket
 
 
@@ -45,7 +45,7 @@ class SocketClient(
         mSocket.on(Socket.EVENT_DISCONNECT) { this.onDisconnected(it) }
         mSocket.on(Socket.EVENT_DISCONNECT) { this.onDisconnected(it) }
         mSocket.on(Socket.EVENT_CONNECT_ERROR) {
         mSocket.on(Socket.EVENT_CONNECT_ERROR) {
             it.forEach {
             it.forEach {
-                Log.e(TAG, "Connection error", it as Throwable)
+                Log.e(tag, "Connection error", it as Throwable)
             }
             }
         }
         }
         try {
         try {
@@ -62,7 +62,7 @@ class SocketClient(
 
 
     override fun call(vararg args: Any?) {
     override fun call(vararg args: Any?) {
         if (args.isNotEmpty()) {
         if (args.isNotEmpty()) {
-            Log.i(TAG, "Received message: " + args[0])
+            Log.i(tag, "Received message: " + args[0])
             if (args[0] is JSONObject) {
             if (args[0] is JSONObject) {
                 val json = args[0] as JSONObject
                 val json = args[0] as JSONObject
                 val action = json.optString("action")
                 val action = json.optString("action")
@@ -81,7 +81,7 @@ class SocketClient(
                                     requestNumberInterval = 50,
                                     requestNumberInterval = 50,
                                     checkConnection = true,
                                     checkConnection = true,
                                     useBackup = false,
                                     useBackup = false,
-                                    endToEndEncryption = true
+                                    e2ee = 0
                                 )
                                 )
                             )
                             )
                         }
                         }

+ 62 - 52
app/src/main/java/com/example/modifier/service/TaskRunner.kt

@@ -5,7 +5,7 @@ import android.text.TextUtils
 import android.util.Base64
 import android.util.Base64
 import android.util.Log
 import android.util.Log
 import android.view.accessibility.AccessibilityNodeInfo
 import android.view.accessibility.AccessibilityNodeInfo
-import com.example.modifier.TAG
+import com.example.modifier.baseTag
 import com.example.modifier.TraverseResult
 import com.example.modifier.TraverseResult
 import com.example.modifier.constants.CMD_BACK
 import com.example.modifier.constants.CMD_BACK
 import com.example.modifier.constants.CMD_CONVERSATION_LIST_ACTIVITY
 import com.example.modifier.constants.CMD_CONVERSATION_LIST_ACTIVITY
@@ -29,7 +29,6 @@ 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.InstallApkAction
 import com.example.modifier.model.InstallApkAction
 import com.example.modifier.model.RunScriptAction
 import com.example.modifier.model.RunScriptAction
-import com.example.modifier.model.SocketCallback
 import com.example.modifier.model.SpoofedSimInfo
 import com.example.modifier.model.SpoofedSimInfo
 import com.example.modifier.model.TaskAction
 import com.example.modifier.model.TaskAction
 import com.example.modifier.model.TaskConfig
 import com.example.modifier.model.TaskConfig
@@ -39,7 +38,6 @@ import com.example.modifier.repo.AppStateRepository
 import com.example.modifier.repo.BackupRepository
 import com.example.modifier.repo.BackupRepository
 import com.example.modifier.repo.GoogleMessageStateRepository
 import com.example.modifier.repo.GoogleMessageStateRepository
 import com.example.modifier.repo.SpoofedSimInfoRepository
 import com.example.modifier.repo.SpoofedSimInfoRepository
-import com.example.modifier.serializer.Json
 import com.example.modifier.utils.changeClashProfile
 import com.example.modifier.utils.changeClashProfile
 import com.example.modifier.utils.clearConv
 import com.example.modifier.utils.clearConv
 import com.example.modifier.utils.genICCID
 import com.example.modifier.utils.genICCID
@@ -77,8 +75,6 @@ import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 import kotlinx.coroutines.withContext
 import kotlinx.coroutines.withTimeout
 import kotlinx.coroutines.withTimeout
 import kotlinx.coroutines.withTimeoutOrNull
 import kotlinx.coroutines.withTimeoutOrNull
-import kotlinx.serialization.encodeToString
-import org.json.JSONObject
 import java.io.File
 import java.io.File
 import java.time.LocalDateTime
 import java.time.LocalDateTime
 import java.time.temporal.ChronoUnit
 import java.time.temporal.ChronoUnit
@@ -97,6 +93,7 @@ class TaskRunner(
     private val googleMessageStateRepository: GoogleMessageStateRepository,
     private val googleMessageStateRepository: GoogleMessageStateRepository,
     private val backupRepository: BackupRepository
     private val backupRepository: BackupRepository
 ) {
 ) {
+    private val tag = "$baseTag/TaskRunner"
     private var lastSend = 0L
     private var lastSend = 0L
     private var currentTaskId = 0
     private var currentTaskId = 0
     private var requestMode = 1
     private var requestMode = 1
@@ -117,37 +114,49 @@ class TaskRunner(
         body: String,
         body: String,
         taskConfig: TaskConfig
         taskConfig: TaskConfig
     ): Boolean {
     ): Boolean {
-        Log.i(TAG, "Sending SMS to $to: $body")
+        Log.i(tag, "Sending SMS to $to: $body")
         context.startActivity(smsIntent(to, body))
         context.startActivity(smsIntent(to, body))
         try {
         try {
             Log.i(
             Log.i(
-                TAG,
+                tag,
                 "Command executed successfully, waiting for app to open..."
                 "Command executed successfully, waiting for app to open..."
             )
             )
             delay(1000)
             delay(1000)
             var success = false
             var success = false
             var traverseResult = TraverseResult()
             var traverseResult = TraverseResult()
             withTimeoutOrNull(taskConfig.rcsWait) {
             withTimeoutOrNull(taskConfig.rcsWait) {
-                while (true) {
+                repeat(999) {
                     traverseResult = TraverseResult()
                     traverseResult = TraverseResult()
                     screenInspector.traverseNode(traverseResult)
                     screenInspector.traverseNode(traverseResult)
                     if (traverseResult.isRcsCapable && traverseResult.sendBtn != null) {
                     if (traverseResult.isRcsCapable && traverseResult.sendBtn != null) {
-                        if (!taskConfig.endToEndEncryption || traverseResult.encrypted) {
-                            break
-                        }
+                        return@withTimeoutOrNull
                     }
                     }
                     delay(200)
                     delay(200)
                 }
                 }
             }
             }
+            if (traverseResult.isRcsCapable && traverseResult.sendBtn != null && taskConfig.e2ee > 0) {
+                withTimeoutOrNull(taskConfig.e2eeTimeout) {
+                    repeat(999) {
+                        traverseResult = TraverseResult()
+                        screenInspector.traverseNode(traverseResult)
+                        if (traverseResult.encrypted) {
+                            return@withTimeoutOrNull
+                        }
+                        delay(200)
+                    }
+                }
+            }
             if (traverseResult.isRcsCapable) {
             if (traverseResult.isRcsCapable) {
                 if (traverseResult.sendBtn == null) {
                 if (traverseResult.sendBtn == null) {
-                    Log.i(TAG, "Send button not found")
+                    Log.i(tag, "Send button not found")
+                } else if (taskConfig.e2ee == 2 && !traverseResult.encrypted) {
+                    Log.i(tag, "E2EE not detected")
                 } else {
                 } else {
-                    Log.i(TAG, "Clicking send button")
+                    Log.i(tag, "Clicking send button")
 
 
                     val dt = System.currentTimeMillis() - lastSend
                     val dt = System.currentTimeMillis() - lastSend
                     if (taskConfig.rcsInterval > 0 && dt < taskConfig.rcsInterval) {
                     if (taskConfig.rcsInterval > 0 && dt < taskConfig.rcsInterval) {
-                        Log.i(TAG, "Waiting for RCS interval")
+                        Log.i(tag, "Waiting for RCS interval")
                         delay(taskConfig.rcsInterval - dt)
                         delay(taskConfig.rcsInterval - dt)
                     }
                     }
                     traverseResult.sendBtn!!.performAction(AccessibilityNodeInfo.ACTION_CLICK)
                     traverseResult.sendBtn!!.performAction(AccessibilityNodeInfo.ACTION_CLICK)
@@ -155,11 +164,11 @@ class TaskRunner(
                     success = true
                     success = true
                 }
                 }
             } else {
             } else {
-                Log.i(TAG, "RCS not detected")
+                Log.i(tag, "RCS not detected")
             }
             }
             appStateRepository.incrementExecutedNum(success)
             appStateRepository.incrementExecutedNum(success)
             Log.i(
             Log.i(
-                TAG,
+                tag,
                 "executedNum: ${appState.value.executedNum}, successNum: ${appState.value.successNum}"
                 "executedNum: ${appState.value.executedNum}, successNum: ${appState.value.successNum}"
             )
             )
             delay(1000)
             delay(1000)
@@ -213,7 +222,7 @@ class TaskRunner(
                         fail.add(taskItem.id)
                         fail.add(taskItem.id)
                     }
                     }
                 } catch (e: Exception) {
                 } catch (e: Exception) {
-                    Log.e(TAG, "runTaskError: ${e.message}", e)
+                    Log.e(tag, "runTaskError: ${e.message}", e)
                     fail.add(taskItem.id)
                     fail.add(taskItem.id)
                 }
                 }
             }
             }
@@ -233,7 +242,7 @@ class TaskRunner(
             }
             }
             appStateRepository.updateRuntimeFlags(running = false)
             appStateRepository.updateRuntimeFlags(running = false)
         } catch (e: Exception) {
         } catch (e: Exception) {
-            Log.e(TAG, "runTaskError: ${e.message}", e)
+            Log.e(tag, "runTaskError: ${e.message}", e)
             onError(e)
             onError(e)
             appStateRepository.updateRuntimeFlags(running = false)
             appStateRepository.updateRuntimeFlags(running = false)
         }
         }
@@ -267,18 +276,18 @@ class TaskRunner(
                         }
                         }
                         if (switchAppear != true) {
                         if (switchAppear != true) {
                             Log.e(
                             Log.e(
-                                TAG,
+                                tag,
                                 "RCS not entered default on state, retrying..."
                                 "RCS not entered default on state, retrying..."
                             )
                             )
                             continue
                             continue
                         }
                         }
                     }
                     }
                     if (!screenController.toggleRcsSwitch(false)) {
                     if (!screenController.toggleRcsSwitch(false)) {
-                        Log.e(TAG, "RCS switch not turned off, retrying...")
+                        Log.e(tag, "RCS switch not turned off, retrying...")
                         continue
                         continue
                     }
                     }
                     if (!screenController.toggleRcsSwitch(true)) {
                     if (!screenController.toggleRcsSwitch(true)) {
-                        Log.e(TAG, "RCS switch not turned on, retrying...")
+                        Log.e(tag, "RCS switch not turned on, retrying...")
                         continue
                         continue
                     }
                     }
                     var resetSuccess = googleMessageStateRepository.waitForRcsState(
                     var resetSuccess = googleMessageStateRepository.waitForRcsState(
@@ -296,7 +305,7 @@ class TaskRunner(
                             ), 1.minutes
                             ), 1.minutes
                         ).let { it == RcsConfigureState.READY }
                         ).let { it == RcsConfigureState.READY }
                     }
                     }
-                    Log.i(TAG, "waitForRcsState: $resetSuccess")
+                    Log.i(tag, "waitForRcsState: $resetSuccess")
                     appStateRepository.resetRequestedNum()
                     appStateRepository.resetRequestedNum()
                     if (resetSuccess) {
                     if (resetSuccess) {
                         delay(3000)
                         delay(3000)
@@ -331,7 +340,7 @@ class TaskRunner(
                         }
                         }
                         if (switchAppear != true) {
                         if (switchAppear != true) {
                             Log.e(
                             Log.e(
-                                TAG,
+                                tag,
                                 "RCS not entered default on state, retrying..."
                                 "RCS not entered default on state, retrying..."
                             )
                             )
                             continue
                             continue
@@ -339,7 +348,7 @@ class TaskRunner(
                     }
                     }
                     val switchOn = screenController.toggleRcsSwitch(true)
                     val switchOn = screenController.toggleRcsSwitch(true)
                     if (!switchOn) {
                     if (!switchOn) {
-                        Log.e(TAG, "RCS switch not turned on, retrying...")
+                        Log.e(tag, "RCS switch not turned on, retrying...")
                         continue
                         continue
                     }
                     }
                     var resetSuccess = googleMessageStateRepository.waitForRcsState(
                     var resetSuccess = googleMessageStateRepository.waitForRcsState(
@@ -357,7 +366,7 @@ class TaskRunner(
                             ), 1.minutes
                             ), 1.minutes
                         ).let { it == RcsConfigureState.READY }
                         ).let { it == RcsConfigureState.READY }
                     }
                     }
-                    Log.i(TAG, "waitForRcsState: $resetSuccess")
+                    Log.i(tag, "waitForRcsState: $resetSuccess")
                     appStateRepository.resetRequestedNum()
                     appStateRepository.resetRequestedNum()
                     if (resetSuccess) {
                     if (resetSuccess) {
                         delay(3000)
                         delay(3000)
@@ -441,6 +450,7 @@ class TaskRunner(
                                 requestSuccess = true
                                 requestSuccess = true
                                 break
                                 break
                             } else {
                             } else {
+                                appStateRepository.updateRuntimeFlags(requestNumberState = RequestNumberState.BACKUP)
                                 backupRepository.backup(
                                 backupRepository.backup(
                                     spoofedSimInfo = spoofedSimInfo.value,
                                     spoofedSimInfo = spoofedSimInfo.value,
                                     type = "auto",
                                     type = "auto",
@@ -478,7 +488,7 @@ class TaskRunner(
                         }
                         }
                     }
                     }
                     var rcsNumber = response.body<RcsNumberResponse>()
                     var rcsNumber = response.body<RcsNumberResponse>()
-                    Log.i(TAG, "requestNumber response: $rcsNumber")
+                    Log.i(tag, "requestNumber response: $rcsNumber")
 
 
                     appStateRepository.updateRuntimeFlags(requestNumberState = RequestNumberState.OTP_1)
                     appStateRepository.updateRuntimeFlags(requestNumberState = RequestNumberState.OTP_1)
 
 
@@ -501,7 +511,7 @@ class TaskRunner(
                     shellRun(CMD_MESSAGING_APP)
                     shellRun(CMD_MESSAGING_APP)
 
 
                     if (rcsNumber.expiryTime.isBefore(LocalDateTime.now())) {
                     if (rcsNumber.expiryTime.isBefore(LocalDateTime.now())) {
-                        Log.e(TAG, "RCS number expired, retrying...")
+                        Log.e(tag, "RCS number expired, retrying...")
                         continue
                         continue
                     }
                     }
                     var sendOtpTimeout = ChronoUnit.SECONDS.between(
                     var sendOtpTimeout = ChronoUnit.SECONDS.between(
@@ -509,7 +519,7 @@ class TaskRunner(
                         rcsNumber.expiryTime
                         rcsNumber.expiryTime
                     ).seconds
                     ).seconds
                     if (sendOtpTimeout < 60.seconds) {
                     if (sendOtpTimeout < 60.seconds) {
-                        Log.e(TAG, "OTP timeout too short, retrying...")
+                        Log.e(tag, "OTP timeout too short, retrying...")
                         continue
                         continue
                     }
                     }
                     if (sendOtpTimeout > 2.minutes) {
                     if (sendOtpTimeout > 2.minutes) {
@@ -524,10 +534,10 @@ class TaskRunner(
                             needRest = true
                             needRest = true
                         }
                         }
                         if (RcsConfigureState.REPLAY_REQUEST == googleMessageStateRepository.rcsConfigureState.value) {
                         if (RcsConfigureState.REPLAY_REQUEST == googleMessageStateRepository.rcsConfigureState.value) {
-                            Log.e(TAG, "REPLAY_REQUEST detected, may reset after 3 retry ($retry)")
+                            Log.e(tag, "REPLAY_REQUEST detected, may reset after 3 retry ($retry)")
                             retry++
                             retry++
                         }
                         }
-                        Log.e(TAG, "RCS not entered waiting for OTP state, retrying...")
+                        Log.e(tag, "RCS not entered waiting for OTP state, retrying...")
                         continue
                         continue
                     }
                     }
 
 
@@ -542,12 +552,12 @@ class TaskRunner(
                                 )
                                 )
                             )
                             )
                         } catch (e: Exception) {
                         } catch (e: Exception) {
-                            Log.e(TAG, "Send OtpState Error: ${e.message}", e)
+                            Log.e(tag, "Send OtpState Error: ${e.message}", e)
                         }
                         }
                     }
                     }
 
 
                     if (rcsNumber.expiryTime.isBefore(LocalDateTime.now())) {
                     if (rcsNumber.expiryTime.isBefore(LocalDateTime.now())) {
-                        Log.e(TAG, "RCS number expired, retrying...")
+                        Log.e(tag, "RCS number expired, retrying...")
                         continue
                         continue
                     }
                     }
 
 
@@ -558,19 +568,19 @@ class TaskRunner(
                                 rcsNumber =
                                 rcsNumber =
                                     ktorClient(appPreferences.value.server).get(RcsNumberApi.Id(id = rcsNumber.id))
                                     ktorClient(appPreferences.value.server).get(RcsNumberApi.Id(id = rcsNumber.id))
                                         .body<RcsNumberResponse>()
                                         .body<RcsNumberResponse>()
-                                Log.i(TAG, "wait for otp response: $rcsNumber")
+                                Log.i(tag, "wait for otp response: $rcsNumber")
                                 if (rcsNumber.status == RcsNumberResponse.STATUS_SUCCESS || rcsNumber.status == RcsNumberResponse.STATUS_EXPIRED) {
                                 if (rcsNumber.status == RcsNumberResponse.STATUS_SUCCESS || rcsNumber.status == RcsNumberResponse.STATUS_EXPIRED) {
                                     break
                                     break
                                 }
                                 }
                             } catch (exception: Exception) {
                             } catch (exception: Exception) {
-                                Log.e(TAG, "wait for otp Error: ${exception.stackTrace}")
+                                Log.e(tag, "wait for otp Error: ${exception.stackTrace}")
                             }
                             }
                             delay(2.seconds)
                             delay(2.seconds)
                         }
                         }
                     }
                     }
 
 
                     if (rcsNumber.status != RcsNumberResponse.STATUS_SUCCESS) {
                     if (rcsNumber.status != RcsNumberResponse.STATUS_SUCCESS) {
-                        Log.e(TAG, "OTP not received, retrying...")
+                        Log.e(tag, "OTP not received, retrying...")
                         continue
                         continue
                     }
                     }
 
 
@@ -581,7 +591,7 @@ class TaskRunner(
                         appStateRepository.updateRuntimeFlags(requestNumberState = RequestNumberState.CONFIG)
                         appStateRepository.updateRuntimeFlags(requestNumberState = RequestNumberState.CONFIG)
 
 
                         val otp = match.groupValues[1]
                         val otp = match.groupValues[1]
-                        Log.i(TAG, "OTP: $otp")
+                        Log.i(tag, "OTP: $otp")
                         val sender = "3538"
                         val sender = "3538"
                         val msg = "Your Messenger verification code is G-$otp"
                         val msg = "Your Messenger verification code is G-$otp"
 
 
@@ -608,14 +618,14 @@ class TaskRunner(
                                     }
                                     }
 
 
                                     else -> {
                                     else -> {
-                                        Log.e(TAG, "verifyOtp fail, retrying...")
+                                        Log.e(tag, "verifyOtp fail, retrying...")
                                     }
                                     }
                                 }
                                 }
                             }
                             }
                             false
                             false
                         }
                         }
                         if (!configured) {
                         if (!configured) {
-                            Log.e(TAG, "RCS not configured, retrying...")
+                            Log.e(tag, "RCS not configured, retrying...")
                             continue
                             continue
                         } else {
                         } else {
                             launch {
                             launch {
@@ -630,7 +640,7 @@ class TaskRunner(
                                     )
                                     )
                                 } catch (e: Exception) {
                                 } catch (e: Exception) {
                                     Log.e(
                                     Log.e(
-                                        TAG,
+                                        tag,
                                         "Send ConfiguredState Error: ${e.message}",
                                         "Send ConfiguredState Error: ${e.message}",
                                         e
                                         e
                                     )
                                     )
@@ -641,7 +651,7 @@ class TaskRunner(
                         }
                         }
                     }
                     }
                 } catch (e: Exception) {
                 } catch (e: Exception) {
-                    Log.e(TAG, "requestNumberError: ${e.message}", e)
+                    Log.e(tag, "requestNumberError: ${e.message}", e)
                 }
                 }
             }
             }
         }
         }
@@ -653,12 +663,12 @@ class TaskRunner(
             )
             )
             appStateRepository.resetSuccessNum()
             appStateRepository.resetSuccessNum()
             appStateRepository.resetExecutedNum()
             appStateRepository.resetExecutedNum()
-            Log.i(TAG, "requestNumber success")
+            Log.i(tag, "requestNumber success")
             delay(5000)
             delay(5000)
             shellRun(PACKAGE_MESSAGING.kill(), "sleep 1", CMD_MESSAGING_APP)
             shellRun(PACKAGE_MESSAGING.kill(), "sleep 1", CMD_MESSAGING_APP)
             delay(2000)
             delay(2000)
         } else {
         } else {
-            Log.e(TAG, "requestNumber failed")
+            Log.e(tag, "requestNumber failed")
             appStateRepository.updateSend(false)
             appStateRepository.updateSend(false)
         }
         }
         appStateRepository.updateRuntimeFlags(
         appStateRepository.updateRuntimeFlags(
@@ -670,7 +680,7 @@ class TaskRunner(
 
 
     private suspend fun checkRcsConnectivity(): Boolean = run checkRcsConnection@{
     private suspend fun checkRcsConnectivity(): Boolean = run checkRcsConnection@{
         repeat(3) {
         repeat(3) {
-            Log.i(TAG, "Checking RCS status...")
+            Log.i(tag, "Checking RCS status...")
             shellRun(
             shellRun(
                 CMD_CONVERSATION_LIST_ACTIVITY,
                 CMD_CONVERSATION_LIST_ACTIVITY,
                 CMD_RCS_SETTINGS_ACTIVITY,
                 CMD_RCS_SETTINGS_ACTIVITY,
@@ -679,11 +689,11 @@ class TaskRunner(
             val res = TraverseResult()
             val res = TraverseResult()
             screenInspector.traverseNode(res)
             screenInspector.traverseNode(res)
             if (res.rcsConnectionStatus == RcsConnectionStatus.CONNECTED) {
             if (res.rcsConnectionStatus == RcsConnectionStatus.CONNECTED) {
-                Log.i(TAG, "RCS is connected")
+                Log.i(tag, "RCS is connected")
                 shellRun(CMD_BACK)
                 shellRun(CMD_BACK)
                 return@checkRcsConnection true
                 return@checkRcsConnection true
             } else {
             } else {
-                Log.i(TAG, "RCS not connected, retrying...")
+                Log.i(tag, "RCS not connected, retrying...")
             }
             }
             shellRun(CMD_BACK, "sleep ${it * 2}")
             shellRun(CMD_BACK, "sleep ${it * 2}")
         }
         }
@@ -706,19 +716,19 @@ class TaskRunner(
                     )
                     )
                 )
                 )
                     .body<SysConfigResponse>()
                     .body<SysConfigResponse>()
-                Log.i(TAG, "sysConfig response: $config")
+                Log.i(tag, "sysConfig response: $config")
                 checkRcsAvailabilityNumbers.addAll(
                 checkRcsAvailabilityNumbers.addAll(
                     config.value.split(",").map { it.trim() })
                     config.value.split(",").map { it.trim() })
             } catch (exception: Exception) {
             } catch (exception: Exception) {
                 Log.e(
                 Log.e(
-                    TAG,
+                    tag,
                     "sysConfig Error: ${exception.message}",
                     "sysConfig Error: ${exception.message}",
                     exception
                     exception
                 )
                 )
             }
             }
 
 
             if (checkRcsAvailabilityNumbers.isEmpty()) {
             if (checkRcsAvailabilityNumbers.isEmpty()) {
-                Log.e(TAG, "checkRcsAvailabilityNumbers is empty")
+                Log.e(tag, "checkRcsAvailabilityNumbers is empty")
                 return@checkAvailability true
                 return@checkAvailability true
             }
             }
 
 
@@ -732,7 +742,7 @@ class TaskRunner(
                             return@withTimeoutOrNull true
                             return@withTimeoutOrNull true
                         } else {
                         } else {
                             Log.i(
                             Log.i(
-                                TAG,
+                                tag,
                                 "checkRcsAvailability: RCS not detected"
                                 "checkRcsAvailability: RCS not detected"
                             )
                             )
                         }
                         }
@@ -740,7 +750,7 @@ class TaskRunner(
                     }
                     }
                 }
                 }
                 if (s == true) {
                 if (s == true) {
-                    Log.i(TAG, "checkRcsAvailability: $it success")
+                    Log.i(tag, "checkRcsAvailability: $it success")
                     delay(1000)
                     delay(1000)
                     return@checkAvailability true
                     return@checkAvailability true
                 }
                 }
@@ -782,7 +792,7 @@ class TaskRunner(
                         }
                         }
                     }
                     }
                 }
                 }
-            Log.i(TAG, "Apk file saved to ${file.path}")
+            Log.i(tag, "Apk file saved to ${file.path}")
             shellRun("pm install -d -r ${file.path}")
             shellRun("pm install -d -r ${file.path}")
             onSuccess()
             onSuccess()
             file.delete()
             file.delete()
@@ -801,7 +811,7 @@ class TaskRunner(
             val (out, err) = shellRun(*installApkAction.data.script.split("\n").toTypedArray())
             val (out, err) = shellRun(*installApkAction.data.script.split("\n").toTypedArray())
             onSuccess(out, err)
             onSuccess(out, err)
         } catch (e: Exception) {
         } catch (e: Exception) {
-            Log.e("Modifier", "Failed to install apk", e)
+            Log.e("Modifier", "Failed to run script", e)
             onError(e)
             onError(e)
         }
         }
     }
     }

+ 3 - 9
app/src/main/java/com/example/modifier/ui/backup/BackupFragment.kt

@@ -6,21 +6,15 @@ import android.util.Log
 import android.view.LayoutInflater
 import android.view.LayoutInflater
 import android.view.View
 import android.view.View
 import android.view.ViewGroup
 import android.view.ViewGroup
-import androidx.appcompat.content.res.AppCompatResources
 import androidx.core.view.ViewCompat
 import androidx.core.view.ViewCompat
 import androidx.core.view.WindowInsetsCompat
 import androidx.core.view.WindowInsetsCompat
 import androidx.core.widget.doAfterTextChanged
 import androidx.core.widget.doAfterTextChanged
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.Fragment
-import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.asFlow
 import androidx.lifecycle.asFlow
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.lifecycleScope
-import androidx.lifecycle.liveData
-import androidx.lifecycle.repeatOnLifecycle
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.LinearLayoutManager
-import com.example.modifier.R
-import com.example.modifier.TAG
-import com.example.modifier.Utils
+import com.example.modifier.baseTag
 import com.example.modifier.adapter.BackupAdapter
 import com.example.modifier.adapter.BackupAdapter
 import com.example.modifier.data.AppDatabase
 import com.example.modifier.data.AppDatabase
 import com.example.modifier.data.BackupItem
 import com.example.modifier.data.BackupItem
@@ -32,11 +26,11 @@ import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.FlowPreview
 import kotlinx.coroutines.FlowPreview
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.debounce
 import kotlinx.coroutines.flow.debounce
-import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 import kotlinx.coroutines.withContext
 
 
 class BackupFragment : Fragment() {
 class BackupFragment : Fragment() {
+    private val tag = "$baseTag/BackupFragment"
     private lateinit var binding: FragmentBackupBinding
     private lateinit var binding: FragmentBackupBinding
     private val list = mutableListOf<BackupItem>()
     private val list = mutableListOf<BackupItem>()
     private lateinit var adapter: BackupAdapter
     private lateinit var adapter: BackupAdapter
@@ -111,7 +105,7 @@ class BackupFragment : Fragment() {
         }
         }
         lifecycleScope.launch {
         lifecycleScope.launch {
             searchText.asFlow().debounce(500).collect {
             searchText.asFlow().debounce(500).collect {
-                Log.i("$TAG/BackupFragment", "searchText: $it")
+                Log.i(tag, "searchText: $it")
                 refresh(it)
                 refresh(it)
             }
             }
         }
         }

+ 5 - 11
app/src/main/java/com/example/modifier/ui/login/LoginViewModel.kt

@@ -1,9 +1,6 @@
 package com.example.modifier.ui.login
 package com.example.modifier.ui.login
 
 
 import android.content.Context
 import android.content.Context
-import android.content.DialogInterface
-import android.content.Intent
-import android.provider.Settings
 import android.util.Log
 import android.util.Log
 import androidx.datastore.core.DataStore
 import androidx.datastore.core.DataStore
 import androidx.datastore.preferences.core.Preferences
 import androidx.datastore.preferences.core.Preferences
@@ -12,12 +9,11 @@ import androidx.datastore.preferences.core.stringPreferencesKey
 import androidx.datastore.preferences.preferencesDataStore
 import androidx.datastore.preferences.preferencesDataStore
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModel
-import com.example.modifier.Utils
+import com.example.modifier.baseTag
 import com.example.modifier.http.request.LoginRequest
 import com.example.modifier.http.request.LoginRequest
 import com.example.modifier.http.response.ErrorResponse
 import com.example.modifier.http.response.ErrorResponse
 import com.example.modifier.http.response.LoginResponse
 import com.example.modifier.http.response.LoginResponse
 import com.example.modifier.model.ServerConfig
 import com.example.modifier.model.ServerConfig
-import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import dagger.hilt.android.lifecycle.HiltViewModel
 import dagger.hilt.android.lifecycle.HiltViewModel
 import dagger.hilt.android.qualifiers.ApplicationContext
 import dagger.hilt.android.qualifiers.ApplicationContext
 import io.ktor.client.HttpClient
 import io.ktor.client.HttpClient
@@ -31,13 +27,10 @@ import io.ktor.http.ContentType
 import io.ktor.http.HttpStatusCode
 import io.ktor.http.HttpStatusCode
 import io.ktor.http.contentType
 import io.ktor.http.contentType
 import io.ktor.serialization.kotlinx.json.json
 import io.ktor.serialization.kotlinx.json.json
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.withContext
 import kotlinx.serialization.json.Json
 import kotlinx.serialization.json.Json
 import javax.inject.Inject
 import javax.inject.Inject
 
 
@@ -54,6 +47,7 @@ class LoginViewModel @Inject constructor() : ViewModel() {
         val TOKEN = stringPreferencesKey("token")
         val TOKEN = stringPreferencesKey("token")
     }
     }
 
 
+    private val tag = "$baseTag/LoginViewModel"
     private val _uiState = MutableStateFlow<LoginUiState>(LoginUiState.Normal)
     private val _uiState = MutableStateFlow<LoginUiState>(LoginUiState.Normal)
     val uiState: StateFlow<LoginUiState> = _uiState.asStateFlow()
     val uiState: StateFlow<LoginUiState> = _uiState.asStateFlow()
     val serverConfig = MutableLiveData<ServerConfig>()
     val serverConfig = MutableLiveData<ServerConfig>()
@@ -87,7 +81,7 @@ class LoginViewModel @Inject constructor() : ViewModel() {
     }
     }
 
 
     suspend fun login() {
     suspend fun login() {
-        Log.d(com.example.modifier.TAG, "login")
+        Log.d(tag, "login")
         _uiState.value = LoginUiState.Loading
         _uiState.value = LoginUiState.Loading
         val client = HttpClient(OkHttp) {
         val client = HttpClient(OkHttp) {
             defaultRequest {
             defaultRequest {
@@ -109,12 +103,12 @@ class LoginViewModel @Inject constructor() : ViewModel() {
         when (response.status) {
         when (response.status) {
             HttpStatusCode.OK -> {
             HttpStatusCode.OK -> {
                 val loginResponse = response.body<LoginResponse>()
                 val loginResponse = response.body<LoginResponse>()
-                Log.i(com.example.modifier.TAG, "response: $loginResponse")
+                Log.i(tag, "response: $loginResponse")
             }
             }
 
 
             else -> {
             else -> {
                 val errorResponse = response.body<ErrorResponse>()
                 val errorResponse = response.body<ErrorResponse>()
-                Log.e(com.example.modifier.TAG, "error: $errorResponse")
+                Log.e(tag, "error: $errorResponse")
             }
             }
         }
         }
     }
     }

+ 7 - 9
app/src/main/java/com/example/modifier/ui/settings/SettingsFragment.kt

@@ -22,7 +22,7 @@ import androidx.core.content.ContextCompat
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.Fragment
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.lifecycleScope
 import com.example.modifier.R
 import com.example.modifier.R
-import com.example.modifier.TAG
+import com.example.modifier.baseTag
 import com.example.modifier.Utils
 import com.example.modifier.Utils
 import com.example.modifier.constants.servers
 import com.example.modifier.constants.servers
 import com.example.modifier.data.AppPreferences
 import com.example.modifier.data.AppPreferences
@@ -34,7 +34,6 @@ 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.model.SpoofedSimInfo
 import com.example.modifier.model.SpoofedSimInfo
 import com.example.modifier.repo.SpoofedSimInfoRepository
 import com.example.modifier.repo.SpoofedSimInfoRepository
-import com.example.modifier.service.ModifierService.Companion.instance
 import com.example.modifier.utils.genICCID
 import com.example.modifier.utils.genICCID
 import com.example.modifier.utils.genIMEI
 import com.example.modifier.utils.genIMEI
 import com.example.modifier.utils.uniqueId
 import com.example.modifier.utils.uniqueId
@@ -58,10 +57,9 @@ import org.apache.commons.validator.routines.UrlValidator
 import java.util.Objects
 import java.util.Objects
 import java.util.Optional
 import java.util.Optional
 
 
-
 @SuppressLint("SetTextI18n", "MissingPermission", "HardwareIds", "NewApi")
 @SuppressLint("SetTextI18n", "MissingPermission", "HardwareIds", "NewApi")
 class SettingsFragment : Fragment() {
 class SettingsFragment : Fragment() {
-
+    private val tag = "$baseTag/SettingsFragment"
     private lateinit var binding: FragmentSettingsBinding
     private lateinit var binding: FragmentSettingsBinding
     private lateinit var requestPermissionLauncher: ActivityResultLauncher<String>
     private lateinit var requestPermissionLauncher: ActivityResultLauncher<String>
     private val appPreferencesRepository: AppPreferencesRepository by lazy {
     private val appPreferencesRepository: AppPreferencesRepository by lazy {
@@ -92,7 +90,7 @@ class SettingsFragment : Fragment() {
                     // decision.
                     // decision.
                 }
                 }
             }
             }
-        Log.i(TAG, "SettingsFragment.onCreate")
+        Log.i(tag, "SettingsFragment.onCreate")
 
 
 
 
     }
     }
@@ -101,7 +99,7 @@ class SettingsFragment : Fragment() {
         inflater: LayoutInflater, container: ViewGroup?,
         inflater: LayoutInflater, container: ViewGroup?,
         savedInstanceState: Bundle?
         savedInstanceState: Bundle?
     ): View {
     ): View {
-        Log.i(TAG, "SettingsFragment.onCreateView")
+        Log.i(tag, "SettingsFragment.onCreateView")
         if (!this::binding.isInitialized) {
         if (!this::binding.isInitialized) {
             binding = FragmentSettingsBinding.inflate(inflater, container, false)
             binding = FragmentSettingsBinding.inflate(inflater, container, false)
             binding.tlIccid.setEndIconOnClickListener {
             binding.tlIccid.setEndIconOnClickListener {
@@ -191,7 +189,7 @@ class SettingsFragment : Fragment() {
                             }
                             }
                             return@req
                             return@req
                         }
                         }
-                        Log.i(com.example.modifier.TAG, "response: ${response.bodyAsText()}")
+                        Log.i(tag, "response: ${response.bodyAsText()}")
                         val res = response.body<RcsNumberResponse>()
                         val res = response.body<RcsNumberResponse>()
                         val number = res.number
                         val number = res.number
                         val mcc = res.mcc
                         val mcc = res.mcc
@@ -318,7 +316,7 @@ class SettingsFragment : Fragment() {
             spoofedSimInfo = spoofedSimInfoRepository.stateFlow()
             spoofedSimInfo = spoofedSimInfoRepository.stateFlow()
             launch {
             launch {
                 appPreferencesRepository.stateFlow().collect {
                 appPreferencesRepository.stateFlow().collect {
-                    Log.i(TAG, "appPreferencesRepository.collect")
+                    Log.i(tag, "appPreferencesRepository.collect")
                     binding.etServer.setText(it.server)
                     binding.etServer.setText(it.server)
                     binding.etDeviceLabel.setText(it.name)
                     binding.etDeviceLabel.setText(it.name)
                     binding.switchClean.isChecked = it.preventClean
                     binding.switchClean.isChecked = it.preventClean
@@ -328,7 +326,7 @@ class SettingsFragment : Fragment() {
             }
             }
             launch {
             launch {
                 spoofedSimInfo.collect {
                 spoofedSimInfo.collect {
-                    Log.i(TAG, "spoofedSimInfo.collect")
+                    Log.i(tag, "spoofedSimInfo.collect")
                     binding.etNumber.setText(it.number)
                     binding.etNumber.setText(it.number)
                     binding.etMcc.setText(it.mcc)
                     binding.etMcc.setText(it.mcc)
                     binding.etMnc.setText(it.mnc)
                     binding.etMnc.setText(it.mnc)

+ 7 - 5
app/src/main/java/com/example/modifier/ui/utils/UtilsFragment.kt

@@ -12,6 +12,7 @@ import androidx.lifecycle.lifecycleScope
 import com.example.modifier.Frida
 import com.example.modifier.Frida
 import com.example.modifier.R
 import com.example.modifier.R
 import com.example.modifier.Utils
 import com.example.modifier.Utils
+import com.example.modifier.baseTag
 import com.example.modifier.constants.CMD_BACK_APP
 import com.example.modifier.constants.CMD_BACK_APP
 import com.example.modifier.constants.PACKAGE_GMS
 import com.example.modifier.constants.PACKAGE_GMS
 import com.example.modifier.constants.PACKAGE_GSF
 import com.example.modifier.constants.PACKAGE_GSF
@@ -52,6 +53,7 @@ import kotlinx.coroutines.withContext
 import java.io.File
 import java.io.File
 
 
 class UtilsFragment : Fragment() {
 class UtilsFragment : Fragment() {
+    private val tag = "$baseTag/UtilsFragment"
     private lateinit var binding: FragmentUtilsBinding
     private lateinit var binding: FragmentUtilsBinding
     private val appPreferencesRepository: AppPreferencesRepository by lazy {
     private val appPreferencesRepository: AppPreferencesRepository by lazy {
         AppPreferencesRepository(requireContext())
         AppPreferencesRepository(requireContext())
@@ -235,7 +237,7 @@ class UtilsFragment : Fragment() {
                         .body<SysConfigResponse>()
                         .body<SysConfigResponse>()
                     installApk(config.value)
                     installApk(config.value)
                 } catch (e: Exception) {
                 } catch (e: Exception) {
-                    Log.e("Modifier", "Failed to get message apk", e)
+                    Log.e(tag, "Failed to get message apk", e)
                 }
                 }
             }
             }
         }
         }
@@ -252,7 +254,7 @@ class UtilsFragment : Fragment() {
                         .body<SysConfigResponse>()
                         .body<SysConfigResponse>()
                     installApk(config.value)
                     installApk(config.value)
                 } catch (e: Exception) {
                 } catch (e: Exception) {
-                    Log.e("Modifier", "Failed to get message apk", e)
+                    Log.e(tag, "Failed to get message apk", e)
                 }
                 }
             }
             }
         }
         }
@@ -269,7 +271,7 @@ class UtilsFragment : Fragment() {
                         .body<SysConfigResponse>()
                         .body<SysConfigResponse>()
                     installApk(config.value)
                     installApk(config.value)
                 } catch (e: Exception) {
                 } catch (e: Exception) {
-                    Log.e("Modifier", "Failed to get gms apk", e)
+                    Log.e(tag, "Failed to get gms apk", e)
                 }
                 }
             }
             }
         }
         }
@@ -381,10 +383,10 @@ class UtilsFragment : Fragment() {
                             }
                             }
                         }
                         }
                     }
                     }
-                Log.i("Modifier", "A file saved to ${file.path}")
+                Log.i(tag, "A file saved to ${file.path}")
                 shellRun("pm install -d -r ${file.path}")
                 shellRun("pm install -d -r ${file.path}")
             } catch (e: Exception) {
             } catch (e: Exception) {
-                Log.e("Modifier", "Failed to download apk", e)
+                Log.e(tag, "Failed to download apk", e)
 
 
             }
             }
 
 

+ 1 - 1
app/src/main/java/com/example/modifier/utils/RcsHackTool.kt

@@ -55,7 +55,7 @@ fun createSmsIntent(context: Context, number: String, body: String?): Intent {
     for (i in 0 until simCount) {
     for (i in 0 until simCount) {
         val subInfo = subscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(i)
         val subInfo = subscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(i)
         if (subInfo != null) {
         if (subInfo != null) {
-            Log.d(com.example.modifier.TAG, "subId: " + subInfo.subscriptionId)
+            Log.d(com.example.modifier.baseTag, "subId: " + subInfo.subscriptionId)
             subId = subInfo.subscriptionId
             subId = subInfo.subscriptionId
             slot = subInfo.simSlotIndex
             slot = subInfo.simSlotIndex
             break
             break

+ 5 - 3
app/src/main/java/com/example/modifier/utils/Root.kt

@@ -1,15 +1,17 @@
 package com.example.modifier.utils
 package com.example.modifier.utils
 
 
 import android.util.Log
 import android.util.Log
+import com.example.modifier.baseTag
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 import kotlinx.coroutines.withContext
 
 
+const val shellTag = "$baseTag/shell"
 suspend fun shellRun(vararg commands: String): Pair<String, String> {
 suspend fun shellRun(vararg commands: String): Pair<String, String> {
     var output = ""
     var output = ""
     var error = ""
     var error = ""
-    Log.i(com.example.modifier.TAG, "shellRun: \t${commands.joinToString("\n\t\t\t")}")
+    Log.i(shellTag, "shellRun: \t${commands.joinToString("\n\t\t\t")}")
     withContext(Dispatchers.IO) {
     withContext(Dispatchers.IO) {
         val p = ProcessBuilder("su", "-M").start()
         val p = ProcessBuilder("su", "-M").start()
         p.outputStream.bufferedWriter().use { writer ->
         p.outputStream.bufferedWriter().use { writer ->
@@ -24,7 +26,7 @@ suspend fun shellRun(vararg commands: String): Pair<String, String> {
                 p.inputStream.bufferedReader().useLines { line ->
                 p.inputStream.bufferedReader().useLines { line ->
                     line.forEach {
                     line.forEach {
                         output += it + "\n"
                         output += it + "\n"
-                        Log.i(com.example.modifier.TAG, "shellRunOut: $it")
+                        Log.i(shellTag, "shellRunOut: $it")
                     }
                     }
                 }
                 }
             }
             }
@@ -32,7 +34,7 @@ suspend fun shellRun(vararg commands: String): Pair<String, String> {
                 p.errorStream.bufferedReader().useLines { line ->
                 p.errorStream.bufferedReader().useLines { line ->
                     line.forEach {
                     line.forEach {
                         error += it + "\n"
                         error += it + "\n"
-                        Log.e(com.example.modifier.TAG, "shellRunErr: $it")
+                        Log.e(shellTag, "shellRunErr: $it")
                     }
                     }
                 }
                 }
             }
             }

+ 10 - 8
app/src/main/java/com/example/modifier/utils/System.kt

@@ -17,6 +17,7 @@ import androidx.core.content.ContextCompat
 import com.example.modifier.BuildConfig
 import com.example.modifier.BuildConfig
 import com.example.modifier.MainActivity
 import com.example.modifier.MainActivity
 import com.example.modifier.Utils
 import com.example.modifier.Utils
+import com.example.modifier.baseTag
 import com.example.modifier.http.ktorClient
 import com.example.modifier.http.ktorClient
 import com.example.modifier.service.ModifierService
 import com.example.modifier.service.ModifierService
 import io.ktor.client.request.head
 import io.ktor.client.request.head
@@ -31,6 +32,7 @@ import java.util.Objects
 import java.util.UUID
 import java.util.UUID
 import kotlin.system.exitProcess
 import kotlin.system.exitProcess
 
 
+const val systemTag = "$baseTag/System"
 val uniqueId: String
 val uniqueId: String
     @SuppressLint("HardwareIds")
     @SuppressLint("HardwareIds")
     get() {
     get() {
@@ -98,7 +100,7 @@ fun isAccessibilityEnabled(): Boolean {
 
 
     for (enabledService in enabledServices) {
     for (enabledService in enabledServices) {
         Log.i(
         Log.i(
-            com.example.modifier.TAG,
+            systemTag,
             "Enabled service: " + enabledService.resolveInfo.serviceInfo.packageName + "/" + enabledService.resolveInfo.serviceInfo.name
             "Enabled service: " + enabledService.resolveInfo.serviceInfo.packageName + "/" + enabledService.resolveInfo.serviceInfo.name
         )
         )
         val enabledServiceInfo = enabledService.resolveInfo.serviceInfo
         val enabledServiceInfo = enabledService.resolveInfo.serviceInfo
@@ -168,7 +170,7 @@ suspend fun syncTime() {
         // convert to Asia/Shanghai
         // convert to Asia/Shanghai
         val dateInZone = date.withZoneSameInstant(ZoneId.of("Asia/Shanghai"))
         val dateInZone = date.withZoneSameInstant(ZoneId.of("Asia/Shanghai"))
         Log.i(
         Log.i(
-            com.example.modifier.TAG,
+            systemTag,
             "CurrentTime from Baidu: ${dateInZone.format(DateTimeFormatter.ISO_DATE_TIME)}"
             "CurrentTime from Baidu: ${dateInZone.format(DateTimeFormatter.ISO_DATE_TIME)}"
         )
         )
         shellRun(
         shellRun(
@@ -179,7 +181,7 @@ suspend fun syncTime() {
             "date \"${dateInZone.format(DateTimeFormatter.ofPattern("MMddHHmmyyyy.ss"))}\""
             "date \"${dateInZone.format(DateTimeFormatter.ofPattern("MMddHHmmyyyy.ss"))}\""
         )
         )
     } catch (e: Exception) {
     } catch (e: Exception) {
-        Log.e(com.example.modifier.TAG, "Error SyncTime", e)
+        Log.e(systemTag, "Error SyncTime", e)
     }
     }
 }
 }
 
 
@@ -206,28 +208,28 @@ suspend fun killPhoneProcess(force: Boolean = false): Boolean {
             repeat(3) {
             repeat(3) {
                 val pid = shellRun("pidof com.android.phone").first.trim()
                 val pid = shellRun("pidof com.android.phone").first.trim()
                 if (!Regex("[0-9]+").matches(pid)) {
                 if (!Regex("[0-9]+").matches(pid)) {
-                    Log.e(com.example.modifier.TAG, "killPhoneProcess: pid not found")
+                    Log.e(systemTag, "killPhoneProcess: pid not found")
                     return true
                     return true
                 }
                 }
-                Log.i(com.example.modifier.TAG, "killPhoneProcess: pid=$pid")
+                Log.i(systemTag, "killPhoneProcess: pid=$pid")
                 shellRun("kill -9 $pid")
                 shellRun("kill -9 $pid")
                 delay(1000)
                 delay(1000)
 
 
                 val pidNew = shellRun("pidof com.android.phone").first.trim()
                 val pidNew = shellRun("pidof com.android.phone").first.trim()
                 if (pidNew == pid) {
                 if (pidNew == pid) {
                     Log.e(
                     Log.e(
-                        com.example.modifier.TAG,
+                        systemTag,
                         "killPhoneProcess: failed to kill phone process"
                         "killPhoneProcess: failed to kill phone process"
                     )
                     )
                 } else {
                 } else {
-                    Log.i(com.example.modifier.TAG, "killPhoneProcess: success, new pid: $pidNew")
+                    Log.i(systemTag, "killPhoneProcess: success, new pid: $pidNew")
                     shellRun("kill -9 $pid", "setprop phonekilled yes")
                     shellRun("kill -9 $pid", "setprop phonekilled yes")
                     return true
                     return true
                 }
                 }
             }
             }
         }
         }
     } catch (e: Exception) {
     } catch (e: Exception) {
-        Log.e(com.example.modifier.TAG, "Error Kill Phone", e)
+        Log.e(systemTag, "Error Kill Phone", e)
     }
     }
     return false
     return false
 }
 }

+ 31 - 10
app/src/main/res/layout/floating_window.xml

@@ -47,15 +47,35 @@
                     app:layout_constraintStart_toStartOf="@id/sw_connect"
                     app:layout_constraintStart_toStartOf="@id/sw_connect"
                     app:layout_constraintTop_toBottomOf="@id/sw_connect" />
                     app:layout_constraintTop_toBottomOf="@id/sw_connect" />
 
 
-                <TextView
-                    android:id="@+id/tv_version"
+                <LinearLayout
+                    android:id="@+id/ll_version"
                     android:layout_width="wrap_content"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_height="wrap_content"
-                    android:padding="4dp"
-                    android:text="v1000"
-                    android:textSize="12sp"
+                    android:gravity="center"
+                    android:orientation="vertical"
+                    android:paddingEnd="4dp"
                     app:layout_constraintRight_toRightOf="parent"
                     app:layout_constraintRight_toRightOf="parent"
-                    app:layout_constraintTop_toTopOf="parent" />
+                    app:layout_constraintTop_toTopOf="parent">
+
+                    <TextView
+                        android:id="@+id/tv_version"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:padding="0dp"
+                        android:text="v1000"
+                        android:textAlignment="center"
+                        android:textSize="12sp" />
+
+                    <TextView
+                        android:id="@+id/tv_country"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="-4dp"
+                        android:padding="0dp"
+                        android:text="us"
+                        android:textAlignment="center"
+                        android:textSize="12sp" />
+                </LinearLayout>
 
 
 
 
                 <ScrollView
                 <ScrollView
@@ -64,7 +84,7 @@
                     android:layout_height="0dp"
                     android:layout_height="0dp"
                     android:clipToPadding="false"
                     android:clipToPadding="false"
                     android:paddingBottom="20dp"
                     android:paddingBottom="20dp"
-                    app:layout_constraintBottom_toTopOf="@id/btns"
+                    app:layout_constraintBottom_toTopOf="@id/tv_status"
                     app:layout_constraintTop_toBottomOf="@id/sw_send">
                     app:layout_constraintTop_toBottomOf="@id/sw_send">
 
 
                     <TextView
                     <TextView
@@ -80,11 +100,12 @@
                     android:id="@+id/tv_status"
                     android:id="@+id/tv_status"
                     android:layout_width="match_parent"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:layout_height="wrap_content"
-                    android:text="Waiting for Configuration"
+                    android:text="waiting for configuration"
                     android:textAlignment="center"
                     android:textAlignment="center"
                     android:textColor="?colorPrimary"
                     android:textColor="?colorPrimary"
-                    android:textSize="12sp"
-                    app:layout_constraintBottom_toTopOf="@id/btns" />
+                    android:textSize="11sp"
+                    app:layout_constraintBottom_toTopOf="@id/btns"
+                    app:layout_constraintTop_toBottomOf="@id/scroll" />
 
 
                 <GridLayout
                 <GridLayout
                     android:id="@+id/btns"
                     android:id="@+id/btns"