package com.example.modifier.service import android.accessibilityservice.AccessibilityService import android.accessibilityservice.AccessibilityServiceInfo import android.annotation.SuppressLint import android.content.ComponentName import android.content.Context import android.content.Intent import android.graphics.PixelFormat import android.graphics.Rect import android.net.Uri 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.Log import android.view.Gravity import android.view.LayoutInflater import android.view.MotionEvent import android.view.View import android.view.View.OnTouchListener import android.view.WindowManager import android.view.accessibility.AccessibilityEvent import android.view.accessibility.AccessibilityNodeInfo import android.widget.CompoundButton import android.widget.FrameLayout import androidx.core.content.ContextCompat import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.preferencesDataStore import androidx.lifecycle.MediatorLiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Observer import androidx.lifecycle.liveData import com.example.modifier.BuildConfig import com.example.modifier.CMD_BACK import com.example.modifier.CMD_CONVERSATION_LIST_ACTIVITY import com.example.modifier.CMD_KILL_GMS import com.example.modifier.CMD_KILL_MESSAGING_APP import com.example.modifier.CMD_MESSAGING_APP import com.example.modifier.CMD_RCS_SETTINGS_ACTIVITY import com.example.modifier.Global import com.example.modifier.Global.backup import com.example.modifier.Global.load import com.example.modifier.Global.resetAll import com.example.modifier.R import com.example.modifier.TraverseResult import com.example.modifier.Utils import com.example.modifier.data.AppDatabase import com.example.modifier.data.BackupItemDao import com.example.modifier.databinding.FloatingWindowBinding import com.example.modifier.enums.RcsConfigureState import com.example.modifier.enums.RcsConnectionStatus import com.example.modifier.http.KtorClient import com.example.modifier.http.api.DeviceApi import com.example.modifier.http.api.RcsNumberApi import com.example.modifier.http.api.SysConfigApi 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.SocketCallback import com.example.modifier.model.TaskAction import com.example.modifier.model.TaskExecutionResult import com.example.modifier.model.TelephonyConfig import com.example.modifier.serializer.Json import com.example.modifier.ui.shellRun import com.google.android.material.color.DynamicColors import io.ktor.client.call.body import io.ktor.client.plugins.resources.get import io.ktor.client.plugins.resources.put import io.ktor.client.request.setBody import io.ktor.http.ContentType import io.ktor.http.contentType import io.socket.client.IO import io.socket.client.Socket import io.socket.emitter.Emitter import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext import kotlinx.coroutines.withTimeout import kotlinx.coroutines.withTimeoutOrNull import kotlinx.serialization.encodeToString import org.apache.commons.collections4.queue.CircularFifoQueue import org.apache.commons.lang3.RandomStringUtils import org.json.JSONException import org.json.JSONObject import java.time.LocalDateTime import java.time.temporal.ChronoUnit import java.util.Optional import java.util.Timer import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.locks.ReentrantLock import kotlin.coroutines.resume import kotlin.math.max import kotlin.math.min import kotlin.time.Duration import kotlin.time.Duration.Companion.hours import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.seconds val Context.dataStore: DataStore by preferencesDataStore(name = "serverConfig") @SuppressLint("SetTextI18n") class ModifierService : AccessibilityService(), Emitter.Listener { companion object { private const val TAG = "ModifierService1" const val NAME: String = BuildConfig.APPLICATION_ID + ".service.ModifierService" @JvmStatic var instance: ModifierService? = null private set } private val handler = Handler(Looper.getMainLooper()) private val mSocketOpts = IO.Options() private lateinit var mSocket: Socket private lateinit var binding: FloatingWindowBinding val lock = ReentrantLock() private var canSend: Boolean get() { return getSharedPreferences( BuildConfig.APPLICATION_ID, MODE_PRIVATE ).getBoolean("canSend", false) } set(value) { getSharedPreferences(BuildConfig.APPLICATION_ID, MODE_PRIVATE).edit() .putBoolean("canSend", value).apply() reportDeviceStatues() } private var counter = 0 private var cleanCount = 0 private var lastSend = 0L private var rcsInterval = 0L private var requestNumberInterval = 0L private val running = MutableLiveData(false) private val requesting = MutableLiveData(false) private val preparing = MutableLiveData(false) private val checkingConnection = MutableLiveData(false) private var currentTaskId = 0 private var busy = MediatorLiveData().apply { addSource(running) { value = it || requesting.value!! } addSource(requesting) { value = it || running.value!! } addSource(preparing) { value = it || running.value!! } addSource(checkingConnection) { value = it || running.value!! } value = requesting.value!! || running.value!! || preparing.value!! || checkingConnection.value!! } private val rcsConfigureState = MutableLiveData(RcsConfigureState.CONFIGURED) private var sendCount: Int get() { return getSharedPreferences( BuildConfig.APPLICATION_ID, MODE_PRIVATE ).getInt("sendCount", 0) } set(value) { getSharedPreferences(BuildConfig.APPLICATION_ID, MODE_PRIVATE).edit() .putInt("sendCount", value).apply() } private var requestNumberCount: Int get() { return getSharedPreferences( BuildConfig.APPLICATION_ID, MODE_PRIVATE ).getInt("requestNumberCount", 0) } set(value) { getSharedPreferences(BuildConfig.APPLICATION_ID, MODE_PRIVATE).edit() .putInt("requestNumberCount", value).apply() } private val logcat = liveData(Dispatchers.IO) { try { val logs = CircularFifoQueue(128) val p = Runtime.getRuntime().exec("su") p.outputStream.bufferedWriter().use { writer -> writer.write("logcat -c") writer.newLine() writer.flush() writer.write("logcat BugleRcsEngine:D *:S -v time") writer.newLine() writer.flush() } p.inputStream .bufferedReader() .useLines { lines -> lines.forEach { line -> if (line.contains("destState=CheckPreconditionsState")) { rcsConfigureState.postValue(RcsConfigureState.NOT_CONFIGURED) } else if (line.contains("destState=ReadyState")) { rcsConfigureState.postValue(RcsConfigureState.READY) } else if (line.contains("destState=WaitingForOtpState")) { rcsConfigureState.postValue(RcsConfigureState.WAITING_FOR_OTP) } else if (line.contains("destState=VerifyOtpState")) { rcsConfigureState.postValue(RcsConfigureState.VERIFYING_OTP) } else if (line.contains("destState=ConfiguredState")) { rcsConfigureState.postValue(RcsConfigureState.CONFIGURED) } else if (line.contains("destState=WaitingForRcsDefaultOnState")) { rcsConfigureState.postValue(RcsConfigureState.WAITING_FOR_DEFAULT_ON) } else if (line.contains("destState=WaitingForGoogleTosState")) { rcsConfigureState.postValue(RcsConfigureState.WAITING_FOR_TOS) } else if (line.contains("destState=RetryState")) { rcsConfigureState.postValue(RcsConfigureState.RETRY) } else if (line.contains("destState=ReplayRequestState")) { rcsConfigureState.postValue(RcsConfigureState.REPLAY_REQUEST) } Regex("(?