|
@@ -5,6 +5,7 @@ import android.accessibilityservice.AccessibilityServiceInfo
|
|
|
import android.annotation.SuppressLint
|
|
import android.annotation.SuppressLint
|
|
|
import android.content.Intent
|
|
import android.content.Intent
|
|
|
import android.graphics.PixelFormat
|
|
import android.graphics.PixelFormat
|
|
|
|
|
+import android.graphics.Rect
|
|
|
import android.net.Uri
|
|
import android.net.Uri
|
|
|
import android.os.Build
|
|
import android.os.Build
|
|
|
import android.util.DisplayMetrics
|
|
import android.util.DisplayMetrics
|
|
@@ -23,6 +24,7 @@ import androidx.lifecycle.liveData
|
|
|
import com.example.modifier.BuildConfig
|
|
import com.example.modifier.BuildConfig
|
|
|
import com.example.modifier.Global
|
|
import com.example.modifier.Global
|
|
|
import com.example.modifier.Global.load
|
|
import com.example.modifier.Global.load
|
|
|
|
|
+import com.example.modifier.Global.resetAll
|
|
|
import com.example.modifier.R
|
|
import com.example.modifier.R
|
|
|
import com.example.modifier.TraverseResult
|
|
import com.example.modifier.TraverseResult
|
|
|
import com.example.modifier.Utils
|
|
import com.example.modifier.Utils
|
|
@@ -98,6 +100,18 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
.putInt("sendCount", value).apply()
|
|
.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()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
|
|
|
val logcat = liveData(Dispatchers.IO) {
|
|
val logcat = liveData(Dispatchers.IO) {
|
|
|
try {
|
|
try {
|
|
@@ -124,6 +138,8 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
rcsConfigureState.postValue(RcsConfigureState.VERIFYING_OTP)
|
|
rcsConfigureState.postValue(RcsConfigureState.VERIFYING_OTP)
|
|
|
} else if (line.contains("destState=ConfiguredState")) {
|
|
} else if (line.contains("destState=ConfiguredState")) {
|
|
|
rcsConfigureState.postValue(RcsConfigureState.CONFIGURED)
|
|
rcsConfigureState.postValue(RcsConfigureState.CONFIGURED)
|
|
|
|
|
+ } else if (line.contains("destState=WaitingForRcsDefaultOnState")) {
|
|
|
|
|
+ rcsConfigureState.postValue(RcsConfigureState.WAITING_FOR_DEFAULT_ON)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -317,7 +333,10 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
counter++
|
|
counter++
|
|
|
- Log.i(TAG, "sendCount: $sendCount, Counter: $counter, cleanCount: $cleanCount")
|
|
|
|
|
|
|
+ Log.i(
|
|
|
|
|
+ TAG,
|
|
|
|
|
+ "sendCount: $sendCount, Counter: $counter, cleanCount: $cleanCount, requestNumberInterval: $requestNumberInterval"
|
|
|
|
|
+ )
|
|
|
if (cleanCount in 1..counter) {
|
|
if (cleanCount in 1..counter) {
|
|
|
counter = 0
|
|
counter = 0
|
|
|
Thread.sleep(2000)
|
|
Thread.sleep(2000)
|
|
@@ -362,6 +381,23 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
result.isRcsCapable = true
|
|
result.isRcsCapable = true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if (text != null && (text.contains("Turn on RCS chats") || text.contains("开启 RCS 聊天功能"))) {
|
|
|
|
|
+ fun findSwitch(node: AccessibilityNodeInfo): Boolean {
|
|
|
|
|
+ if ("com.google.android.apps.messaging:id/switchWidget" == node.viewIdResourceName) {
|
|
|
|
|
+ result.rcsSwitch = node
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
+ for (i in 0 until node.childCount) {
|
|
|
|
|
+ val child = node.getChild(i)
|
|
|
|
|
+ if (findSwitch(child)) {
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ findSwitch(node.parent.parent)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (node.childCount != 0) {
|
|
if (node.childCount != 0) {
|
|
|
for (i in 0 until node.childCount) {
|
|
for (i in 0 until node.childCount) {
|
|
|
traverseNode(node.getChild(i), result)
|
|
traverseNode(node.getChild(i), result)
|
|
@@ -442,7 +478,6 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
false
|
|
false
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
binding.swConnect.isChecked = true
|
|
binding.swConnect.isChecked = true
|
|
|
binding.swConnect.setOnCheckedChangeListener { buttonView: CompoundButton?, isChecked: Boolean ->
|
|
binding.swConnect.setOnCheckedChangeListener { buttonView: CompoundButton?, isChecked: Boolean ->
|
|
|
if (isChecked) {
|
|
if (isChecked) {
|
|
@@ -472,33 +507,24 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
}
|
|
}
|
|
|
rcsConfigureState.observeForever {
|
|
rcsConfigureState.observeForever {
|
|
|
when (it) {
|
|
when (it) {
|
|
|
- RcsConfigureState.NOT_CONFIGURED -> {
|
|
|
|
|
- binding.btnReq.isEnabled = false
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- RcsConfigureState.WAITING_FOR_OTP -> {
|
|
|
|
|
- binding.btnReq.isEnabled = false
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- RcsConfigureState.VERIFYING_OTP -> {
|
|
|
|
|
- binding.btnReq.isEnabled = false
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
RcsConfigureState.CONFIGURED -> {
|
|
RcsConfigureState.CONFIGURED -> {
|
|
|
binding.btnReq.isEnabled = true
|
|
binding.btnReq.isEnabled = true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- RcsConfigureState.CONFIGURING -> {
|
|
|
|
|
- binding.btnReq.isEnabled = false
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ else -> {}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
binding.btnReq.setOnClickListener {
|
|
binding.btnReq.setOnClickListener {
|
|
|
|
|
+ requestNumberCount = 6
|
|
|
CoroutineScope(Dispatchers.IO).launch {
|
|
CoroutineScope(Dispatchers.IO).launch {
|
|
|
requestNumber()
|
|
requestNumber()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ binding.btnInspect.setOnClickListener {
|
|
|
|
|
+ CoroutineScope(Dispatchers.IO).launch {
|
|
|
|
|
+ traverseNode(getRootInActiveWindow(), TraverseResult())
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private fun updateDevice(key: String, value: Any) {
|
|
private fun updateDevice(key: String, value: Any) {
|
|
@@ -519,7 +545,60 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
suspend fun requestNumber() {
|
|
suspend fun requestNumber() {
|
|
|
|
|
+ withContext(Dispatchers.Main) {
|
|
|
|
|
+ binding.btnReq.isEnabled = false
|
|
|
|
|
+ }
|
|
|
while (true) {
|
|
while (true) {
|
|
|
|
|
+ withContext(Dispatchers.Main) {
|
|
|
|
|
+ binding.tvLog.text = "Waiting for logs..."
|
|
|
|
|
+ }
|
|
|
|
|
+ requestNumberCount++
|
|
|
|
|
+ if (requestNumberCount > 5) {
|
|
|
|
|
+ requestNumberCount = 0
|
|
|
|
|
+
|
|
|
|
|
+ while (true) {
|
|
|
|
|
+ withContext(Dispatchers.Main) {
|
|
|
|
|
+ binding.tvLog.text = "Waiting for logs..."
|
|
|
|
|
+ }
|
|
|
|
|
+ resetAll()
|
|
|
|
|
+ var resetSuccess = false
|
|
|
|
|
+ val time = System.currentTimeMillis()
|
|
|
|
|
+ while (true) {
|
|
|
|
|
+ if (rcsConfigureState.value == RcsConfigureState.WAITING_FOR_DEFAULT_ON) {
|
|
|
|
|
+ Utils.runAsRoot(
|
|
|
|
|
+ "am start com.google.android.apps.messaging/com.google.android.apps.messaging.ui.appsettings.RcsSettingsActivity",
|
|
|
|
|
+ "sleep 1"
|
|
|
|
|
+ )
|
|
|
|
|
+ val res = TraverseResult()
|
|
|
|
|
+ traverseNode(getRootInActiveWindow(), res)
|
|
|
|
|
+ if (res.rcsSwitch != null) {
|
|
|
|
|
+ val rect = Rect()
|
|
|
|
|
+ res.rcsSwitch.getBoundsInScreen(rect)
|
|
|
|
|
+ Utils.runAsRoot(
|
|
|
|
|
+ "input tap ${rect.centerX()} ${rect.centerY()}",
|
|
|
|
|
+ "sleep 1",
|
|
|
|
|
+ "input keyevent KEYCODE_BACK",
|
|
|
|
|
+ "am start com.google.android.apps.messaging/com.google.android.apps.messaging.ui.appsettings.RcsSettingsActivity",
|
|
|
|
|
+ )
|
|
|
|
|
+ resetSuccess = true
|
|
|
|
|
+ Log.i(TAG, "RCS switch turned on, waiting 60 seconds...")
|
|
|
|
|
+ delay(60000)
|
|
|
|
|
+ }
|
|
|
|
|
+ break
|
|
|
|
|
+ }
|
|
|
|
|
+ if (System.currentTimeMillis() - time > 60000) {
|
|
|
|
|
+ Log.e(TAG, "rcsConfigureState not changed in 60 seconds")
|
|
|
|
|
+ break
|
|
|
|
|
+ } else {
|
|
|
|
|
+ delay(3000)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (resetSuccess) {
|
|
|
|
|
+ break
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
lateinit var rcsRes: RcsNumberResponse
|
|
lateinit var rcsRes: RcsNumberResponse
|
|
|
rcsConfigureState.postValue(RcsConfigureState.NOT_CONFIGURED)
|
|
rcsConfigureState.postValue(RcsConfigureState.NOT_CONFIGURED)
|
|
|
try {
|
|
try {
|
|
@@ -550,8 +629,10 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
|
|
|
delay(1000)
|
|
delay(1000)
|
|
|
Utils.runAsRoot("am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER com.google.android.apps.messaging")
|
|
Utils.runAsRoot("am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER com.google.android.apps.messaging")
|
|
|
delay(1000)
|
|
delay(1000)
|
|
|
- Utils.runAsRoot("am start com.google.android.apps.messaging/com.google.android.apps.messaging.ui.appsettings.SettingsActivity")
|
|
|
|
|
- Utils.runAsRoot("am start com.google.android.apps.messaging/com.google.android.apps.messaging.ui.appsettings.RcsSettingsActivity")
|
|
|
|
|
|
|
+ Utils.runAsRoot(
|
|
|
|
|
+ "am start com.google.android.apps.messaging/com.google.android.apps.messaging.ui.appsettings.SettingsActivity",
|
|
|
|
|
+ "am start com.google.android.apps.messaging/com.google.android.apps.messaging.ui.appsettings.RcsSettingsActivity"
|
|
|
|
|
+ )
|
|
|
delay(1000)
|
|
delay(1000)
|
|
|
|
|
|
|
|
val time = System.currentTimeMillis()
|
|
val time = System.currentTimeMillis()
|