x1ongzhu 1 жил өмнө
parent
commit
0b5b630cbc
27 өөрчлөгдсөн 779 нэмэгдсэн , 858 устгасан
  1. 11 6
      app/build.gradle
  2. 16 22
      app/src/main/AndroidManifest.xml
  3. 9 7
      app/src/main/java/com/example/modifier/Backup.java
  4. 12 11
      app/src/main/java/com/example/modifier/Global.kt
  5. 0 51
      app/src/main/java/com/example/modifier/LoginActivity1.java
  6. 1 0
      app/src/main/java/com/example/modifier/MainActivity.kt
  7. 8 9
      app/src/main/java/com/example/modifier/MyApplication.kt
  8. 3 3
      app/src/main/java/com/example/modifier/fragments/BackupFragment.java
  9. 22 22
      app/src/main/java/com/example/modifier/fragments/SettingsFragment.java
  10. 9 0
      app/src/main/java/com/example/modifier/model/ServerConfig.kt
  11. 3 3
      app/src/main/java/com/example/modifier/model/TelephonyConfig.kt
  12. 47 0
      app/src/main/java/com/example/modifier/repository/ServerConfigRepository.kt
  13. 15 19
      app/src/main/java/com/example/modifier/ui/LoginActivity.kt
  14. 7 0
      app/src/main/java/com/example/modifier/ui/LoginUiState.kt
  15. 32 0
      app/src/main/java/com/example/modifier/ui/LoginViewModel.kt
  16. 0 3
      app/src/main/java/com/example/modifier/ui/settings/SettingsUiState.kt
  17. 0 12
      app/src/main/java/com/example/modifier/ui/settings/SettingsViewModel.kt
  18. 91 99
      app/src/main/res/layout/activity_login.xml
  19. 0 119
      app/src/main/res/layout/activity_login1.xml
  20. 25 22
      app/src/main/res/layout/activity_main.xml
  21. 50 47
      app/src/main/res/layout/floating_window.xml
  22. 29 26
      app/src/main/res/layout/fragment_backup.xml
  23. 178 175
      app/src/main/res/layout/fragment_settings.xml
  24. 127 124
      app/src/main/res/layout/fragment_utils.xml
  25. 80 77
      app/src/main/res/layout/item_backup.xml
  26. 2 1
      build.gradle
  27. 2 0
      gradle/libs.versions.toml

+ 11 - 6
app/build.gradle

