x1ongzhu 1 سال پیش
والد
کامیت
aaf98e1bd2

+ 131 - 0
app/schemas/com.example.modifier.data.AppDatabase/3.json

@@ -0,0 +1,131 @@
+{
+  "formatVersion": 1,
+  "database": {
+    "version": 3,
+    "identityHash": "6dd4629cfca24e8a796915386c507fa2",
+    "entities": [
+      {
+        "tableName": "BackupItem",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `createdAt` INTEGER NOT NULL, `number` TEXT NOT NULL, `country` TEXT NOT NULL, `code` TEXT NOT NULL, `mcc` TEXT NOT NULL, `mnc` TEXT NOT NULL, `imei` TEXT NOT NULL, `imsi` TEXT NOT NULL, `iccid` TEXT NOT NULL, `sendCount` INTEGER NOT NULL, `path` TEXT NOT NULL, `lastUse` INTEGER NOT NULL, `type` TEXT NOT NULL, `fresh` INTEGER NOT NULL DEFAULT 0, `carrierId` TEXT NOT NULL, `carrierName` TEXT NOT NULL)",
+        "fields": [
+          {
+            "fieldPath": "id",
+            "columnName": "id",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "createdAt",
+            "columnName": "createdAt",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "number",
+            "columnName": "number",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "country",
+            "columnName": "country",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "code",
+            "columnName": "code",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "mcc",
+            "columnName": "mcc",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "mnc",
+            "columnName": "mnc",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "imei",
+            "columnName": "imei",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "imsi",
+            "columnName": "imsi",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "iccid",
+            "columnName": "iccid",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "sendCount",
+            "columnName": "sendCount",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "path",
+            "columnName": "path",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "lastUse",
+            "columnName": "lastUse",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "type",
+            "columnName": "type",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "fresh",
+            "columnName": "fresh",
+            "affinity": "INTEGER",
+            "notNull": true,
+            "defaultValue": "0"
+          },
+          {
+            "fieldPath": "carrierId",
+            "columnName": "carrierId",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "carrierName",
+            "columnName": "carrierName",
+            "affinity": "TEXT",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": true,
+          "columnNames": [
+            "id"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": []
+      }
+    ],
+    "views": [],
+    "setupQueries": [
+      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '6dd4629cfca24e8a796915386c507fa2')"
+    ]
+  }
+}

+ 30 - 6
app/src/main/java/com/example/modifier/Global.kt

@@ -44,7 +44,19 @@ object Global {
     var name: String? = ""
 
     @JvmField
-    var telephonyConfig: TelephonyConfig = TelephonyConfig("", "", "", "", "", "", "", "")
+    var telephonyConfig: TelephonyConfig = TelephonyConfig(
+        number = "",
+        mcc = "",
+        mnc = "",
+        iccid = "",
+        imsi = "",
+        imei = "",
+        country = "",
+        areaCode = "",
+        available = false,
+        carrierId = "1",
+        carrierName = "T-Mobile"
+    )
 
     private const val TAG = "Modifier"
 
@@ -112,6 +124,8 @@ object Global {
         Global.telephonyConfig.imei = telephonyConfig.imei
         Global.telephonyConfig.imsi = telephonyConfig.imsi
         Global.telephonyConfig.available = telephonyConfig.available
+        Global.telephonyConfig.carrierId = telephonyConfig.carrierId
+        Global.telephonyConfig.carrierName = telephonyConfig.carrierName
 
         try {
             if (suspend == true) {
@@ -127,6 +141,8 @@ object Global {
                 "setprop persist.spoof.iccid ${telephonyConfig.iccid}",
                 "setprop persist.spoof.imei ${telephonyConfig.imei}",
                 "setprop persist.spoof.imsi ${telephonyConfig.imsi}",
+                "setprop persist.spoof.carrier.id ${telephonyConfig.carrierId}",
+                "setprop persist.spoof.carrier.name ${telephonyConfig.carrierName}",
             )
             if (suspend == true) {
                 unsuspend(gms = true, sms = true)
@@ -169,7 +185,9 @@ object Global {
                             Utils.generateIMEI(),
                             "us",
                             "1",
-                            available = false
+                            available = false,
+                            carrierId = "1779",
+                            carrierName = "Cricket Wireless"
                         )
                     )
                 }
@@ -193,7 +211,9 @@ object Global {
                             Utils.generateIMEI(),
                             "us",
                             "1",
-                            available = false
+                            available = false,
+                            "1",
+                            "T-Mobile"
                         )
                     )
                 }
@@ -673,7 +693,9 @@ object Global {
             sendCount = sendCount,
             lastUse = Date().time,
             type = type,
-            fresh = fresh
+            fresh = fresh,
+            carrierId = telephonyConfig.carrierId,
+            carrierName = telephonyConfig.carrierName
         )
 
         backupItemDao.findBackupForNumber(telephonyConfig.country, telephonyConfig.number)?.let {
@@ -700,7 +722,9 @@ object Global {
                 iccid = backup.iccid,
                 imei = backup.imei,
                 imsi = backup.imsi,
-                available = true
+                available = true,
+                carrierId = backup.carrierId,
+                carrierName = backup.carrierName
             ), false
         )
         val packages = mutableListOf(
@@ -808,7 +832,7 @@ object Global {
     }
 
     @JvmStatic
-    fun restartModifier(){
+    fun restartModifier() {
         val context = Utils.getContext()
         val mStartActivity: Intent = Intent(context, MainActivity::class.java)
         val mPendingIntentId = 123456

+ 21 - 12
app/src/main/java/com/example/modifier/data/AppDatabase.kt

@@ -9,21 +9,29 @@ import androidx.room.TypeConverters
 import androidx.room.migration.Migration
 import androidx.sqlite.db.SupportSQLiteDatabase
 
-//val MIGRATION_1_2 = object : Migration(1, 2) {
-//    override fun migrate(db: SupportSQLiteDatabase) {
-//        db.execSQL(
-//            "ALTER TABLE BackupItem ADD COLUMN fresh INTEGER NOT NULL DEFAULT 0"
-//        )
-//    }
-//}
+val MIGRATION_1_2 = object : Migration(1, 2) {
+    override fun migrate(db: SupportSQLiteDatabase) {
+        db.execSQL(
+            "ALTER TABLE BackupItem ADD COLUMN fresh INTEGER NOT NULL DEFAULT 0"
+        )
+    }
+}
+
+val MIGRATION_2_3 = object : Migration(2, 3) {
+    override fun migrate(db: SupportSQLiteDatabase) {
+        db.execSQL(
+            "ALTER TABLE BackupItem ADD COLUMN carrierId TEXT NOT NULL DEFAULT ''"
+        )
+        db.execSQL(
+            "ALTER TABLE BackupItem ADD COLUMN carrierName TEXT NOT NULL DEFAULT ''"
+        )
+    }
+}
 
 @Database(
     entities = [BackupItem::class],
-    version = 2,
+    version = 3,
     exportSchema = true,
-    autoMigrations = [
-        AutoMigration(from = 1, to = 2)
-    ]
 )
 @TypeConverters(Converters::class)
 abstract class AppDatabase : RoomDatabase() {
@@ -38,7 +46,8 @@ abstract class AppDatabase : RoomDatabase() {
             // if the Instance is not null, return it, otherwise create a new database instance.
             return Instance ?: synchronized(this) {
                 Room.databaseBuilder(context, AppDatabase::class.java, "app")
-//                    .addMigrations(MIGRATION_1_2)
+                    .addMigrations(MIGRATION_1_2)
+                    .addMigrations(MIGRATION_2_3)
                     .build()
                     .also { Instance = it }
             }

+ 3 - 1
app/src/main/java/com/example/modifier/data/BackupItem.kt

@@ -25,5 +25,7 @@ data class BackupItem(
     val lastUse: Long,
     val type: String,
     @ColumnInfo(defaultValue = "0")
-    var fresh: Boolean = false
+    var fresh: Boolean = false,
+    val carrierId: String,
+    val carrierName: String,
 )

+ 2 - 0
app/src/main/java/com/example/modifier/http/response/RcsNumberResponse.kt

@@ -22,6 +22,8 @@ data class RcsNumberResponse(
     val status: String,
     val extra: JsonElement,
     val deviceId: String?,
+    val carrierId: String,
+    val carrierName: String,
 ) {
     companion object {
         const val STATUS_PENDING = "pending"

+ 3 - 1
app/src/main/java/com/example/modifier/model/TelephonyConfig.kt

@@ -12,5 +12,7 @@ data class TelephonyConfig(
     var imei: String,
     var country: String,
     var areaCode: String,
-    var available: Boolean? = null
+    var available: Boolean,
+    var carrierId: String,
+    var carrierName: String,
 )

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

@@ -1202,7 +1202,10 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
                             ),
                             Utils.generateIMEI(),
                             rcsNumber.country,
-                            rcsNumber.areaCode
+                            rcsNumber.areaCode,
+                            false,
+                            rcsNumber.carrierId,
+                            rcsNumber.carrierName,
                         )
                     )
 

+ 77 - 82
app/src/main/java/com/example/modifier/ui/settings/SettingsFragment.kt

@@ -24,7 +24,6 @@ import androidx.core.content.ContextCompat
 import androidx.fragment.app.Fragment
 import androidx.lifecycle.lifecycleScope
 import com.example.modifier.Global
-import com.example.modifier.Global.load
 import com.example.modifier.Global.save
 import com.example.modifier.Global.saveServer
 import com.example.modifier.Global.servers
@@ -93,6 +92,13 @@ class SettingsFragment : Fragment() {
             }
     }
 
+    override fun onResume() {
+        super.onResume()
+        lifecycleScope.launch {
+            loadConfigs()
+        }
+    }
+
     override fun onCreateView(
         inflater: LayoutInflater, container: ViewGroup?,
         savedInstanceState: Bundle?
@@ -167,56 +173,63 @@ class SettingsFragment : Fragment() {
                 Utils.makeLoadingButton(context, binding.btnRequest)
                 binding.btnRequest.isEnabled = false
 
-                val response: HttpResponse
-                try {
-                    response = KtorClient.put(
-                        RcsNumberApi()
-                    ) {
-                        contentType(ContentType.Application.Json)
-                        setBody(
-                            RcsNumberRequest(
-                                deviceId = Utils.getUniqueID()
+                withContext(Dispatchers.IO) req@{
+                    val response: HttpResponse
+                    try {
+                        response = KtorClient.put(
+                            RcsNumberApi()
+                        ) {
+                            contentType(ContentType.Application.Json)
+                            setBody(
+                                RcsNumberRequest(
+                                    deviceId = Utils.getUniqueID()
+                                )
                             )
-                        )
-                    }
-                } catch (e: Exception) {
-                    MaterialAlertDialogBuilder(requireContext())
-                        .setTitle("Error")
-                        .setMessage(e.message)
-                        .setPositiveButton("OK") { dialog: DialogInterface, which: Int ->
-                            dialog.dismiss()
                         }
-                        .show()
-                    binding.btnRequest.isEnabled = true
-                    binding.btnRequest.text = "Request"
-                    binding.btnRequest.icon = null
-                    return@launch
-                }
-                Log.i(TAG, "response: ${response.bodyAsText()}")
-                var res = response.body<RcsNumberResponse>()
-                val id = res.id
-                val expiryTime = res.expiryTime
-                val number = res.number
-                val mcc = res.mcc
-                val mnc = res.mnc
-                val country = res.country
-                val areaCode = res.areaCode
-                val iccid = Global.genICCID(mnc, areaCode)
-                val imsi =
-                    mcc + mnc + RandomStringUtils.randomNumeric(15 - mcc.length - mnc.length)
-                val imei = Utils.generateIMEI()
-                save(TelephonyConfig(number, mcc, mnc, iccid, imsi, imei, country, areaCode))
-
-                val telephonyConfig = Global.telephonyConfig
-                binding.etNumber.setText(telephonyConfig.number)
-                binding.etMcc.setText(telephonyConfig.mcc)
-                binding.etMnc.setText(telephonyConfig.mnc)
-                binding.etIccid.setText(telephonyConfig.iccid)
-                binding.etImsi.setText(telephonyConfig.imsi)
-                binding.etImei.setText(telephonyConfig.imei)
-                binding.etCountry.setText(telephonyConfig.country)
-                binding.etAreaCode.setText(telephonyConfig.areaCode)
+                    } catch (e: Exception) {
+                        withContext(Dispatchers.Main) {
+                            MaterialAlertDialogBuilder(requireContext())
+                                .setTitle("Error")
+                                .setMessage(e.message)
+                                .setPositiveButton("OK") { dialog: DialogInterface, which: Int ->
+                                    dialog.dismiss()
+                                }
+                                .show()
+                            binding.btnRequest.isEnabled = true
+                            binding.btnRequest.text = "Request"
+                            binding.btnRequest.icon = null
+                        }
+                        return@req
+                    }
+                    Log.i(TAG, "response: ${response.bodyAsText()}")
+                    val res = response.body<RcsNumberResponse>()
+                    val number = res.number
+                    val mcc = res.mcc
+                    val mnc = res.mnc
+                    val country = res.country
+                    val areaCode = res.areaCode
+                    val iccid = Global.genICCID(mnc, areaCode)
+                    val imsi =
+                        mcc + mnc + RandomStringUtils.randomNumeric(15 - mcc.length - mnc.length)
+                    val imei = Utils.generateIMEI()
+                    save(
+                        TelephonyConfig(
+                            number,
+                            mcc,
+                            mnc,
+                            iccid,
+                            imsi,
+                            imei,
+                            country,
+                            areaCode,
+                            false,
+                            res.carrierId,
+                            res.carrierName
+                        )
+                    )
 
+                    loadConfigs()
+                }
                 binding.btnRequest.icon = null
                 binding.btnRequest.isEnabled = true
                 binding.btnRequest.text = "Request"
@@ -308,10 +321,17 @@ class SettingsFragment : Fragment() {
             }
 
         }
+        lifecycleScope.launch {
+            loadConfigs()
+        }
 
-        executor.execute {
-            load()
-            handler.post {
+        return binding.root
+    }
+
+    private suspend fun loadConfigs() {
+        withContext(Dispatchers.IO) {
+            Global.load()
+            withContext(Dispatchers.Main) {
                 binding.etServer.setText(Global.serverUrl)
                 binding.etServer.setSimpleItems(servers.toTypedArray<String>())
                 binding.etDeviceLabel.setText(Global.name)
@@ -324,38 +344,10 @@ class SettingsFragment : Fragment() {
                 binding.etImei.setText(telephonyConfig.imei)
                 binding.etCountry.setText(telephonyConfig.country)
                 binding.etAreaCode.setText(telephonyConfig.areaCode)
+                binding.etCarrierId.setText(telephonyConfig.carrierId)
+                binding.etCarrierName.setText(telephonyConfig.carrierName)
             }
         }
-
-        CoroutineScope(Dispatchers.IO).launch {
-            try {
-                val response = KtorClient.post(
-                    ChannelApi()
-                ) {
-                    contentType(ContentType.Application.Json)
-                }
-                Log.i(TAG, "response: ${response.bodyAsText()}")
-                val res = response.body<GetChannelListResponse>()
-                channels = res.items
-                withContext(Dispatchers.Main) {
-                    if (isAdded) {
-                        binding.etChannel.threshold = 1000
-                        binding.etChannel.setSimpleItems(res.items.map { "${it.country}-${it.mcc}-${it.mnc}-${it.operator}" }
-                            .toTypedArray())
-                        binding.etChannel.setOnItemClickListener { parent, view, position, id ->
-                            val channel = channels[position]
-                            binding.etMcc.setText(channel.mcc)
-                            binding.etMnc.setText(channel.mnc)
-                            binding.etCountry.setText(channel.country)
-                        }
-                    }
-                }
-            } catch (e: Exception) {
-                e.printStackTrace()
-            }
-        }
-
-        return binding.root
     }
 
     private fun onSave() {
@@ -371,7 +363,10 @@ class SettingsFragment : Fragment() {
                     binding.etImsi.text.toString(),
                     binding.etImei.text.toString(),
                     binding.etCountry.text.toString(),
-                    binding.etAreaCode.text.toString()
+                    binding.etAreaCode.text.toString(),
+                    false,
+                    binding.etCarrierId.text.toString(),
+                    binding.etCarrierName.text.toString()
                 )
             )
             handler.post {

+ 0 - 59
app/src/main/java/com/example/modifier/ui/settings/SettingsViewModel.kt

@@ -1,59 +0,0 @@
-package com.example.modifier.ui.settings
-
-import android.util.Log
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.liveData
-import androidx.lifecycle.viewModelScope
-import com.example.modifier.Global
-import com.example.modifier.Utils
-import com.example.modifier.http.KtorClient
-import com.example.modifier.http.response.RcsNumberResponse
-import com.example.modifier.model.TelephonyConfig
-import io.ktor.client.call.body
-import io.ktor.client.request.put
-import io.ktor.http.ContentType
-import io.ktor.http.contentType
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import org.apache.commons.lang3.RandomStringUtils
-
-class SettingsViewModel : ViewModel() {
-    private val TAG = "SettingsViewModel"
-
-    suspend fun requestNumber() {
-        val response = KtorClient.put("/api/rcs-number") {
-            contentType(ContentType.Application.Json)
-        }
-        val rcsRes = response.body<RcsNumberResponse>()
-        Log.i(TAG, "response: $rcsRes")
-
-        Global.save(
-            TelephonyConfig(
-                rcsRes.number,
-                rcsRes.mcc,
-                rcsRes.mnc,
-                Global.genICCID(rcsRes.mnc, rcsRes.areaCode),
-                rcsRes.mcc + rcsRes.mnc + RandomStringUtils.randomNumeric(
-                    15 - rcsRes.mcc.length - rcsRes.mnc.length
-                ),
-                Utils.generateIMEI(),
-                rcsRes.country,
-                rcsRes.areaCode
-            )
-        )
-
-        liveData(Dispatchers.IO) {
-            viewModelScope.launch {
-                Runtime.getRuntime().exec("su -c \"logcat -c\"")
-                Runtime.getRuntime().exec("su -c logcat")
-                    .inputStream
-                    .bufferedReader()
-                    .useLines { lines ->
-                        lines.forEach { line -> emit(line) }
-                    }
-            }
-        }
-
-
-    }
-}

+ 40 - 16
app/src/main/res/layout/fragment_settings.xml

@@ -100,24 +100,9 @@
                             android:textSize="14sp"
                             android:textStyle="bold" />
 
-                        <com.google.android.material.textfield.TextInputLayout
-                            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
-                            android:layout_width="match_parent"
-                            android:layout_height="wrap_content"
-                            android:hint="Channel">
-
-                            <com.google.android.material.textfield.MaterialAutoCompleteTextView
-                                android:id="@+id/et_channel"
-                                android:layout_width="match_parent"
-                                android:layout_height="wrap_content"
-                                android:inputType="none" />
-
-                        </com.google.android.material.textfield.TextInputLayout>
-
                         <LinearLayout
                             android:layout_width="match_parent"
                             android:layout_height="wrap_content"
-                            android:layout_marginTop="16dp"
                             android:orientation="horizontal">
 
                             <com.google.android.material.textfield.TextInputLayout
@@ -163,10 +148,18 @@
                                     android:lines="1" />
                             </com.google.android.material.textfield.TextInputLayout>
 
+                        </LinearLayout>
+
+                        <LinearLayout
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_marginTop="16dp"
+                            android:orientation="horizontal">
+
                             <com.google.android.material.textfield.TextInputLayout
                                 android:layout_width="0dp"
                                 android:layout_height="wrap_content"
-                                android:layout_marginLeft="16dp"
+
                                 android:layout_weight="1"
                                 android:hint="Code">
 
@@ -177,6 +170,37 @@
                                     android:inputType="number"
                                     android:lines="1" />
                             </com.google.android.material.textfield.TextInputLayout>
+
+                            <com.google.android.material.textfield.TextInputLayout
+                                android:layout_width="0dp"
+                                android:layout_height="wrap_content"
+                                android:layout_marginLeft="16dp"
+                                android:layout_weight="1"
+                                android:hint="CID">
+
+                                <com.google.android.material.textfield.TextInputEditText
+                                    android:id="@+id/et_carrier_id"
+                                    android:layout_width="match_parent"
+                                    android:layout_height="wrap_content"
+                                    android:inputType="number"
+                                    android:lines="1" />
+                            </com.google.android.material.textfield.TextInputLayout>
+
+                            <com.google.android.material.textfield.TextInputLayout
+                                android:layout_width="0dp"
+                                android:layout_height="wrap_content"
+                                android:layout_marginLeft="16dp"
+                                android:layout_weight="1"
+                                android:hint="CNAME">
+
+                                <com.google.android.material.textfield.TextInputEditText
+                                    android:id="@+id/et_carrier_name"
+                                    android:layout_width="match_parent"
+                                    android:layout_height="wrap_content"
+                                    android:lines="1" />
+                            </com.google.android.material.textfield.TextInputLayout>
+
+
                         </LinearLayout>
 
                         <com.google.android.material.textfield.TextInputLayout