From 84cd577a3cb541e8aa46d4b790e361ec89cec986 Mon Sep 17 00:00:00 2001 From: Aayush Gupta Date: Tue, 19 Nov 2024 13:37:26 +0700 Subject: [PATCH] SpoofProvider: Refactor and adjust a bit * Show default device on top under different category * Remove spoof configuration when default is selected Signed-off-by: Aayush Gupta --- .../store/data/providers/SpoofProviderTest.kt | 12 +-- .../store/data/providers/AuthProvider.kt | 41 +-------- .../providers/NativeDeviceInfoProvider.kt | 24 +++-- .../data/providers/SpoofDeviceProvider.kt | 13 +-- .../store/data/providers/SpoofProvider.kt | 87 ++++++++++++------ .../view/epoxy/views/preference/DeviceView.kt | 1 + .../view/epoxy/views/preference/LocaleView.kt | 1 + .../view/ui/spoof/DeviceSpoofFragment.kt | 90 ++++++++++--------- .../view/ui/spoof/LocaleSpoofFragment.kt | 84 ++++++++--------- .../store/view/ui/spoof/SpoofFragment.kt | 3 +- .../store/viewmodel/spoof/SpoofViewModel.kt | 55 ++++++++++-- app/src/main/res/values/strings.xml | 4 + 12 files changed, 229 insertions(+), 186 deletions(-) diff --git a/app/src/androidTest/java/com/aurora/store/data/providers/SpoofProviderTest.kt b/app/src/androidTest/java/com/aurora/store/data/providers/SpoofProviderTest.kt index b25498637..d4de24b75 100644 --- a/app/src/androidTest/java/com/aurora/store/data/providers/SpoofProviderTest.kt +++ b/app/src/androidTest/java/com/aurora/store/data/providers/SpoofProviderTest.kt @@ -36,22 +36,22 @@ class SpoofProviderTest { @Test fun testSpoofingDeviceLocale() { - assertThat(spoofProvider.isLocaleSpoofEnabled()).isFalse() + assertThat(spoofProvider.isLocaleSpoofEnabled).isFalse() spoofProvider.setSpoofLocale(Locale.JAPAN) - assertThat(spoofProvider.isLocaleSpoofEnabled()).isTrue() - assertThat(spoofProvider.getSpoofLocale() == Locale.JAPAN).isTrue() + assertThat(spoofProvider.isLocaleSpoofEnabled).isTrue() + assertThat(spoofProvider.locale == Locale.JAPAN).isTrue() } @Test fun testSpoofingDeviceProperties() { - assertThat(spoofProvider.isDeviceSpoofEnabled()).isFalse() + assertThat(spoofProvider.isDeviceSpoofEnabled).isFalse() val properties = Properties().apply { setProperty("UserReadableName", "Test") } spoofProvider.setSpoofDeviceProperties(properties) - assertThat(spoofProvider.isDeviceSpoofEnabled()).isTrue() - assertThat(spoofProvider.getSpoofDeviceProperties() == properties).isTrue() + assertThat(spoofProvider.isDeviceSpoofEnabled).isTrue() + assertThat(spoofProvider.deviceProperties == properties).isTrue() } } diff --git a/app/src/main/java/com/aurora/store/data/providers/AuthProvider.kt b/app/src/main/java/com/aurora/store/data/providers/AuthProvider.kt index f6e7d3df4..9103af7cd 100644 --- a/app/src/main/java/com/aurora/store/data/providers/AuthProvider.kt +++ b/app/src/main/java/com/aurora/store/data/providers/AuthProvider.kt @@ -32,13 +32,10 @@ import com.aurora.store.data.model.Auth import com.aurora.store.util.Preferences import com.aurora.store.util.Preferences.PREFERENCE_AUTH_DATA import com.aurora.store.util.Preferences.PREFERENCE_DISPENSER_URLS -import com.aurora.store.util.Preferences.PREFERENCE_VENDING_VERSION import com.google.gson.Gson import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import java.util.Locale -import java.util.Properties import javax.inject.Inject import javax.inject.Singleton @@ -72,24 +69,6 @@ class AuthProvider @Inject constructor( val isAnonymous: Boolean get() = AccountProvider.getAccountType(context) == AccountType.ANONYMOUS - private val properties: Properties - get() { - val currentProperties = if (spoofProvider.isDeviceSpoofEnabled()) { - spoofProvider.getSpoofDeviceProperties() - } else { - NativeDeviceInfoProvider(context).getNativeDeviceProperties() - } - setVendingVersion(currentProperties) - return currentProperties - } - - private val locale: Locale - get() = if (spoofProvider.isLocaleSpoofEnabled()) { - spoofProvider.getSpoofLocale() - } else { - Locale.getDefault() - } - /** * Checks whether saved AuthData is valid or not */ @@ -124,8 +103,8 @@ class AuthProvider @Inject constructor( email = email, token = token, tokenType = tokenType, - properties = properties, - locale = locale, + properties = spoofProvider.deviceProperties, + locale = spoofProvider.locale, ) ) } catch (exception: Exception) { @@ -153,8 +132,8 @@ class AuthProvider @Inject constructor( token = auth.auth, tokenType = AuthHelper.Token.AUTH, isAnonymous = true, - properties = properties, - locale = locale + properties = spoofProvider.deviceProperties, + locale = spoofProvider.locale ) ) } catch (exception: Exception) { @@ -178,18 +157,6 @@ class AuthProvider @Inject constructor( Preferences.remove(context, PREFERENCE_AUTH_DATA) } - private fun setVendingVersion(currentProperties: Properties) { - val vendingVersionIndex = Preferences.getInteger(context, PREFERENCE_VENDING_VERSION) - if (vendingVersionIndex > 0) { - val resources = context.resources - val versionCodes = resources.getStringArray(R.array.pref_vending_version_codes) - val versionStrings = resources.getStringArray(R.array.pref_vending_version) - - currentProperties.setProperty("Vending.version", versionCodes[vendingVersionIndex]) - currentProperties.setProperty("Vending.versionString", versionStrings[vendingVersionIndex]) - } - } - @Throws(Exception::class) private fun throwError(playResponse: PlayResponse, context: Context) { when (playResponse.code) { diff --git a/app/src/main/java/com/aurora/store/data/providers/NativeDeviceInfoProvider.kt b/app/src/main/java/com/aurora/store/data/providers/NativeDeviceInfoProvider.kt index 3df6441f5..f1c606315 100644 --- a/app/src/main/java/com/aurora/store/data/providers/NativeDeviceInfoProvider.kt +++ b/app/src/main/java/com/aurora/store/data/providers/NativeDeviceInfoProvider.kt @@ -26,12 +26,12 @@ import androidx.core.content.getSystemService import com.aurora.extensions.isHuawei import java.util.Properties -class NativeDeviceInfoProvider(val context: Context) { +object NativeDeviceInfoProvider { - fun getNativeDeviceProperties(isExport: Boolean = false): Properties { + fun getNativeDeviceProperties(context: Context, isExport: Boolean = false): Properties { val properties = Properties().apply { //Build Props - setProperty("UserReadableName", "${Build.DEVICE}-default") + setProperty("UserReadableName", "${Build.MANUFACTURER} ${Build.MODEL}") setProperty("Build.HARDWARE", Build.HARDWARE) setProperty( "Build.RADIO", @@ -71,11 +71,11 @@ class NativeDeviceInfoProvider(val context: Context) { //Supported Platforms setProperty("Platforms", Build.SUPPORTED_ABIS.joinToString(separator = ",")) //Supported Features - setProperty("Features", getFeatures().joinToString(separator = ",")) + setProperty("Features", getFeatures(context).joinToString(separator = ",")) //Shared Locales - setProperty("Locales", getLocales().joinToString(separator = ",")) + setProperty("Locales", getLocales(context).joinToString(separator = ",")) //Shared Libraries - setProperty("SharedLibraries", getSharedLibraries().joinToString(separator = ",")) + setProperty("SharedLibraries", getSharedLibraries(context).joinToString(separator = ",")) //GL Extensions val activityManager = context.getSystemService() setProperty( @@ -104,27 +104,25 @@ class NativeDeviceInfoProvider(val context: Context) { setProperty("SimOperator", "38") } - if (isHuawei && !isExport) - stripHuaweiProperties(properties) - + if (isHuawei && !isExport) stripHuaweiProperties(properties) return properties } - private fun getFeatures(): List { + private fun getFeatures(context: Context): List { return context .packageManager .systemAvailableFeatures - ?.mapNotNull { it.name } ?: emptyList() + .mapNotNull { it.name } } - private fun getLocales(): List { + private fun getLocales(context: Context): List { return context .assets .locales .mapNotNull { it.replace("-", "_") } } - private fun getSharedLibraries(): List { + private fun getSharedLibraries(context: Context): List { return context .packageManager .systemSharedLibraryNames diff --git a/app/src/main/java/com/aurora/store/data/providers/SpoofDeviceProvider.kt b/app/src/main/java/com/aurora/store/data/providers/SpoofDeviceProvider.kt index 763a16462..4536f2d7c 100644 --- a/app/src/main/java/com/aurora/store/data/providers/SpoofDeviceProvider.kt +++ b/app/src/main/java/com/aurora/store/data/providers/SpoofDeviceProvider.kt @@ -23,7 +23,6 @@ import android.content.Context import android.util.Log import com.aurora.store.BuildConfig import com.aurora.store.util.PathUtil -import dagger.hilt.android.qualifiers.ApplicationContext import java.io.BufferedInputStream import java.io.File import java.io.FileInputStream @@ -31,22 +30,26 @@ import java.io.IOException import java.util.Properties import java.util.jar.JarEntry import java.util.jar.JarFile -import javax.inject.Inject import javax.inject.Singleton +/** + * Provider class to work with device spoof configs imported by users & shipped by GPlayAPI library + * + * Do not use this class directly. Consider using [SpoofProvider] instead. + */ @Singleton -class SpoofDeviceProvider @Inject constructor(@ApplicationContext val context: Context) { +open class SpoofDeviceProvider(private val context: Context) { private val TAG = SpoofDeviceProvider::class.java.simpleName private val SUFFIX = ".properties" - val availableDevice: List + val availableDeviceProperties: MutableList get() { val propertiesList: MutableList = ArrayList() - propertiesList.add(0, NativeDeviceInfoProvider(context).getNativeDeviceProperties()) propertiesList.addAll(spoofDevicesFromApk) propertiesList.addAll(spoofDevicesFromUser) + propertiesList.sortBy { it.getProperty("UserReadableName") } return propertiesList } diff --git a/app/src/main/java/com/aurora/store/data/providers/SpoofProvider.kt b/app/src/main/java/com/aurora/store/data/providers/SpoofProvider.kt index 81d43d198..dcbad046b 100644 --- a/app/src/main/java/com/aurora/store/data/providers/SpoofProvider.kt +++ b/app/src/main/java/com/aurora/store/data/providers/SpoofProvider.kt @@ -20,7 +20,9 @@ package com.aurora.store.data.providers import android.content.Context +import com.aurora.store.R import com.aurora.store.util.Preferences +import com.aurora.store.util.Preferences.PREFERENCE_VENDING_VERSION import com.google.gson.Gson import dagger.hilt.android.qualifiers.ApplicationContext import java.util.Locale @@ -28,50 +30,65 @@ import java.util.Properties import javax.inject.Inject import javax.inject.Singleton +/** + * Provider class to work with device and locale spoofs + */ @Singleton class SpoofProvider @Inject constructor( + private val gson: Gson, @ApplicationContext val context: Context, - private val gson: Gson -) { +) : SpoofDeviceProvider(context) { companion object { - const val LOCALE_SPOOF_ENABLED = "LOCALE_SPOOF_ENABLED" - const val LOCALE_SPOOF_LANG = "LOCALE_SPOOF_LANG" - const val LOCALE_SPOOF_COUNTRY = "LOCALE_SPOOF_COUNTRY" + private const val LOCALE_SPOOF_ENABLED = "LOCALE_SPOOF_ENABLED" + private const val LOCALE_SPOOF_LANG = "LOCALE_SPOOF_LANG" + private const val LOCALE_SPOOF_COUNTRY = "LOCALE_SPOOF_COUNTRY" - const val DEVICE_SPOOF_ENABLED = "DEVICE_SPOOF_ENABLED" - const val DEVICE_SPOOF_PROPERTIES = "DEVICE_SPOOF_PROPERTIES" + private const val DEVICE_SPOOF_ENABLED = "DEVICE_SPOOF_ENABLED" + private const val DEVICE_SPOOF_PROPERTIES = "DEVICE_SPOOF_PROPERTIES" } - fun isLocaleSpoofEnabled(): Boolean { - return Preferences.getBoolean(context, LOCALE_SPOOF_ENABLED) + val availableSpoofDeviceProperties get() = availableDeviceProperties + val availableSpoofLocales = Locale.getAvailableLocales().toMutableList().apply { + remove(Locale.getDefault()) + sortBy { it.displayName } } - fun isDeviceSpoofEnabled(): Boolean { - return Preferences.getBoolean(context, DEVICE_SPOOF_ENABLED) - } + val deviceProperties: Properties + get() { + val currentProperties = if (isDeviceSpoofEnabled) { + spoofDeviceProperties + } else { + NativeDeviceInfoProvider.getNativeDeviceProperties(context) + } + setVendingVersion(currentProperties) + return currentProperties + } - fun getSpoofLocale(): Locale { - return if (isLocaleSpoofEnabled()) { - Locale( - Preferences.getString(context, LOCALE_SPOOF_LANG), - Preferences.getString(context, LOCALE_SPOOF_COUNTRY) - ) + val locale: Locale + get() = if (isLocaleSpoofEnabled) { + spoofLocale } else { Locale.getDefault() } - } - fun getSpoofDeviceProperties(): Properties { - return if (isDeviceSpoofEnabled()) { - return gson.fromJson( - Preferences.getString(context, DEVICE_SPOOF_PROPERTIES), - Properties::class.java - ) - } else { - Properties() - } - } + val isLocaleSpoofEnabled: Boolean + get() = Preferences.getBoolean(context, LOCALE_SPOOF_ENABLED) + + val isDeviceSpoofEnabled: Boolean + get() = Preferences.getBoolean(context, DEVICE_SPOOF_ENABLED) + + private val spoofLocale: Locale + get() = Locale( + Preferences.getString(context, LOCALE_SPOOF_LANG), + Preferences.getString(context, LOCALE_SPOOF_COUNTRY) + ) + + private val spoofDeviceProperties: Properties + get() = gson.fromJson( + Preferences.getString(context, DEVICE_SPOOF_PROPERTIES), + Properties::class.java + ) fun setSpoofLocale(locale: Locale) { Preferences.putBoolean(context, LOCALE_SPOOF_ENABLED, true) @@ -94,4 +111,16 @@ class SpoofProvider @Inject constructor( Preferences.remove(context, DEVICE_SPOOF_ENABLED) Preferences.remove(context, DEVICE_SPOOF_PROPERTIES) } + + private fun setVendingVersion(currentProperties: Properties) { + val vendingVersionIndex = Preferences.getInteger(context, PREFERENCE_VENDING_VERSION) + if (vendingVersionIndex > 0) { + val resources = context.resources + val versionCodes = resources.getStringArray(R.array.pref_vending_version_codes) + val versionStrings = resources.getStringArray(R.array.pref_vending_version) + + currentProperties.setProperty("Vending.version", versionCodes[vendingVersionIndex]) + currentProperties.setProperty("Vending.versionString", versionStrings[vendingVersionIndex]) + } + } } diff --git a/app/src/main/java/com/aurora/store/view/epoxy/views/preference/DeviceView.kt b/app/src/main/java/com/aurora/store/view/epoxy/views/preference/DeviceView.kt index 6d51d25dd..3932c458e 100644 --- a/app/src/main/java/com/aurora/store/view/epoxy/views/preference/DeviceView.kt +++ b/app/src/main/java/com/aurora/store/view/epoxy/views/preference/DeviceView.kt @@ -55,6 +55,7 @@ class DeviceView @JvmOverloads constructor( @ModelProp fun markChecked(isChecked: Boolean) { binding.checkbox.isChecked = isChecked + binding.checkbox.isEnabled = !isChecked } @CallbackProp diff --git a/app/src/main/java/com/aurora/store/view/epoxy/views/preference/LocaleView.kt b/app/src/main/java/com/aurora/store/view/epoxy/views/preference/LocaleView.kt index 0aa51ab3b..c8525f5b7 100644 --- a/app/src/main/java/com/aurora/store/view/epoxy/views/preference/LocaleView.kt +++ b/app/src/main/java/com/aurora/store/view/epoxy/views/preference/LocaleView.kt @@ -49,6 +49,7 @@ class LocaleView @JvmOverloads constructor( @ModelProp fun markChecked(isChecked: Boolean) { binding.checkbox.isChecked = isChecked + binding.checkbox.isEnabled = !isChecked } @CallbackProp diff --git a/app/src/main/java/com/aurora/store/view/ui/spoof/DeviceSpoofFragment.kt b/app/src/main/java/com/aurora/store/view/ui/spoof/DeviceSpoofFragment.kt index 9c991f86e..014190eda 100644 --- a/app/src/main/java/com/aurora/store/view/ui/spoof/DeviceSpoofFragment.kt +++ b/app/src/main/java/com/aurora/store/view/ui/spoof/DeviceSpoofFragment.kt @@ -25,83 +25,85 @@ import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle +import androidx.navigation.fragment.findNavController import com.aurora.extensions.toast import com.aurora.store.R -import com.aurora.store.data.providers.NativeDeviceInfoProvider -import com.aurora.store.data.providers.SpoofProvider import com.aurora.store.databinding.FragmentGenericRecyclerBinding +import com.aurora.store.view.epoxy.views.TextDividerViewModel_ import com.aurora.store.view.epoxy.views.preference.DeviceViewModel_ import com.aurora.store.view.ui.commons.BaseFragment import com.aurora.store.viewmodel.spoof.SpoofViewModel import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch import java.util.Properties -import javax.inject.Inject @AndroidEntryPoint class DeviceSpoofFragment : BaseFragment() { + private val viewModel: SpoofViewModel by viewModels() - @Inject - lateinit var spoofProvider: SpoofProvider - - private lateinit var properties: Properties - companion object { @JvmStatic fun newInstance(): DeviceSpoofFragment { - return DeviceSpoofFragment().apply { - - } + return DeviceSpoofFragment() } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - properties = if (spoofProvider.isDeviceSpoofEnabled()) { - spoofProvider.getSpoofDeviceProperties() - } else { - NativeDeviceInfoProvider(requireContext()).getNativeDeviceProperties() - } - viewLifecycleOwner.lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.availableDevices.collect { updateController(it) } } } - viewModel.fetchAvailableDevices() } - private fun updateController(locales: List) { + private fun updateController(devices: List) { binding.recycler.withModels { setFilterDuplicates(true) - locales - .sortedBy { it.getProperty("UserReadableName") } - .forEach { - add( - DeviceViewModel_() - .id(it.hashCode()) - .markChecked( - properties.getProperty("UserReadableName") == it.getProperty( - "UserReadableName" - ) - ) - .checked { _, checked -> - if (checked) { - properties = it - saveSelection(it) - requestModelBuild() - } + + add( + TextDividerViewModel_() + .id("default_divider") + .title(getString(R.string.default_spoof)) + ) + + add( + DeviceViewModel_() + .id(viewModel.defaultProperties.hashCode()) + .markChecked(viewModel.isDeviceSelected(viewModel.defaultProperties)) + .checked { _, checked -> + if (checked) { + viewModel.onDeviceSelected(viewModel.defaultProperties) + requestModelBuild() + findNavController().navigate(R.id.forceRestartDialog) + } + } + .properties(viewModel.defaultProperties) + ) + + add( + TextDividerViewModel_() + .id("available_divider") + .title(getString(R.string.available_spoof)) + ) + + devices.forEach { + add( + DeviceViewModel_() + .id(it.hashCode()) + .markChecked(viewModel.isDeviceSelected(it)) + .checked { _, checked -> + if (checked) { + viewModel.onDeviceSelected(it) + requestModelBuild() + findNavController().navigate(R.id.forceRestartDialog) } - .properties(it) - ) - } + } + .properties(it) + ) + } } } - - private fun saveSelection(properties: Properties) { - requireContext().toast(R.string.spoof_apply) - spoofProvider.setSpoofDeviceProperties(properties) - } } diff --git a/app/src/main/java/com/aurora/store/view/ui/spoof/LocaleSpoofFragment.kt b/app/src/main/java/com/aurora/store/view/ui/spoof/LocaleSpoofFragment.kt index b3755a7f4..83cfbf895 100644 --- a/app/src/main/java/com/aurora/store/view/ui/spoof/LocaleSpoofFragment.kt +++ b/app/src/main/java/com/aurora/store/view/ui/spoof/LocaleSpoofFragment.kt @@ -20,68 +20,83 @@ package com.aurora.store.view.ui.spoof import android.os.Bundle -import android.util.Log import android.view.View +import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope +import androidx.navigation.fragment.findNavController import com.aurora.extensions.toast import com.aurora.store.R -import com.aurora.store.data.providers.SpoofProvider import com.aurora.store.databinding.FragmentGenericRecyclerBinding +import com.aurora.store.view.epoxy.views.TextDividerViewModel_ import com.aurora.store.view.epoxy.views.preference.LocaleViewModel_ import com.aurora.store.view.ui.commons.BaseFragment +import com.aurora.store.viewmodel.spoof.SpoofViewModel import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch import java.util.Locale -import javax.inject.Inject @AndroidEntryPoint class LocaleSpoofFragment : BaseFragment() { - private val TAG = LocaleSpoofFragment::class.java.simpleName - - @Inject - lateinit var spoofProvider: SpoofProvider - - private lateinit var locale: Locale + private val viewModel: SpoofViewModel by viewModels() companion object { @JvmStatic fun newInstance(): LocaleSpoofFragment { - return LocaleSpoofFragment().apply { - - } + return LocaleSpoofFragment() } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - locale = if (spoofProvider.isLocaleSpoofEnabled()) { - spoofProvider.getSpoofLocale() - } else { - Locale.getDefault() - } - - try { - updateController(fetchAvailableLocales()) - } catch (exception: Exception) { - Log.e(TAG, "Could not get available locales", exception) + viewLifecycleOwner.lifecycleScope.launch { + viewModel.availableLocales.collect { + updateController(it) + } } } private fun updateController(locales: List) { binding.recycler.withModels { setFilterDuplicates(true) - locales - .sortedBy { it.displayName } - .forEach { + + add( + TextDividerViewModel_() + .id("default_divider") + .title(getString(R.string.default_spoof)) + ) + + add( + LocaleViewModel_() + .id(viewModel.defaultLocale.language) + .markChecked(viewModel.isLocaleSelected(viewModel.defaultLocale)) + .checked { _, checked -> + if (checked) { + viewModel.onLocaleSelected(viewModel.defaultLocale) + requestModelBuild() + findNavController().navigate(R.id.forceRestartDialog) + } + } + .locale(viewModel.defaultLocale) + ) + + add( + TextDividerViewModel_() + .id("available_divider") + .title(getString(R.string.available_spoof)) + ) + + locales.forEach { add( LocaleViewModel_() .id(it.language) - .markChecked(locale == it) + .markChecked(viewModel.spoofProvider.locale == it) .checked { _, checked -> if (checked) { - locale = it - saveSelection(it) + viewModel.onLocaleSelected(it) requestModelBuild() + findNavController().navigate(R.id.forceRestartDialog) } } .locale(it) @@ -89,17 +104,4 @@ class LocaleSpoofFragment : BaseFragment() { } } } - - private fun fetchAvailableLocales(): List { - val locales = Locale.getAvailableLocales() - val localeList: MutableList = ArrayList() - localeList.addAll(locales) - localeList.add(0, Locale.getDefault()) - return localeList - } - - private fun saveSelection(locale: Locale) { - requireContext().toast(R.string.spoof_apply) - spoofProvider.setSpoofLocale(locale) - } } diff --git a/app/src/main/java/com/aurora/store/view/ui/spoof/SpoofFragment.kt b/app/src/main/java/com/aurora/store/view/ui/spoof/SpoofFragment.kt index 3609bcf27..16df22231 100644 --- a/app/src/main/java/com/aurora/store/view/ui/spoof/SpoofFragment.kt +++ b/app/src/main/java/com/aurora/store/view/ui/spoof/SpoofFragment.kt @@ -123,8 +123,7 @@ class SpoofFragment : BaseFragment() { private fun exportDeviceConfig(uri: Uri) { try { - NativeDeviceInfoProvider(requireContext()) - .getNativeDeviceProperties(true) + NativeDeviceInfoProvider.getNativeDeviceProperties(requireContext(), true) .store(requireContext().contentResolver?.openOutputStream(uri), "DEVICE_CONFIG") toast(R.string.toast_export_success) } catch (exception: Exception) { diff --git a/app/src/main/java/com/aurora/store/viewmodel/spoof/SpoofViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/spoof/SpoofViewModel.kt index f04089a30..7990be8a5 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/spoof/SpoofViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/spoof/SpoofViewModel.kt @@ -1,27 +1,64 @@ package com.aurora.store.viewmodel.spoof +import android.content.Context import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.aurora.store.data.providers.SpoofDeviceProvider +import com.aurora.store.data.providers.NativeDeviceInfoProvider +import com.aurora.store.data.providers.SpoofProvider import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Dispatchers +import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.launch +import java.util.Locale import java.util.Properties import javax.inject.Inject @HiltViewModel class SpoofViewModel @Inject constructor( - private val spoofDeviceProvider: SpoofDeviceProvider + val spoofProvider: SpoofProvider, + @ApplicationContext private val context: Context ): ViewModel() { - private val _availableDevices: MutableStateFlow> = MutableStateFlow(emptyList()) + val defaultLocale: Locale = Locale.getDefault() + val defaultProperties = NativeDeviceInfoProvider.getNativeDeviceProperties(context) + + private var currentDevice = spoofProvider.deviceProperties.getProperty("UserReadableName") + private var currentLocale = spoofProvider.locale + + private val _availableLocales: MutableStateFlow> = MutableStateFlow( + spoofProvider.availableSpoofLocales + ) + val availableLocales = _availableLocales.asStateFlow() + + private val _availableDevices: MutableStateFlow> = MutableStateFlow( + spoofProvider.availableSpoofDeviceProperties + ) val availableDevices = _availableDevices.asStateFlow() - fun fetchAvailableDevices() { - viewModelScope.launch(Dispatchers.IO) { - _availableDevices.value = spoofDeviceProvider.availableDevice + fun isDeviceSelected(properties: Properties): Boolean { + return currentDevice == properties.getProperty("UserReadableName") + } + + fun onDeviceSelected(properties: Properties) { + currentDevice = properties.getProperty("UserReadableName") + + if (currentDevice == defaultProperties.getProperty("UserReadableName")) { + spoofProvider.removeSpoofDeviceProperties() + } else { + spoofProvider.setSpoofDeviceProperties(properties) + } + } + + fun isLocaleSelected(locale: Locale): Boolean { + return currentLocale == locale + } + + fun onLocaleSelected(locale: Locale) { + currentLocale = locale + + if (currentLocale == defaultLocale) { + spoofProvider.removeSpoofLocale() + } else { + spoofProvider.setSpoofLocale(locale) } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1990bb5e9..1cebcc869 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -467,4 +467,8 @@ Authentication required Please log in to your Google Play account to unarchive the app! + + + Default + Available