@@ -1,6 +1,8 @@
 plugins {
     alias(libs.plugins.androidApplication)
     alias(libs.plugins.jetbrainsKotlinAndroid)
+    id 'kotlin-kapt'
+    id("com.google.dagger.hilt.android")
 }
 
 android {
@@ -9,9 +11,10 @@ android {
     useLibrary 'org.apache.http.legacy'
     buildFeatures {
         buildConfig = true
-        viewBinding true
     }
-
+    dataBinding {
+        enabled = true
+    }
     defaultConfig {
         applicationId "com.example.modifier"
         minSdk 26
@@ -45,12 +48,12 @@ android {
         sourceCompatibility JavaVersion.VERSION_17
         targetCompatibility JavaVersion.VERSION_17
     }
-    viewBinding {
-        enabled = true
-    }
     kotlinOptions {
         jvmTarget = '17'
     }
+    kapt {
+        correctErrorTypes = true
+    }
 }
 
 dependencies {
@@ -66,6 +69,7 @@ dependencies {
     implementation libs.navigation.fragment
     implementation libs.navigation.ui
     implementation libs.annotation
+    implementation(libs.datastore.preferences)
 
     implementation libs.core.ktx
     implementation libs.lifecycle.livedata.ktx
@@ -86,5 +90,6 @@ dependencies {
     implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01"
     implementation "androidx.work:work-runtime:2.9.0"
     implementation 'com.google.android.gms:play-services-code-scanner:16.1.0'
-
+    implementation("com.google.dagger:hilt-android:2.44")
+    kapt("com.google.dagger:hilt-android-compiler:2.44")
 }

+ 16 - 22
app/src/main/AndroidManifest.xml

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools" >
+    xmlns:tools="http://schemas.android.com/tools">
 
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
@@ -10,7 +10,6 @@
         android:name=".MyApplication"
         android:allowBackup="true"
         android:dataExtractionRules="@xml/data_extraction_rules"
-        android:enableOnBackInvokedCallback="true"
         android:fullBackupContent="@xml/backup_rules"
         android:icon="@mipmap/ic_launcher"
         android:label="@string/app_name"
@@ -18,28 +17,31 @@
         android:supportsRtl="true"
         android:theme="@style/AppTheme"
         android:usesCleartextTraffic="true"
-        tools:targetApi="31" >
+        tools:targetApi="31">
         <activity
             android:name=".ui.LoginActivity"
-            android:exported="true" >
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
 
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
         </activity>
+
         <activity
-            android:name=".LoginActivity1"
+            android:name=".MainActivity"
             android:exported="true"
-            android:launchMode="singleInstance" >
-        </activity>
+            android:launchMode="singleInstance"
+            android:windowSoftInputMode="adjustResize">
 
-        <meta-data
-            android:name="com.google.mlkit.vision.DEPENDENCIES"
-            android:value="barcode_ui" />
+        </activity>
 
         <service
             android:name=".ModifierService"
             android:enabled="true"
             android:exported="true"
             android:label="@string/accessibility_service_label"
-            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
+            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
             <meta-data
                 android:name="android.accessibilityservice"
                 android:resource="@xml/accessibility_service_config" />
@@ -49,18 +51,10 @@
             </intent-filter>
         </service>
 
-        <activity
-            android:name=".MainActivity"
-            android:exported="true"
-            android:launchMode="singleInstance"
-            android:windowSoftInputMode="adjustResize" >
-
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
+        <meta-data
+            android:name="com.google.mlkit.vision.DEPENDENCIES"
+            android:value="barcode_ui" />
 
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
     </application>
 
 </manifest>

+ 9 - 7
app/src/main/java/com/example/modifier/Backup.java

@@ -1,27 +1,29 @@
 package com.example.modifier;
 
+import com.example.modifier.model.TelephonyConfig;
+
 import java.util.Date;
 
 public class Backup {
 
-    private Config config;
+    private TelephonyConfig telephonyConfig;
 
     private Date date;
 
     private String path;
 
-    public Backup(Config config, Date date, String path) {
-        this.config = config;
+    public Backup(TelephonyConfig telephonyConfig, Date date, String path) {
+        this.telephonyConfig = telephonyConfig;
         this.date = date;
         this.path = path;
     }
 
-    public Config getConfig() {
-        return config;
+    public TelephonyConfig getConfig() {
+        return telephonyConfig;
     }
 
-    public void setConfig(Config config) {
-        this.config = config;
+    public void setConfig(TelephonyConfig telephonyConfig) {
+        this.telephonyConfig = telephonyConfig;
     }
 
     public Date getDate() {

+ 12 - 11
app/src/main/java/com/example/modifier/Global.kt

@@ -4,6 +4,7 @@ import android.content.Context
 import android.os.Build
 import android.util.Log
 import androidx.core.content.ContextCompat
+import com.example.modifier.model.TelephonyConfig
 import com.google.gson.Gson
 import org.apache.commons.io.FileUtils
 import org.apache.commons.lang3.StringUtils
@@ -18,7 +19,7 @@ object Global {
     var name: String? = ""
 
     @JvmField
-    var config: Config = Config("", "", "", "", "", "", "")
+    var telephonyConfig: TelephonyConfig = TelephonyConfig("", "", "", "", "", "", "")
 
     @JvmStatic
     fun load() {
@@ -31,7 +32,7 @@ object Global {
             if (file.exists()) {
                 val gson = Gson()
                 val json = FileUtils.readFileToString(file, "UTF-8")
-                config = gson.fromJson(json, Config::class.java)
+                telephonyConfig = gson.fromJson(json, TelephonyConfig::class.java)
             }
         } catch (e: Exception) {
             e.printStackTrace()
@@ -66,20 +67,20 @@ object Global {
     }
 
     @JvmStatic
-    fun save(config: Config) {
+    fun save(telephonyConfig: TelephonyConfig) {
         val context = Utils.getContext()
-        Global.config.mcc = config.mcc
-        Global.config.mnc = config.mnc
-        Global.config.number = config.number
-        Global.config.country = config.country
-        Global.config.iccid = config.iccid
-        Global.config.imei = config.imei
-        Global.config.imsi = config.imsi
+        Global.telephonyConfig.mcc = telephonyConfig.mcc
+        Global.telephonyConfig.mnc = telephonyConfig.mnc
+        Global.telephonyConfig.number = telephonyConfig.number
+        Global.telephonyConfig.country = telephonyConfig.country
+        Global.telephonyConfig.iccid = telephonyConfig.iccid
+        Global.telephonyConfig.imei = telephonyConfig.imei
+        Global.telephonyConfig.imsi = telephonyConfig.imsi
 
         try {
             val file = File(ContextCompat.getDataDir(context), "config.json")
             val gson = Gson()
-            val json = gson.toJson(config)
+            val json = gson.toJson(telephonyConfig)
 
             try {
                 val writer = FileWriter(file)

+ 0 - 51
app/src/main/java/com/example/modifier/LoginActivity1.java

@@ -1,51 +0,0 @@
-package com.example.modifier;
-
-import android.os.Bundle;
-import android.view.View;
-
-import androidx.activity.EdgeToEdge;
-import androidx.appcompat.app.AppCompatActivity;
-
-import com.example.modifier.databinding.ActivityLogin1Binding;
-
-import org.apache.commons.lang3.StringUtils;
-
-import java.util.Optional;
-
-public class LoginActivity1 extends AppCompatActivity {
-
-    private ActivityLogin1Binding binding;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        EdgeToEdge.enable(this);
-        binding = ActivityLogin1Binding.inflate(getLayoutInflater());
-        setContentView(binding.getRoot());
-        binding.etServer.setSimpleItems(Global.getServers().toArray(new String[0]));
-        binding.btnLogin.setOnClickListener(v -> {
-            String server = Optional.ofNullable(binding.etServer.getText()).map(Object::toString).orElse("");
-            String name = Optional.ofNullable(binding.etName.getText()).map(Object::toString).orElse("");
-            String username = Optional.ofNullable(binding.etUsername.getText()).map(Object::toString).orElse("");
-            String password = Optional.ofNullable(binding.etPassword.getText()).map(Object::toString).orElse("");
-            if (StringUtils.isBlank(server)) {
-                binding.tlServer.setError("Server is required");
-            }
-            if (StringUtils.isBlank(name)) {
-                binding.tlName.setError("Name is required");
-            }
-            if (StringUtils.isBlank(username)) {
-                binding.tlUsername.setError("Username is required");
-            }
-            if (StringUtils.isBlank(password)) {
-                binding.tlPassword.setError("Password is required");
-            }
-            if (StringUtils.isNotBlank(server) && StringUtils.isNotBlank(name) && StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password)) {
-                Global.serverUrl = server;
-                Global.name = name;
-                Global.load();
-                binding.progressBar.setVisibility(View.VISIBLE);
-            }
-        });
-    }
-}

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

@@ -11,6 +11,7 @@ import androidx.appcompat.app.AlertDialog
 import androidx.appcompat.app.AppCompatActivity
 import androidx.navigation.fragment.NavHostFragment
 import androidx.navigation.ui.NavigationUI.setupWithNavController
+import com.example.modifier.databinding.ActivityLoginBinding
 import com.example.modifier.databinding.ActivityMainBinding
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import kotlinx.coroutines.CoroutineScope

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

@@ -1,13 +1,12 @@
-package com.example.modifier;
+package com.example.modifier
 
-import android.app.Application;
+import android.app.Application
+import dagger.hilt.android.HiltAndroidApp
 
-import com.google.android.material.color.DynamicColors;
-
-public class MyApplication extends Application {
-    @Override
-    public void onCreate() {
-        super.onCreate();
-//        DynamicColors.applyToActivitiesIfAvailable(this);
+@HiltAndroidApp
+class MyApplication : Application() {
+    override fun onCreate() {
+        super.onCreate()
+        //        DynamicColors.applyToActivitiesIfAvailable(this);
     }
 }

+ 3 - 3
app/src/main/java/com/example/modifier/fragments/BackupFragment.java

@@ -15,7 +15,7 @@ import androidx.recyclerview.widget.LinearLayoutManager;
 
 import com.example.modifier.Backup;
 import com.example.modifier.BackupAdapter;
-import com.example.modifier.Config;
+import com.example.modifier.model.TelephonyConfig;
 import com.example.modifier.R;
 import com.example.modifier.Utils;
 import com.example.modifier.databinding.FragmentBackupBinding;
@@ -135,8 +135,8 @@ public class BackupFragment extends Fragment {
                             continue;
                         }
                         try {
-                            Config config = new Gson().fromJson(FileUtils.readFileToString(configFile, "UTF-8"), Config.class);
-                            list.add(new Backup(config, new Date(file.lastModified()), file.getPath()));
+                            TelephonyConfig telephonyConfig = new Gson().fromJson(FileUtils.readFileToString(configFile, "UTF-8"), TelephonyConfig.class);
+                            list.add(new Backup(telephonyConfig, new Date(file.lastModified()), file.getPath()));
                         } catch (IOException e) {
                             throw new RuntimeException(e);
                         }

+ 22 - 22
app/src/main/java/com/example/modifier/fragments/SettingsFragment.java

@@ -20,7 +20,7 @@ import com.android.volley.RequestQueue;
 import com.android.volley.toolbox.JsonObjectRequest;
 import com.android.volley.toolbox.RequestFuture;
 import com.android.volley.toolbox.Volley;
-import com.example.modifier.Config;
+import com.example.modifier.model.TelephonyConfig;
 import com.example.modifier.Global;
 import com.example.modifier.MainActivity;
 import com.example.modifier.ModifierService;
@@ -95,7 +95,7 @@ public class SettingsFragment extends Fragment {
                 Toast.makeText(getContext(), "Server is required", Toast.LENGTH_SHORT).show();
                 return;
             }
-            Global.saveServer(server, binding.etName.getText().toString());
+            Global.saveServer(server, binding.etDeviceLabel.getText().toString());
             binding.etServer.setSimpleItems(Global.getServers().toArray(new String[0]));
 
             ModifierService modifierService = ModifierService.getInstance();
@@ -139,19 +139,19 @@ public class SettingsFragment extends Fragment {
                     String iccid = RandomStringUtils.randomNumeric(20);
                     String imsi = mcc + mnc + RandomStringUtils.randomNumeric(15 - mcc.length() - mnc.length());
                     String imei = Utils.generateIMEI();
-                    Global.save(new Config(number, mcc, mnc, iccid, imsi, imei, country));
+                    Global.save(new TelephonyConfig(number, mcc, mnc, iccid, imsi, imei, country));
 
                     Global.stop(false, true, true);
 
                     handler.post(() -> {
-                        Config config = Global.config;
-                        binding.etNumber.setText(config.getNumber());
-                        binding.etMcc.setText(config.getMcc());
-                        binding.etMnc.setText(config.getMnc());
-                        binding.etIccid.setText(config.getIccid());
-                        binding.etImsi.setText(config.getImsi());
-                        binding.etImei.setText(config.getImei());
-                        binding.etCountry.setText(config.getCountry());
+                        TelephonyConfig telephonyConfig = Global.telephonyConfig;
+                        binding.etNumber.setText(telephonyConfig.getNumber());
+                        binding.etMcc.setText(telephonyConfig.getMcc());
+                        binding.etMnc.setText(telephonyConfig.getMnc());
+                        binding.etIccid.setText(telephonyConfig.getIccid());
+                        binding.etImsi.setText(telephonyConfig.getImsi());
+                        binding.etImei.setText(telephonyConfig.getImei());
+                        binding.etCountry.setText(telephonyConfig.getCountry());
                         binding.btnRequest.setText("Waiting for OTP...");
                     });
 
@@ -244,15 +244,15 @@ public class SettingsFragment extends Fragment {
             handler.post(() -> {
                 binding.etServer.setText(Global.serverUrl);
                 binding.etServer.setSimpleItems(Global.getServers().toArray(new String[0]));
-                binding.etName.setText(Global.name);
-                Config config = Global.config;
-                binding.etNumber.setText(config.getNumber());
-                binding.etMcc.setText(config.getMcc());
-                binding.etMnc.setText(config.getMnc());
-                binding.etIccid.setText(config.getIccid());
-                binding.etImsi.setText(config.getImsi());
-                binding.etImei.setText(config.getImei());
-                binding.etCountry.setText(config.getCountry());
+                binding.etDeviceLabel.setText(Global.name);
+                TelephonyConfig telephonyConfig = Global.telephonyConfig;
+                binding.etNumber.setText(telephonyConfig.getNumber());
+                binding.etMcc.setText(telephonyConfig.getMcc());
+                binding.etMnc.setText(telephonyConfig.getMnc());
+                binding.etIccid.setText(telephonyConfig.getIccid());
+                binding.etImsi.setText(telephonyConfig.getImsi());
+                binding.etImei.setText(telephonyConfig.getImei());
+                binding.etCountry.setText(telephonyConfig.getCountry());
             });
         });
 
@@ -278,7 +278,7 @@ public class SettingsFragment extends Fragment {
 
     private void save() {
         try {
-            Config config = new Config(binding.etNumber.getText().toString(),
+            TelephonyConfig telephonyConfig = new TelephonyConfig(binding.etNumber.getText().toString(),
                     binding.etMcc.getText().toString(),
                     binding.etMnc.getText().toString(),
                     binding.etIccid.getText().toString(),
@@ -287,7 +287,7 @@ public class SettingsFragment extends Fragment {
                     binding.etCountry.getText().toString());
             File file = new File(ContextCompat.getDataDir(getContext()), "config.json");
             Gson gson = new Gson();
-            String json = gson.toJson(config);
+            String json = gson.toJson(telephonyConfig);
 
             try {
                 FileWriter writer = new FileWriter(file);

+ 9 - 0
app/src/main/java/com/example/modifier/model/ServerConfig.kt

@@ -0,0 +1,9 @@
+package com.example.modifier.model
+
+data class ServerConfig(
+    val url: String? = "https://rcs.izouma.com",
+    val deviceLabel: String? = "Android",
+    val username: String? = "",
+    val password: String? = "",
+    val token: String? = ""
+)

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

@@ -1,6 +1,6 @@
-package com.example.modifier
+package com.example.modifier.model
 
-class Config(
+data class TelephonyConfig(
     var number: String,
     var mcc: String,
     var mnc: String,
@@ -8,4 +8,4 @@ class Config(
     var imsi: String,
     var imei: String,
     var country: String
-)
+)

+ 47 - 0
app/src/main/java/com/example/modifier/repository/ServerConfigRepository.kt

@@ -0,0 +1,47 @@
+package com.example.modifier.repository
+
+import android.content.Context
+import androidx.datastore.core.DataStore
+import androidx.datastore.preferences.core.Preferences
+import androidx.datastore.preferences.core.edit
+import androidx.datastore.preferences.core.stringPreferencesKey
+import androidx.datastore.preferences.preferencesDataStore
+import com.example.modifier.model.ServerConfig
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.map
+import javax.inject.Inject
+
+val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "serverConfig")
+
+class ServerConfigRepository @Inject constructor(private val context: Context) {
+
+    companion object {
+        val URL = stringPreferencesKey("url")
+        val USERNAME = stringPreferencesKey("username")
+        val PASSWORD = stringPreferencesKey("password")
+        val DEVICE_LABEL = stringPreferencesKey("device_label")
+        val TOKEN = stringPreferencesKey("token")
+    }
+
+    suspend fun saveServerConfig(
+        serverConfig: ServerConfig
+    ) {
+        context.dataStore.edit {
+            it[URL] = serverConfig.url ?: ""
+            it[USERNAME] = serverConfig.username ?: ""
+            it[PASSWORD] = serverConfig.password ?: ""
+            it[DEVICE_LABEL] = serverConfig.deviceLabel ?: ""
+            it[TOKEN] = serverConfig.token ?: ""
+        }
+    }
+
+    fun getServerConfig() = context.dataStore.data.map {
+        ServerConfig(
+            url = it[URL] ?: "",
+            username = it[USERNAME] ?: "",
+            password = it[PASSWORD] ?: "",
+            deviceLabel = it[DEVICE_LABEL] ?: "",
+            token = it[TOKEN] ?: ""
+        )
+    }
+}

+ 15 - 19
app/src/main/java/com/example/modifier/ui/LoginActivity.kt

@@ -1,43 +1,39 @@
 package com.example.modifier.ui
 
 import android.os.Bundle
-import android.view.View
 import androidx.activity.enableEdgeToEdge
+import androidx.activity.viewModels
 import androidx.appcompat.app.AppCompatActivity
 import androidx.core.view.ViewCompat
 import androidx.core.view.WindowInsetsCompat
+import androidx.databinding.DataBindingUtil
 import com.example.modifier.Global
 import com.example.modifier.R
 import com.example.modifier.databinding.ActivityLoginBinding
+import com.example.modifier.model.ServerConfig
 import org.apache.commons.lang3.StringUtils
-import java.util.Optional
-import java.util.function.Function
 
 class LoginActivity : AppCompatActivity() {
+    private val loginViewModel: LoginViewModel by viewModels()
     private lateinit var binding: ActivityLoginBinding
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         enableEdgeToEdge()
-        binding = ActivityLoginBinding.inflate(layoutInflater)
-        val view = binding.root
-        setContentView(view)
-        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
-            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
-            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
-            insets
-        }
-        binding.etServer.setSimpleItems(Global.servers.toTypedArray())
+        binding = DataBindingUtil.setContentView(this, R.layout.activity_login)
+        binding.loginViewModel = loginViewModel
+        binding.lifecycleOwner = this
 
+        binding.etServer.setSimpleItems(Global.servers.toTypedArray())
         binding.btnLogin.setOnClickListener { v ->
-            val server = binding.etName.text?.toString()
-            val name = binding.etName.text?.toString()
+            val server = binding.etDeviceLabel.text?.toString()
+            val deviceLabel = binding.etDeviceLabel.text?.toString()
             val username = binding.etUsername.text?.toString()
             val password = binding.etPassword.text?.toString()
             if (StringUtils.isBlank(server)) {
                 binding.tlServer.error = "Server is required"
             }
-            if (StringUtils.isBlank(name)) {
-                binding.tlName.error = "Name is required"
+            if (StringUtils.isBlank(deviceLabel)) {
+                binding.tlName.error = "Device label is required"
             }
             if (StringUtils.isBlank(username)) {
                 binding.tlUsername.error = "Username is required"
@@ -46,16 +42,16 @@ class LoginActivity : AppCompatActivity() {
                 binding.tlPassword.error = "Password is required"
             }
             if (StringUtils.isNotBlank(server)
-                && StringUtils.isNotBlank(name)
+                && StringUtils.isNotBlank(deviceLabel)
                 && StringUtils.isNotBlank(username)
                 && StringUtils.isNotBlank(password)
             ) {
                 Global.serverUrl = server
-                Global.name = name
+                Global.name = deviceLabel
                 Global.load()
-                binding.progressBar.visibility = View.VISIBLE
             }
         }
 
+        loginViewModel.serverConfig.postValue(ServerConfig())
     }
 }

+ 7 - 0
app/src/main/java/com/example/modifier/ui/LoginUiState.kt

@@ -0,0 +1,7 @@
+package com.example.modifier.ui
+
+data class LoginUiState(
+    val isLoading: Boolean = false,
+    val errorMessage: String? = null,
+    val isUserLoggedIn: Boolean = false
+)

+ 32 - 0
app/src/main/java/com/example/modifier/ui/LoginViewModel.kt

@@ -0,0 +1,32 @@
+package com.example.modifier.ui
+
+import android.content.Context
+import androidx.datastore.core.DataStore
+import androidx.datastore.dataStore
+import androidx.datastore.preferences.core.Preferences
+import androidx.datastore.preferences.core.intPreferencesKey
+import androidx.datastore.preferences.preferencesDataStore
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import com.example.modifier.model.ServerConfig
+import com.example.modifier.repository.ServerConfigRepository
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import javax.inject.Inject
+
+class LoginViewModel @Inject constructor(private val serverConfigRepository: ServerConfigRepository) : ViewModel() {
+    private val _uiState = MutableStateFlow(LoginUiState())
+    val uiState: StateFlow<LoginUiState> = _uiState.asStateFlow()
+    val serverConfig = MutableLiveData<ServerConfig>()
+
+
+    fun load() {
+        serverConfig.postValue(ServerConfig())
+    }
+
+    fun save() {
+
+    }
+}

+ 0 - 3
app/src/main/java/com/example/modifier/ui/settings/SettingsUiState.kt

@@ -1,3 +0,0 @@
-package com.example.modifier.ui.settings
-
-data class SettingsUiState(val serverUrl: String? = null, val mcc: String? = null)

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

@@ -1,12 +0,0 @@
-package com.example.modifier.ui.settings
-
-import androidx.lifecycle.ViewModel
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
-
-class SettingsViewModel : ViewModel() {
-
-    private val _uiState = MutableStateFlow(SettingsUiState())
-    val uiState: StateFlow<SettingsUiState> = _uiState.asStateFlow()
-}

+ 91 - 99
app/src/main/res/layout/activity_login.xml

@@ -1,119 +1,111 @@
 <?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/main"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".LoginActivity1">
-
-    <com.google.android.material.card.MaterialCardView
-        style="?attr/materialCardViewFilledStyle"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <data>
+
+        <variable
+            name="loginViewModel"
+            type="com.example.modifier.ui.LoginViewModel" />
+    </data>
+
+    <LinearLayout
+        android:id="@+id/main"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_margin="16dp"
-        app:cardBackgroundColor="?attr/colorSurfaceContainer"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent"
-        app:layout_constraintTop_toTopOf="parent">
-
-        <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_height="match_parent"
+        android:background="?attr/colorSecondaryContainer"
+        android:orientation="vertical"
+        android:fitsSystemWindows="true"
+        tools:context=".LoginActivity1">
+
+        <LinearLayout
             android:layout_width="match_parent"
-            android:layout_height="wrap_content">
+            android:layout_height="match_parent"
+            android:orientation="vertical"
+            android:padding="16dp">
 
-            <com.google.android.material.progressindicator.LinearProgressIndicator
-                android:id="@+id/progress_bar"
-                android:layout_width="match_parent"
+            <TextView
+                android:id="@+id/tv_login"
+                android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:indeterminate="true"
-                android:visibility="gone"
-                app:layout_constraintTop_toTopOf="parent" />
-
-            <LinearLayout
+                android:layout_marginBottom="16dp"
+                android:text="Login"
+                android:textColor="?attr/colorPrimary"
+                android:textSize="24sp"
+                android:textStyle="bold" />
+
+            <com.google.android.material.textfield.TextInputLayout
+                android:id="@+id/tl_server"
+                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
                 android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:orientation="vertical"
-                android:padding="16dp">
+                android:layout_height="wrap_content"
+                android:hint="Server"
+                app:errorEnabled="true">
 
-                <TextView
-                    android:id="@+id/tv_login"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginBottom="8dp"
-                    android:text="Login"
-                    android:textColor="?attr/colorPrimary"
-                    android:textSize="16sp"
-                    android:textStyle="bold" />
-
-                <com.google.android.material.textfield.TextInputLayout
-                    android:id="@+id/tl_server"
-                    style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
+                <com.google.android.material.textfield.MaterialAutoCompleteTextView
+                    android:id="@+id/et_server"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:hint="Server"
-                    app:errorEnabled="true">
+                    android:text="@{loginViewModel.serverConfig.url}" />
 
-                    <com.google.android.material.textfield.MaterialAutoCompleteTextView
-                        android:id="@+id/et_server"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content" />
+            </com.google.android.material.textfield.TextInputLayout>
 
-                </com.google.android.material.textfield.TextInputLayout>
+            <com.google.android.material.textfield.TextInputLayout
+                android:id="@+id/tl_username"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:hint="Username"
+                app:endIconDrawable="@drawable/ic_qr_code"
+                app:endIconMode="custom"
+                app:errorEnabled="true">
 
-                <com.google.android.material.textfield.TextInputLayout
-                    android:id="@+id/tl_username"
+                <com.google.android.material.textfield.TextInputEditText
+                    android:id="@+id/et_username"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:hint="Username"
-                    app:endIconDrawable="@drawable/ic_qr_code"
-                    app:endIconMode="custom"
-                    app:errorEnabled="true">
-
-                    <com.google.android.material.textfield.TextInputEditText
-                        android:id="@+id/et_username"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:lines="1" />
-                </com.google.android.material.textfield.TextInputLayout>
-
-                <com.google.android.material.textfield.TextInputLayout
-                    android:id="@+id/tl_password"
+                    android:lines="1"
+                    android:text="@{loginViewModel.serverConfig.username}" />
+            </com.google.android.material.textfield.TextInputLayout>
+
+            <com.google.android.material.textfield.TextInputLayout
+                android:id="@+id/tl_password"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:hint="Password"
+                app:errorEnabled="true">
+
+                <com.google.android.material.textfield.TextInputEditText
+                    android:id="@+id/et_password"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:hint="Password"
-                    app:errorEnabled="true">
-
-                    <com.google.android.material.textfield.TextInputEditText
-                        android:id="@+id/et_password"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:inputType="textPassword"
-                        android:lines="1" />
-                </com.google.android.material.textfield.TextInputLayout>
-
-                <com.google.android.material.textfield.TextInputLayout
-                    android:id="@+id/tl_name"
+                    android:inputType="textPassword"
+                    android:lines="1"
+                    android:text="@{loginViewModel.serverConfig.password}" />
+            </com.google.android.material.textfield.TextInputLayout>
+
+            <com.google.android.material.textfield.TextInputLayout
+                android:id="@+id/tl_name"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:hint="Device Label"
+                app:errorEnabled="true">
+
+                <com.google.android.material.textfield.TextInputEditText
+                    android:id="@+id/et_device_label"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:hint="Device Name"
-                    app:errorEnabled="true">
-
-                    <com.google.android.material.textfield.TextInputEditText
-                        android:id="@+id/et_name"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:lines="1" />
-                </com.google.android.material.textfield.TextInputLayout>
-
-                <com.google.android.material.button.MaterialButton
-                    android:id="@+id/btn_login"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_gravity="center_horizontal"
-                    android:text="Login" />
-            </LinearLayout>
-        </androidx.constraintlayout.widget.ConstraintLayout>
-    </com.google.android.material.card.MaterialCardView>
+                    android:lines="1"
+                    android:text="@{loginViewModel.serverConfig.deviceLabel}" />
+            </com.google.android.material.textfield.TextInputLayout>
+
+            <com.google.android.material.button.MaterialButton
+                android:id="@+id/btn_login"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:text="Login" />
+        </LinearLayout>
 
-</androidx.constraintlayout.widget.ConstraintLayout>
+    </LinearLayout>
+</layout>

+ 0 - 119
app/src/main/res/layout/activity_login1.xml

@@ -1,119 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/main"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".LoginActivity1">
-
-    <com.google.android.material.card.MaterialCardView
-        style="?attr/materialCardViewFilledStyle"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_margin="16dp"
-        app:cardBackgroundColor="?attr/colorSurfaceContainer"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent"
-        app:layout_constraintTop_toTopOf="parent">
-
-        <androidx.constraintlayout.widget.ConstraintLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content">
-
-            <com.google.android.material.progressindicator.LinearProgressIndicator
-                android:id="@+id/progress_bar"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:indeterminate="true"
-                android:visibility="gone"
-                app:layout_constraintTop_toTopOf="parent" />
-
-            <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:orientation="vertical"
-                android:padding="16dp">
-
-                <TextView
-                    android:id="@+id/tv_login"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginBottom="8dp"
-                    android:text="Login"
-                    android:textColor="?attr/colorPrimary"
-                    android:textSize="16sp"
-                    android:textStyle="bold" />
-
-                <com.google.android.material.textfield.TextInputLayout
-                    android:id="@+id/tl_server"
-                    style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:hint="Server"
-                    app:errorEnabled="true">
-
-                    <com.google.android.material.textfield.MaterialAutoCompleteTextView
-                        android:id="@+id/et_server"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content" />
-
-                </com.google.android.material.textfield.TextInputLayout>
-
-                <com.google.android.material.textfield.TextInputLayout
-                    android:id="@+id/tl_username"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:hint="Username"
-                    app:endIconDrawable="@drawable/ic_qr_code"
-                    app:endIconMode="custom"
-                    app:errorEnabled="true">
-
-                    <com.google.android.material.textfield.TextInputEditText
-                        android:id="@+id/et_username"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:lines="1" />
-                </com.google.android.material.textfield.TextInputLayout>
-
-                <com.google.android.material.textfield.TextInputLayout
-                    android:id="@+id/tl_password"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:hint="Password"
-                    app:errorEnabled="true">
-
-                    <com.google.android.material.textfield.TextInputEditText
-                        android:id="@+id/et_password"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:inputType="textPassword"
-                        android:lines="1" />
-                </com.google.android.material.textfield.TextInputLayout>
-
-                <com.google.android.material.textfield.TextInputLayout
-                    android:id="@+id/tl_name"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:hint="Device Name"
-                    app:errorEnabled="true">
-
-                    <com.google.android.material.textfield.TextInputEditText
-                        android:id="@+id/et_name"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:lines="1" />
-                </com.google.android.material.textfield.TextInputLayout>
-
-                <com.google.android.material.button.MaterialButton
-                    android:id="@+id/btn_login"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_gravity="center_horizontal"
-                    android:text="Login" />
-            </LinearLayout>
-        </androidx.constraintlayout.widget.ConstraintLayout>
-    </com.google.android.material.card.MaterialCardView>
-
-</androidx.constraintlayout.widget.ConstraintLayout>

+ 25 - 22
app/src/main/res/layout/activity_main.xml

@@ -1,28 +1,31 @@
 <?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/main"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".MainActivity">
+    xmlns:tools="http://schemas.android.com/tools">
 
-    <com.google.android.material.bottomnavigation.BottomNavigationView
-        android:id="@+id/nav"
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/main"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:menu="@menu/bottom_nav_menu">
+        android:layout_height="match_parent"
+        tools:context=".MainActivity">
 
-    </com.google.android.material.bottomnavigation.BottomNavigationView>
+        <com.google.android.material.bottomnavigation.BottomNavigationView
+            android:id="@+id/nav"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:menu="@menu/bottom_nav_menu">
 
-    <fragment
-        android:id="@+id/nav_host_fragment"
-        android:name="androidx.navigation.fragment.NavHostFragment"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        app:defaultNavHost="true"
-        app:layout_constraintBottom_toTopOf="@id/nav"
-        app:layout_constraintTop_toTopOf="parent"
-        app:navGraph="@navigation/home_nav" />
-</androidx.constraintlayout.widget.ConstraintLayout>
+        </com.google.android.material.bottomnavigation.BottomNavigationView>
+
+        <fragment
+            android:id="@+id/nav_host_fragment"
+            android:name="androidx.navigation.fragment.NavHostFragment"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            app:defaultNavHost="true"
+            app:layout_constraintBottom_toTopOf="@id/nav"
+            app:layout_constraintTop_toTopOf="parent"
+            app:navGraph="@navigation/home_nav" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>

+ 50 - 47
app/src/main/res/layout/floating_window.xml

@@ -1,54 +1,57 @@
 <?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/floating_window"
-    android:layout_width="108dp"
-    android:layout_height="108dp"
-    android:orientation="vertical">
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
 
-    <com.google.android.material.card.MaterialCardView
-        style="?attr/materialCardViewElevatedStyle"
-        android:layout_width="100dp"
-        android:layout_height="100dp"
-        android:layout_gravity="center">
+    <FrameLayout
+        android:id="@+id/floating_window"
+        android:layout_width="108dp"
+        android:layout_height="108dp"
+        android:orientation="vertical">
 
-        <androidx.constraintlayout.widget.ConstraintLayout
-            android:layout_width="match_parent"
-            android:layout_height="match_parent">
+        <com.google.android.material.card.MaterialCardView
+            style="?attr/materialCardViewElevatedStyle"
+            android:layout_width="100dp"
+            android:layout_height="100dp"
+            android:layout_gravity="center">
 
-            <com.google.android.material.textview.MaterialTextView
-                android:id="@+id/tv_device_name"
+            <androidx.constraintlayout.widget.ConstraintLayout
                 android:layout_width="match_parent"
-                android:layout_height="24dp"
-                android:ellipsize="end"
-                android:gravity="center"
-                android:lines="1"
-                android:text="01-001"
-                android:textColor="?attr/colorPrimary"
-                android:textSize="14sp"
-                app:layout_constraintTop_toTopOf="parent" />
+                android:layout_height="match_parent">
 
-            <com.google.android.material.checkbox.MaterialCheckBox
-                android:id="@+id/sw_connect"
-                style="@style/Widget.Material3.CompoundButton.CheckBox"
-                android:layout_width="wrap_content"
-                android:layout_height="36dp"
-                android:checked="true"
-                android:text="Connect"
-                android:textSize="14sp"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toBottomOf="@id/tv_device_name" />
+                <com.google.android.material.textview.MaterialTextView
+                    android:id="@+id/tv_device_name"
+                    android:layout_width="match_parent"
+                    android:layout_height="24dp"
+                    android:ellipsize="end"
+                    android:gravity="center"
+                    android:lines="1"
+                    android:text="01-001"
+                    android:textColor="?attr/colorPrimary"
+                    android:textSize="14sp"
+                    app:layout_constraintTop_toTopOf="parent" />
 
-            <com.google.android.material.checkbox.MaterialCheckBox
-                android:id="@+id/sw_send"
-                style="@style/Widget.Material3.CompoundButton.CheckBox"
-                android:layout_width="wrap_content"
-                android:layout_height="36dp"
-                android:checked="true"
-                android:text="Send"
-                android:textSize="14sp"
-                app:layout_constraintStart_toStartOf="@id/sw_connect"
-                app:layout_constraintTop_toBottomOf="@id/sw_connect" />
-        </androidx.constraintlayout.widget.ConstraintLayout>
-    </com.google.android.material.card.MaterialCardView>
-</FrameLayout>
+                <com.google.android.material.checkbox.MaterialCheckBox
+                    android:id="@+id/sw_connect"
+                    style="@style/Widget.Material3.CompoundButton.CheckBox"
+                    android:layout_width="wrap_content"
+                    android:layout_height="36dp"
+                    android:checked="true"
+                    android:text="Connect"
+                    android:textSize="14sp"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toBottomOf="@id/tv_device_name" />
+
+                <com.google.android.material.checkbox.MaterialCheckBox
+                    android:id="@+id/sw_send"
+                    style="@style/Widget.Material3.CompoundButton.CheckBox"
+                    android:layout_width="wrap_content"
+                    android:layout_height="36dp"
+                    android:checked="true"
+                    android:text="Send"
+                    android:textSize="14sp"
+                    app:layout_constraintStart_toStartOf="@id/sw_connect"
+                    app:layout_constraintTop_toBottomOf="@id/sw_connect" />
+            </androidx.constraintlayout.widget.ConstraintLayout>
+        </com.google.android.material.card.MaterialCardView>
+    </FrameLayout>
+</layout>

+ 29 - 26
app/src/main/res/layout/fragment_backup.xml

@@ -1,35 +1,38 @@
 <?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".fragments.BackupFragment">
+    xmlns:tools="http://schemas.android.com/tools">
 
-    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
-        android:id="@+id/refresh"
+    <androidx.constraintlayout.widget.ConstraintLayout
         android:layout_width="match_parent"
-        android:layout_height="match_parent">
+        android:layout_height="match_parent"
+        tools:context=".fragments.BackupFragment">
 
-        <androidx.recyclerview.widget.RecyclerView
-            android:id="@+id/rv_backup"
+        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
+            android:id="@+id/refresh"
             android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:clipToPadding="false"
-            android:fitsSystemWindows="true">
+            android:layout_height="match_parent">
 
-        </androidx.recyclerview.widget.RecyclerView>
-    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/rv_backup"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:clipToPadding="false"
+                android:fitsSystemWindows="true">
 
+            </androidx.recyclerview.widget.RecyclerView>
+        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
 
-    <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
-        android:id="@+id/fab_backup"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="bottom|end"
-        android:layout_margin="16dp"
-        android:text="Backup"
-        app:icon="@drawable/ic_add"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent" />
-</androidx.constraintlayout.widget.ConstraintLayout>
+
+        <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
+            android:id="@+id/fab_backup"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom|end"
+            android:layout_margin="16dp"
+            android:text="Backup"
+            app:icon="@drawable/ic_add"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>

+ 178 - 175
app/src/main/res/layout/fragment_settings.xml

@@ -1,131 +1,180 @@
 <?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".fragments.SettingsFragment">
+    xmlns:tools="http://schemas.android.com/tools">
 
-    <ScrollView
+    <androidx.constraintlayout.widget.ConstraintLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:clipToPadding="false"
-        android:fitsSystemWindows="true">
+        tools:context=".fragments.SettingsFragment">
 
-        <LinearLayout
+        <ScrollView
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical"
-            android:padding="20dp">
+            android:layout_height="match_parent"
+            android:clipToPadding="false"
+            android:fitsSystemWindows="true">
 
-            <com.google.android.material.card.MaterialCardView
-                style="@style/Widget.Material3.CardView.Filled"
+            <LinearLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                app:cardBackgroundColor="?attr/colorSurfaceContainer">
+                android:orientation="vertical"
+                android:padding="20dp">
 
-                <LinearLayout
+                <com.google.android.material.card.MaterialCardView
+                    style="@style/Widget.Material3.CardView.Filled"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:orientation="vertical"
-                    android:padding="16dp">
+                    app:cardBackgroundColor="?attr/colorSurfaceContainer">
 
-                    <TextView
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_marginBottom="16dp"
-                        android:text="Server Settings"
-                        android:textColor="?attr/colorPrimary"
-                        android:textSize="14sp"
-                        android:textStyle="bold" />
-
-                    <com.google.android.material.textfield.TextInputLayout
+                    <LinearLayout
                         android:layout_width="match_parent"
                         android:layout_height="wrap_content"
-                        android:hint="Name">
+                        android:orientation="vertical"
+                        android:padding="16dp">
 
-                        <com.google.android.material.textfield.TextInputEditText
-                            android:id="@+id/et_name"
+                        <TextView
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_marginBottom="16dp"
+                            android:text="Server Settings"
+                            android:textColor="?attr/colorPrimary"
+                            android:textSize="14sp"
+                            android:textStyle="bold" />
+
+                        <com.google.android.material.textfield.TextInputLayout
                             android:layout_width="match_parent"
                             android:layout_height="wrap_content"
-                            android:lines="1" />
-                    </com.google.android.material.textfield.TextInputLayout>
+                            android:hint="Name">
 
-                    <com.google.android.material.textfield.TextInputLayout
-                        style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="16dp"
-                        android:hint="Server">
+                            <com.google.android.material.textfield.TextInputEditText
+                                android:id="@+id/et_device_label"
+                                android:layout_width="match_parent"
+                                android:layout_height="wrap_content"
+                                android:lines="1" />
+                        </com.google.android.material.textfield.TextInputLayout>
 
-                        <com.google.android.material.textfield.MaterialAutoCompleteTextView
-                            android:id="@+id/et_server"
+                        <com.google.android.material.textfield.TextInputLayout
+                            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
                             android:layout_width="match_parent"
-                            android:layout_height="wrap_content" />
+                            android:layout_height="wrap_content"
+                            android:layout_marginTop="16dp"
+                            android:hint="Server">
 
-                    </com.google.android.material.textfield.TextInputLayout>
+                            <com.google.android.material.textfield.MaterialAutoCompleteTextView
+                                android:id="@+id/et_server"
+                                android:layout_width="match_parent"
+                                android:layout_height="wrap_content" />
 
-                    <com.google.android.material.button.MaterialButton
-                        android:id="@+id/btn_server"
-                        android:layout_width="120dp"
-                        android:layout_height="wrap_content"
-                        android:layout_gravity="center"
-                        android:layout_marginTop="16dp"
-                        android:text="Save" />
-                </LinearLayout>
-            </com.google.android.material.card.MaterialCardView>
+                        </com.google.android.material.textfield.TextInputLayout>
 
+                        <com.google.android.material.button.MaterialButton
+                            android:id="@+id/btn_server"
+                            android:layout_width="120dp"
+                            android:layout_height="wrap_content"
+                            android:layout_gravity="center"
+                            android:layout_marginTop="16dp"
+                            android:text="Save" />
+                    </LinearLayout>
+                </com.google.android.material.card.MaterialCardView>
 
-            <com.google.android.material.card.MaterialCardView
-                style="@style/Widget.Material3.CardView.Filled"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="16dp"
-                app:cardBackgroundColor="?attr/colorSurfaceContainer">
 
-                <LinearLayout
+                <com.google.android.material.card.MaterialCardView
+                    style="@style/Widget.Material3.CardView.Filled"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:orientation="vertical"
-                    android:padding="16dp">
-
-                    <TextView
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_marginBottom="16dp"
-                        android:text="SIM Settings"
-                        android:textColor="?attr/colorPrimary"
-                        android:textSize="14sp"
-                        android:textStyle="bold" />
+                    android:layout_marginTop="16dp"
+                    app:cardBackgroundColor="?attr/colorSurfaceContainer">
 
                     <LinearLayout
                         android:layout_width="match_parent"
                         android:layout_height="wrap_content"
-                        android:orientation="horizontal">
+                        android:orientation="vertical"
+                        android:padding="16dp">
+
+                        <TextView
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_marginBottom="16dp"
+                            android:text="SIM Settings"
+                            android:textColor="?attr/colorPrimary"
+                            android:textSize="14sp"
+                            android:textStyle="bold" />
+
+                        <LinearLayout
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:orientation="horizontal">
+
+                            <com.google.android.material.textfield.TextInputLayout
+                                android:layout_width="0dp"
+                                android:layout_height="wrap_content"
+                                android:layout_weight="1"
+                                android:hint="MCC">
+
+                                <com.google.android.material.textfield.TextInputEditText
+                                    android:id="@+id/et_mcc"
+                                    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="MNC">
+
+                                <com.google.android.material.textfield.TextInputEditText
+                                    android:id="@+id/et_mnc"
+                                    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="Country">
+
+                                <com.google.android.material.textfield.TextInputEditText
+                                    android:id="@+id/et_country"
+                                    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
-                            android:layout_width="0dp"
+                            android:layout_width="match_parent"
                             android:layout_height="wrap_content"
-                            android:layout_weight="1"
-                            android:hint="MCC">
+                            android:layout_marginTop="16dp"
+                            android:hint="Number">
 
                             <com.google.android.material.textfield.TextInputEditText
-                                android:id="@+id/et_mcc"
+                                android:id="@+id/et_number"
                                 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:id="@+id/tl_iccid"
+                            android:layout_width="match_parent"
                             android:layout_height="wrap_content"
-                            android:layout_marginLeft="16dp"
-                            android:layout_weight="1"
-                            android:hint="MNC">
+                            android:layout_marginTop="16dp"
+                            android:hint="ICCID"
+                            app:endIconDrawable="@drawable/ic_refresh"
+                            app:endIconMode="custom">
 
                             <com.google.android.material.textfield.TextInputEditText
-                                android:id="@+id/et_mnc"
+                                android:id="@+id/et_iccid"
                                 android:layout_width="match_parent"
                                 android:layout_height="wrap_content"
                                 android:inputType="number"
@@ -133,114 +182,68 @@
                         </com.google.android.material.textfield.TextInputLayout>
 
                         <com.google.android.material.textfield.TextInputLayout
-                            android:layout_width="0dp"
+                            android:id="@+id/tl_imei"
+                            android:layout_width="match_parent"
                             android:layout_height="wrap_content"
-                            android:layout_marginLeft="16dp"
-                            android:layout_weight="1"
-                            android:hint="Country">
+                            android:layout_marginTop="16dp"
+                            android:hint="IMEI"
+                            app:endIconDrawable="@drawable/ic_refresh"
+                            app:endIconMode="custom">
 
                             <com.google.android.material.textfield.TextInputEditText
-                                android:id="@+id/et_country"
+                                android:id="@+id/et_imei"
                                 android:layout_width="match_parent"
                                 android:layout_height="wrap_content"
+                                android:inputType="number"
                                 android:lines="1" />
                         </com.google.android.material.textfield.TextInputLayout>
-                    </LinearLayout>
-
-                    <com.google.android.material.textfield.TextInputLayout
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="16dp"
-                        android:hint="Number">
-
-                        <com.google.android.material.textfield.TextInputEditText
-                            android:id="@+id/et_number"
-                            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:id="@+id/tl_iccid"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="16dp"
-                        android:hint="ICCID"
-                        app:endIconDrawable="@drawable/ic_refresh"
-                        app:endIconMode="custom">
 
-                        <com.google.android.material.textfield.TextInputEditText
-                            android:id="@+id/et_iccid"
-                            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:id="@+id/tl_imei"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="16dp"
-                        android:hint="IMEI"
-                        app:endIconDrawable="@drawable/ic_refresh"
-                        app:endIconMode="custom">
-
-                        <com.google.android.material.textfield.TextInputEditText
-                            android:id="@+id/et_imei"
+                        <com.google.android.material.textfield.TextInputLayout
+                            android:id="@+id/tl_imsi"
                             android:layout_width="match_parent"
                             android:layout_height="wrap_content"
-                            android:inputType="number"
-                            android:lines="1" />
-                    </com.google.android.material.textfield.TextInputLayout>
+                            android:layout_marginTop="16dp"
+                            android:hint="IMSI"
+                            app:endIconDrawable="@drawable/ic_refresh"
+                            app:endIconMode="custom">
 
-                    <com.google.android.material.textfield.TextInputLayout
-                        android:id="@+id/tl_imsi"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="16dp"
-                        android:hint="IMSI"
-                        app:endIconDrawable="@drawable/ic_refresh"
-                        app:endIconMode="custom">
+                            <com.google.android.material.textfield.TextInputEditText
+                                android:id="@+id/et_imsi"
+                                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.TextInputEditText
-                            android:id="@+id/et_imsi"
-                            android:layout_width="match_parent"
+                        <LinearLayout
+                            android:layout_width="wrap_content"
                             android:layout_height="wrap_content"
-                            android:inputType="number"
-                            android:lines="1" />
-                    </com.google.android.material.textfield.TextInputLayout>
-
-                    <LinearLayout
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_gravity="center_horizontal"
-                        android:layout_marginTop="16dp"
-                        android:orientation="horizontal">
+                            android:layout_gravity="center_horizontal"
+                            android:layout_marginTop="16dp"
+                            android:orientation="horizontal">
+
+                            <com.google.android.material.button.MaterialButton
+                                android:id="@+id/btn_request"
+                                style="?attr/materialIconButtonFilledTonalStyle"
+                                android:layout_width="120dp"
+                                android:layout_height="wrap_content"
+                                android:layout_gravity="center"
+                                android:text="Request"
+                                android:visibility="visible" />
 
-                        <com.google.android.material.button.MaterialButton
-                            android:id="@+id/btn_request"
-                            style="?attr/materialIconButtonFilledTonalStyle"
-                            android:layout_width="120dp"
-                            android:layout_height="wrap_content"
-                            android:layout_gravity="center"
-                            android:text="Request"
-                            android:visibility="visible" />
+                            <com.google.android.material.button.MaterialButton
+                                android:id="@+id/btn_save"
+                                android:layout_width="120dp"
+                                android:layout_height="wrap_content"
+                                android:layout_gravity="center"
+                                android:layout_marginLeft="16dp"
+                                android:text="Save"
+                                android:visibility="visible" />
+                        </LinearLayout>
 
-                        <com.google.android.material.button.MaterialButton
-                            android:id="@+id/btn_save"
-                            android:layout_width="120dp"
-                            android:layout_height="wrap_content"
-                            android:layout_gravity="center"
-                            android:layout_marginLeft="16dp"
-                            android:text="Save"
-                            android:visibility="visible" />
                     </LinearLayout>
-
-                </LinearLayout>
-            </com.google.android.material.card.MaterialCardView>
-        </LinearLayout>
-    </ScrollView>
-</androidx.constraintlayout.widget.ConstraintLayout>
+                </com.google.android.material.card.MaterialCardView>
+            </LinearLayout>
+        </ScrollView>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>

+ 127 - 124
app/src/main/res/layout/fragment_utils.xml

@@ -1,168 +1,171 @@
 <?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".fragments.UtilsFragment">
+    xmlns:tools="http://schemas.android.com/tools">
 
-    <ScrollView
+    <androidx.constraintlayout.widget.ConstraintLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:clipToPadding="false"
-        android:fitsSystemWindows="true">
+        tools:context=".fragments.UtilsFragment">
 
-        <LinearLayout
+        <ScrollView
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical"
-            android:padding="20dp">
+            android:layout_height="match_parent"
+            android:clipToPadding="false"
+            android:fitsSystemWindows="true">
 
-            <com.google.android.material.card.MaterialCardView
-                style="@style/Widget.Material3.CardView.Filled"
+            <LinearLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                app:cardBackgroundColor="?attr/colorSurfaceContainer">
+                android:orientation="vertical"
+                android:padding="20dp">
 
-                <LinearLayout
+                <com.google.android.material.card.MaterialCardView
+                    style="@style/Widget.Material3.CardView.Filled"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:orientation="vertical"
-                    android:padding="16dp">
-
-                    <TextView
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_marginBottom="16dp"
-                        android:text="App &amp; Data"
-                        android:textColor="?attr/colorPrimary"
-                        android:textSize="14sp"
-                        android:textStyle="bold" />
+                    app:cardBackgroundColor="?attr/colorSurfaceContainer">
 
                     <LinearLayout
                         android:layout_width="match_parent"
                         android:layout_height="wrap_content"
-                        android:gravity="center"
-                        android:orientation="horizontal">
+                        android:orientation="vertical"
+                        android:padding="16dp">
 
-                        <CheckBox
-                            android:id="@+id/cb_gsf"
+                        <TextView
                             android:layout_width="wrap_content"
                             android:layout_height="wrap_content"
-                            android:text="GSF" />
+                            android:layout_marginBottom="16dp"
+                            android:text="App &amp; Data"
+                            android:textColor="?attr/colorPrimary"
+                            android:textSize="14sp"
+                            android:textStyle="bold" />
 
-                        <CheckBox
-                            android:id="@+id/cb_gms"
-                            android:layout_width="wrap_content"
+                        <LinearLayout
+                            android:layout_width="match_parent"
                             android:layout_height="wrap_content"
-                            android:text="GMS" />
-
-                        <CheckBox
-                            android:id="@+id/cb_sms"
-                            android:layout_width="wrap_content"
+                            android:gravity="center"
+                            android:orientation="horizontal">
+
+                            <CheckBox
+                                android:id="@+id/cb_gsf"
+                                android:layout_width="wrap_content"
+                                android:layout_height="wrap_content"
+                                android:text="GSF" />
+
+                            <CheckBox
+                                android:id="@+id/cb_gms"
+                                android:layout_width="wrap_content"
+                                android:layout_height="wrap_content"
+                                android:text="GMS" />
+
+                            <CheckBox
+                                android:id="@+id/cb_sms"
+                                android:layout_width="wrap_content"
+                                android:layout_height="wrap_content"
+                                android:text="SMS" />
+                        </LinearLayout>
+
+                        <LinearLayout
+                            android:layout_width="match_parent"
                             android:layout_height="wrap_content"
-                            android:text="SMS" />
+                            android:orientation="horizontal">
+
+                            <com.google.android.material.button.MaterialButton
+                                android:id="@+id/btn_clear"
+                                android:layout_width="0dp"
+                                android:layout_height="wrap_content"
+                                android:layout_weight="1"
+                                android:text="Clear" />
+
+                            <com.google.android.material.button.MaterialButton
+                                android:id="@+id/btn_stop"
+                                android:layout_width="0dp"
+                                android:layout_height="wrap_content"
+                                android:layout_marginLeft="16dp"
+                                android:layout_weight="1"
+                                android:text="Stop" />
+                        </LinearLayout>
                     </LinearLayout>
+                </com.google.android.material.card.MaterialCardView>
+
+                <com.google.android.material.card.MaterialCardView
+                    style="@style/Widget.Material3.CardView.Filled"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="16dp"
+                    app:cardBackgroundColor="?attr/colorSurfaceContainer">
 
                     <LinearLayout
                         android:layout_width="match_parent"
                         android:layout_height="wrap_content"
-                        android:orientation="horizontal">
+                        android:orientation="vertical"
+                        android:padding="16dp">
 
-                        <com.google.android.material.button.MaterialButton
-                            android:id="@+id/btn_clear"
-                            android:layout_width="0dp"
+                        <TextView
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_marginBottom="16dp"
+                            android:text="Inject OTP"
+                            android:textColor="?attr/colorPrimary"
+                            android:textSize="14sp"
+                            android:textStyle="bold" />
+
+                        <com.google.android.material.textfield.TextInputLayout
+                            android:layout_width="match_parent"
                             android:layout_height="wrap_content"
-                            android:layout_weight="1"
-                            android:text="Clear" />
+                            android:hint="OTP">
+
+                            <com.google.android.material.textfield.TextInputEditText
+                                android:id="@+id/et_otp"
+                                android:layout_width="match_parent"
+                                android:layout_height="wrap_content"
+                                android:layout_gravity="center"
+                                android:inputType="number"
+                                android:lines="1" />
+                        </com.google.android.material.textfield.TextInputLayout>
 
                         <com.google.android.material.button.MaterialButton
-                            android:id="@+id/btn_stop"
-                            android:layout_width="0dp"
+                            android:id="@+id/btn_send"
+                            android:layout_width="120dp"
                             android:layout_height="wrap_content"
-                            android:layout_marginLeft="16dp"
-                            android:layout_weight="1"
-                            android:text="Stop" />
+                            android:layout_gravity="center"
+                            android:layout_marginTop="16dp"
+                            android:text="Send" />
                     </LinearLayout>
-                </LinearLayout>
-            </com.google.android.material.card.MaterialCardView>
-
-            <com.google.android.material.card.MaterialCardView
-                style="@style/Widget.Material3.CardView.Filled"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="16dp"
-                app:cardBackgroundColor="?attr/colorSurfaceContainer">
+                </com.google.android.material.card.MaterialCardView>
 
-                <LinearLayout
+                <com.google.android.material.card.MaterialCardView
+                    style="@style/Widget.Material3.CardView.Filled"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:orientation="vertical"
-                    android:padding="16dp">
+                    android:layout_marginTop="16dp"
+                    app:cardBackgroundColor="?attr/colorSurfaceContainer">
 
-                    <TextView
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_marginBottom="16dp"
-                        android:text="Inject OTP"
-                        android:textColor="?attr/colorPrimary"
-                        android:textSize="14sp"
-                        android:textStyle="bold" />
-
-                    <com.google.android.material.textfield.TextInputLayout
+                    <LinearLayout
                         android:layout_width="match_parent"
                         android:layout_height="wrap_content"
-                        android:hint="OTP">
+                        android:orientation="vertical"
+                        android:padding="16dp">
 
-                        <com.google.android.material.textfield.TextInputEditText
-                            android:id="@+id/et_otp"
-                            android:layout_width="match_parent"
+                        <TextView
+                            android:layout_width="wrap_content"
                             android:layout_height="wrap_content"
-                            android:layout_gravity="center"
-                            android:inputType="number"
-                            android:lines="1" />
-                    </com.google.android.material.textfield.TextInputLayout>
-
-                    <com.google.android.material.button.MaterialButton
-                        android:id="@+id/btn_send"
-                        android:layout_width="120dp"
-                        android:layout_height="wrap_content"
-                        android:layout_gravity="center"
-                        android:layout_marginTop="16dp"
-                        android:text="Send" />
-                </LinearLayout>
-            </com.google.android.material.card.MaterialCardView>
-
-            <com.google.android.material.card.MaterialCardView
-                style="@style/Widget.Material3.CardView.Filled"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="16dp"
-                app:cardBackgroundColor="?attr/colorSurfaceContainer">
+                            android:layout_marginBottom="16dp"
+                            android:text="MISC"
+                            android:textColor="?attr/colorPrimary"
+                            android:textSize="14sp"
+                            android:textStyle="bold" />
 
-                <LinearLayout
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:orientation="vertical"
-                    android:padding="16dp">
-
-                    <TextView
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_marginBottom="16dp"
-                        android:text="MISC"
-                        android:textColor="?attr/colorPrimary"
-                        android:textSize="14sp"
-                        android:textStyle="bold" />
-
-                    <com.google.android.material.button.MaterialButton
-                        android:id="@+id/btn_clear_conv"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:text="Clear Conversations" />
-                </LinearLayout>
-            </com.google.android.material.card.MaterialCardView>
-        </LinearLayout>
-    </ScrollView>
+                        <com.google.android.material.button.MaterialButton
+                            android:id="@+id/btn_clear_conv"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="Clear Conversations" />
+                    </LinearLayout>
+                </com.google.android.material.card.MaterialCardView>
+            </LinearLayout>
+        </ScrollView>
 
-</androidx.constraintlayout.widget.ConstraintLayout>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>

+ 80 - 77
app/src/main/res/layout/item_backup.xml

@@ -1,96 +1,99 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content">
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
 
-    <com.google.android.material.card.MaterialCardView
-        style="?attr/materialCardViewFilledStyle"
+    <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginLeft="16dp"
-        android:layout_marginTop="16dp"
-        android:layout_marginRight="16dp"
-        app:cardBackgroundColor="?attr/colorSurfaceContainer">
+        android:layout_height="wrap_content">
 
-        <LinearLayout
+        <com.google.android.material.card.MaterialCardView
+            style="?attr/materialCardViewFilledStyle"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:orientation="vertical"
-            android:paddingStart="16dp"
-            android:paddingTop="8dp"
-            android:paddingEnd="16dp">
+            android:layout_marginLeft="16dp"
+            android:layout_marginTop="16dp"
+            android:layout_marginRight="16dp"
+            app:cardBackgroundColor="?attr/colorSurfaceContainer">
 
-            <androidx.constraintlayout.widget.ConstraintLayout
+            <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content">
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:paddingStart="16dp"
+                android:paddingTop="8dp"
+                android:paddingEnd="16dp">
 
-                <com.google.android.material.textview.MaterialTextView
-                    android:id="@+id/tv_number"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="123456789"
-                    android:textColor="?attr/colorPrimary"
-                    android:textSize="16sp"
-                    android:textStyle="bold"
-                    app:layout_constraintBottom_toBottomOf="parent"
-                    app:layout_constraintStart_toStartOf="parent"
-                    app:layout_constraintTop_toTopOf="parent" />
+                <androidx.constraintlayout.widget.ConstraintLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content">
 
-                <com.google.android.material.textview.MaterialTextView
-                    android:id="@+id/tv_time"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="2024-05-13 18:00:00"
-                    android:textColor="?attr/colorOnSurfaceVariant"
-                    android:textSize="14sp"
-                    app:layout_constraintBaseline_toBaselineOf="@id/tv_number"
-                    app:layout_constraintBottom_toBottomOf="parent"
-                    app:layout_constraintEnd_toEndOf="parent"
-                    app:layout_constraintTop_toTopOf="parent" />
-            </androidx.constraintlayout.widget.ConstraintLayout>
+                    <com.google.android.material.textview.MaterialTextView
+                        android:id="@+id/tv_number"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="123456789"
+                        android:textColor="?attr/colorPrimary"
+                        android:textSize="16sp"
+                        android:textStyle="bold"
+                        app:layout_constraintBottom_toBottomOf="parent"
+                        app:layout_constraintStart_toStartOf="parent"
+                        app:layout_constraintTop_toTopOf="parent" />
 
+                    <com.google.android.material.textview.MaterialTextView
+                        android:id="@+id/tv_time"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="2024-05-13 18:00:00"
+                        android:textColor="?attr/colorOnSurfaceVariant"
+                        android:textSize="14sp"
+                        app:layout_constraintBaseline_toBaselineOf="@id/tv_number"
+                        app:layout_constraintBottom_toBottomOf="parent"
+                        app:layout_constraintEnd_toEndOf="parent"
+                        app:layout_constraintTop_toTopOf="parent" />
+                </androidx.constraintlayout.widget.ConstraintLayout>
 
-            <com.google.android.material.textview.MaterialTextView
-                android:id="@+id/tv_info"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="8dp"
-                android:text="mcc: 310    mnc: 240   coutry: us"
-                android:textColor="?attr/colorOnSurfaceVariant"
-                android:textSize="14sp" />
 
-            <androidx.constraintlayout.widget.ConstraintLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="8dp"
-                android:orientation="horizontal">
-
-                <com.google.android.material.button.MaterialButton
-                    android:id="@+id/btn_del"
-                    style="@style/Widget.Material3.Button.TextButton"
+                <com.google.android.material.textview.MaterialTextView
+                    android:id="@+id/tv_info"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:layout_gravity="center_vertical"
-                    android:layout_marginEnd="8dp"
-                    android:text="Delete"
-                    android:textColor="?attr/colorSecondary"
-                    app:layout_constraintBaseline_toBaselineOf="@id/btn_restore"
-                    app:layout_constraintEnd_toStartOf="@id/btn_restore" />
+                    android:layout_marginTop="8dp"
+                    android:text="mcc: 310    mnc: 240   coutry: us"
+                    android:textColor="?attr/colorOnSurfaceVariant"
+                    android:textSize="14sp" />
 
-                <com.google.android.material.button.MaterialButton
-                    android:id="@+id/btn_restore"
-                    style="@style/Widget.Material3.Button.TextButton"
-                    android:layout_width="wrap_content"
+                <androidx.constraintlayout.widget.ConstraintLayout
+                    android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:layout_gravity="center_vertical"
-                    android:text="Restore"
-                    app:layout_constraintBottom_toBottomOf="parent"
-                    app:layout_constraintEnd_toEndOf="parent"
-                    app:layout_constraintTop_toTopOf="parent" />
-            </androidx.constraintlayout.widget.ConstraintLayout>
+                    android:layout_marginTop="8dp"
+                    android:orientation="horizontal">
+
+                    <com.google.android.material.button.MaterialButton
+                        android:id="@+id/btn_del"
+                        style="@style/Widget.Material3.Button.TextButton"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="center_vertical"
+                        android:layout_marginEnd="8dp"
+                        android:text="Delete"
+                        android:textColor="?attr/colorSecondary"
+                        app:layout_constraintBaseline_toBaselineOf="@id/btn_restore"
+                        app:layout_constraintEnd_toStartOf="@id/btn_restore" />
+
+                    <com.google.android.material.button.MaterialButton
+                        android:id="@+id/btn_restore"
+                        style="@style/Widget.Material3.Button.TextButton"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="center_vertical"
+                        android:text="Restore"
+                        app:layout_constraintBottom_toBottomOf="parent"
+                        app:layout_constraintEnd_toEndOf="parent"
+                        app:layout_constraintTop_toTopOf="parent" />
+                </androidx.constraintlayout.widget.ConstraintLayout>
 
-        </LinearLayout>
+            </LinearLayout>
 
-    </com.google.android.material.card.MaterialCardView>
-</LinearLayout>
+        </com.google.android.material.card.MaterialCardView>
+    </LinearLayout>
+</layout>

+ 2 - 1
build.gradle

@@ -1,5 +1,6 @@
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
 plugins {
-alias(libs.plugins.androidApplication) apply false
+    alias(libs.plugins.androidApplication) apply false
     alias(libs.plugins.jetbrainsKotlinAndroid) apply false
+    id("com.google.dagger.hilt.android") version "2.44" apply false
 }

+ 2 - 0
gradle/libs.versions.toml

@@ -3,6 +3,7 @@ agp = "8.3.2"
 commonsCollections4 = "4.4"
 commonsIo = "2.16.1"
 commonsLang3 = "3.14.0"
+datastore = "1.1.1"
 gson = "2.10.1"
 junit = "4.13.2"
 junitVersion = "1.1.5"
@@ -24,6 +25,7 @@ coreKtx = "1.13.1"
 commons-collections4 = { module = "org.apache.commons:commons-collections4", version.ref = "commonsCollections4" }
 commons-io = { module = "commons-io:commons-io", version.ref = "commonsIo" }
 commons-lang3 = { module = "org.apache.commons:commons-lang3", version.ref = "commonsLang3" }
+datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastore" }
 gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
 junit = { group = "junit", name = "junit", version.ref = "junit" }
 ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }