forked from PeterCxy/OpenEUICC
Compare commits
No commits in common. "3e0a2f591ae5e7cef07c68a6198f028104f14133" and "e9f4d3d1f9d4557628bd9946ffb7f72101dca6bd" have entirely different histories.
3e0a2f591a
...
e9f4d3d1f9
15 changed files with 16 additions and 306 deletions
|
@ -32,10 +32,6 @@
|
||||||
android:name="im.angry.openeuicc.ui.LogsActivity"
|
android:name="im.angry.openeuicc.ui.LogsActivity"
|
||||||
android:label="@string/pref_advanced_logs" />
|
android:label="@string/pref_advanced_logs" />
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name="im.angry.openeuicc.ui.wizard.DownloadWizardActivity"
|
|
||||||
android:label="@string/download_wizard" />
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="com.journeyapps.barcodescanner.CaptureActivity"
|
android:name="com.journeyapps.barcodescanner.CaptureActivity"
|
||||||
android:screenOrientation="fullSensor"
|
android:screenOrientation="fullSensor"
|
||||||
|
|
|
@ -42,8 +42,7 @@ open class DefaultEuiccChannelFactory(protected val context: Context) : EuiccCha
|
||||||
port,
|
port,
|
||||||
context.preferenceRepository.verboseLoggingFlow
|
context.preferenceRepository.verboseLoggingFlow
|
||||||
),
|
),
|
||||||
context.preferenceRepository.verboseLoggingFlow,
|
context.preferenceRepository.verboseLoggingFlow
|
||||||
context.preferenceRepository.ignoreTLSCertificate,
|
|
||||||
).also {
|
).also {
|
||||||
Log.i(DefaultEuiccChannelManager.TAG, "Is OMAPI channel, setting MSS to 60")
|
Log.i(DefaultEuiccChannelManager.TAG, "Is OMAPI channel, setting MSS to 60")
|
||||||
it.lpa.setEs10xMss(60)
|
it.lpa.setEs10xMss(60)
|
||||||
|
@ -73,8 +72,7 @@ open class DefaultEuiccChannelFactory(protected val context: Context) : EuiccCha
|
||||||
bulkOut,
|
bulkOut,
|
||||||
context.preferenceRepository.verboseLoggingFlow
|
context.preferenceRepository.verboseLoggingFlow
|
||||||
),
|
),
|
||||||
context.preferenceRepository.verboseLoggingFlow,
|
context.preferenceRepository.verboseLoggingFlow
|
||||||
context.preferenceRepository.ignoreTLSCertificate,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,15 +11,14 @@ class EuiccChannelImpl(
|
||||||
override val type: String,
|
override val type: String,
|
||||||
override val port: UiccPortInfoCompat,
|
override val port: UiccPortInfoCompat,
|
||||||
apduInterface: ApduInterface,
|
apduInterface: ApduInterface,
|
||||||
verboseLoggingFlow: Flow<Boolean>,
|
verboseLoggingFlow: Flow<Boolean>
|
||||||
ignoreTLSCertificate: Flow<Boolean>
|
|
||||||
) : EuiccChannel {
|
) : EuiccChannel {
|
||||||
override val slotId = port.card.physicalSlotIndex
|
override val slotId = port.card.physicalSlotIndex
|
||||||
override val logicalSlotId = port.logicalSlotIndex
|
override val logicalSlotId = port.logicalSlotIndex
|
||||||
override val portId = port.portIndex
|
override val portId = port.portIndex
|
||||||
|
|
||||||
override val lpa: LocalProfileAssistant =
|
override val lpa: LocalProfileAssistant =
|
||||||
LocalProfileAssistantImpl(apduInterface, HttpInterfaceImpl(verboseLoggingFlow, ignoreTLSCertificate))
|
LocalProfileAssistantImpl(apduInterface, HttpInterfaceImpl(verboseLoggingFlow))
|
||||||
|
|
||||||
override val valid: Boolean
|
override val valid: Boolean
|
||||||
get() = lpa.valid
|
get() = lpa.valid
|
||||||
|
|
|
@ -31,12 +31,10 @@ import net.typeblog.lpac_jni.LocalProfileInfo
|
||||||
import im.angry.openeuicc.common.R
|
import im.angry.openeuicc.common.R
|
||||||
import im.angry.openeuicc.service.EuiccChannelManagerService
|
import im.angry.openeuicc.service.EuiccChannelManagerService
|
||||||
import im.angry.openeuicc.service.EuiccChannelManagerService.Companion.waitDone
|
import im.angry.openeuicc.service.EuiccChannelManagerService.Companion.waitDone
|
||||||
import im.angry.openeuicc.ui.wizard.DownloadWizardActivity
|
|
||||||
import im.angry.openeuicc.util.*
|
import im.angry.openeuicc.util.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.TimeoutCancellationException
|
import kotlinx.coroutines.TimeoutCancellationException
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.first
|
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
@ -107,14 +105,8 @@ open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener,
|
||||||
LinearLayoutManager(view.context, LinearLayoutManager.VERTICAL, false)
|
LinearLayoutManager(view.context, LinearLayoutManager.VERTICAL, false)
|
||||||
|
|
||||||
fab.setOnClickListener {
|
fab.setOnClickListener {
|
||||||
lifecycleScope.launch {
|
ProfileDownloadFragment.newInstance(slotId, portId)
|
||||||
if (preferenceRepository.experimentalDownloadWizardFlow.first()) {
|
.show(childFragmentManager, ProfileDownloadFragment.TAG)
|
||||||
startActivity(Intent(requireContext(), DownloadWizardActivity::class.java))
|
|
||||||
} else {
|
|
||||||
ProfileDownloadFragment.newInstance(slotId, portId)
|
|
||||||
.show(childFragmentManager, ProfileDownloadFragment.TAG)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,48 +3,26 @@ package im.angry.openeuicc.ui
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Toast
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
import androidx.datastore.preferences.core.Preferences
|
import androidx.datastore.preferences.core.Preferences
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.preference.CheckBoxPreference
|
import androidx.preference.CheckBoxPreference
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceCategory
|
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import im.angry.openeuicc.common.R
|
import im.angry.openeuicc.common.R
|
||||||
import im.angry.openeuicc.util.*
|
import im.angry.openeuicc.util.*
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
class SettingsFragment: PreferenceFragmentCompat() {
|
class SettingsFragment: PreferenceFragmentCompat() {
|
||||||
private lateinit var developerPref: PreferenceCategory
|
|
||||||
|
|
||||||
// Hidden developer options switch
|
|
||||||
private var numClicks = 0
|
|
||||||
private var lastClickTimestamp = -1L
|
|
||||||
private var lastToast: Toast? = null
|
|
||||||
|
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
setPreferencesFromResource(R.xml.pref_settings, rootKey)
|
setPreferencesFromResource(R.xml.pref_settings, rootKey)
|
||||||
|
|
||||||
developerPref = findPreference("pref_developer")!!
|
|
||||||
|
|
||||||
// Show / hide developer preference based on whether it is enabled
|
|
||||||
lifecycleScope.launch {
|
|
||||||
preferenceRepository.developerOptionsEnabledFlow.onEach {
|
|
||||||
developerPref.isVisible = it
|
|
||||||
}.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
findPreference<Preference>("pref_info_app_version")
|
findPreference<Preference>("pref_info_app_version")
|
||||||
?.apply {
|
?.summary = requireContext().selfAppVersion
|
||||||
summary = requireContext().selfAppVersion
|
|
||||||
|
|
||||||
// Enable developer options when this is clicked for 7 times
|
|
||||||
setOnPreferenceClickListener(this@SettingsFragment::onAppVersionClicked)
|
|
||||||
}
|
|
||||||
|
|
||||||
findPreference<Preference>("pref_info_source_code")
|
findPreference<Preference>("pref_info_source_code")
|
||||||
?.setOnPreferenceClickListener {
|
?.setOnPreferenceClickListener {
|
||||||
|
@ -72,12 +50,6 @@ class SettingsFragment: PreferenceFragmentCompat() {
|
||||||
|
|
||||||
findPreference<CheckBoxPreference>("pref_advanced_verbose_logging")
|
findPreference<CheckBoxPreference>("pref_advanced_verbose_logging")
|
||||||
?.bindBooleanFlow(preferenceRepository.verboseLoggingFlow, PreferenceKeys.VERBOSE_LOGGING)
|
?.bindBooleanFlow(preferenceRepository.verboseLoggingFlow, PreferenceKeys.VERBOSE_LOGGING)
|
||||||
|
|
||||||
findPreference<CheckBoxPreference>("pref_developer_experimental_download_wizard")
|
|
||||||
?.bindBooleanFlow(preferenceRepository.experimentalDownloadWizardFlow, PreferenceKeys.EXPERIMENTAL_DOWNLOAD_WIZARD)
|
|
||||||
|
|
||||||
findPreference<CheckBoxPreference>("pref_ignore_tls_certificate")
|
|
||||||
?.bindBooleanFlow(preferenceRepository.ignoreTLSCertificate, PreferenceKeys.IGNORE_TLS_CERTIFICATE)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
|
@ -85,44 +57,6 @@ class SettingsFragment: PreferenceFragmentCompat() {
|
||||||
setupRootViewInsets(requireView().requireViewById(androidx.preference.R.id.recycler_view))
|
setupRootViewInsets(requireView().requireViewById(androidx.preference.R.id.recycler_view))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
|
||||||
private fun onAppVersionClicked(pref: Preference): Boolean {
|
|
||||||
if (developerPref.isVisible) return false
|
|
||||||
val now = System.currentTimeMillis()
|
|
||||||
if (now - lastClickTimestamp >= 1000) {
|
|
||||||
numClicks = 1
|
|
||||||
} else {
|
|
||||||
numClicks++
|
|
||||||
}
|
|
||||||
lastClickTimestamp = now
|
|
||||||
|
|
||||||
if (numClicks == 7) {
|
|
||||||
lifecycleScope.launch {
|
|
||||||
preferenceRepository.updatePreference(
|
|
||||||
PreferenceKeys.DEVELOPER_OPTIONS_ENABLED,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
|
|
||||||
lastToast?.cancel()
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
R.string.developer_options_enabled,
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
} else if (numClicks > 1) {
|
|
||||||
lastToast?.cancel()
|
|
||||||
lastToast = Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
getString(R.string.developer_options_steps, 7 - numClicks),
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
)
|
|
||||||
lastToast!!.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun CheckBoxPreference.bindBooleanFlow(flow: Flow<Boolean>, key: Preferences.Key<Boolean>) {
|
private fun CheckBoxPreference.bindBooleanFlow(flow: Flow<Boolean>, key: Preferences.Key<Boolean>) {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
flow.collect { isChecked = it }
|
flow.collect { isChecked = it }
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
package im.angry.openeuicc.ui.wizard
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.ProgressBar
|
|
||||||
import androidx.activity.OnBackPressedCallback
|
|
||||||
import androidx.activity.enableEdgeToEdge
|
|
||||||
import androidx.core.view.ViewCompat
|
|
||||||
import androidx.core.view.WindowInsetsCompat
|
|
||||||
import androidx.core.view.updatePadding
|
|
||||||
import im.angry.openeuicc.common.R
|
|
||||||
import im.angry.openeuicc.ui.BaseEuiccAccessActivity
|
|
||||||
|
|
||||||
class DownloadWizardActivity: BaseEuiccAccessActivity() {
|
|
||||||
private lateinit var progressBar: ProgressBar
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
enableEdgeToEdge()
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
setContentView(R.layout.activity_download_wizard)
|
|
||||||
onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
|
|
||||||
override fun handleOnBackPressed() {
|
|
||||||
// TODO: Actually implement this
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
progressBar = requireViewById(R.id.progress)
|
|
||||||
|
|
||||||
val navigation = requireViewById<View>(R.id.download_wizard_navigation)
|
|
||||||
val origHeight = navigation.layoutParams.height
|
|
||||||
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(navigation) { v, insets ->
|
|
||||||
val bars = insets.getInsets(
|
|
||||||
WindowInsetsCompat.Type.systemBars()
|
|
||||||
or WindowInsetsCompat.Type.displayCutout()
|
|
||||||
)
|
|
||||||
v.updatePadding(bars.left, 0, bars.right, bars.bottom)
|
|
||||||
val newParams = navigation.layoutParams
|
|
||||||
newParams.height = origHeight + bars.bottom
|
|
||||||
navigation.layoutParams = newParams
|
|
||||||
WindowInsetsCompat.CONSUMED
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onInit() {
|
|
||||||
progressBar.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -20,19 +20,11 @@ val Fragment.preferenceRepository: PreferenceRepository
|
||||||
get() = requireContext().preferenceRepository
|
get() = requireContext().preferenceRepository
|
||||||
|
|
||||||
object PreferenceKeys {
|
object PreferenceKeys {
|
||||||
// ---- Profile Notifications ----
|
|
||||||
val NOTIFICATION_DOWNLOAD = booleanPreferencesKey("notification_download")
|
val NOTIFICATION_DOWNLOAD = booleanPreferencesKey("notification_download")
|
||||||
val NOTIFICATION_DELETE = booleanPreferencesKey("notification_delete")
|
val NOTIFICATION_DELETE = booleanPreferencesKey("notification_delete")
|
||||||
val NOTIFICATION_SWITCH = booleanPreferencesKey("notification_switch")
|
val NOTIFICATION_SWITCH = booleanPreferencesKey("notification_switch")
|
||||||
|
|
||||||
// ---- Advanced ----
|
|
||||||
val DISABLE_SAFEGUARD_REMOVABLE_ESIM = booleanPreferencesKey("disable_safeguard_removable_esim")
|
val DISABLE_SAFEGUARD_REMOVABLE_ESIM = booleanPreferencesKey("disable_safeguard_removable_esim")
|
||||||
val VERBOSE_LOGGING = booleanPreferencesKey("verbose_logging")
|
val VERBOSE_LOGGING = booleanPreferencesKey("verbose_logging")
|
||||||
|
|
||||||
// ---- Developer Options ----
|
|
||||||
val DEVELOPER_OPTIONS_ENABLED = booleanPreferencesKey("developer_options_enabled")
|
|
||||||
val EXPERIMENTAL_DOWNLOAD_WIZARD = booleanPreferencesKey("experimental_download_wizard")
|
|
||||||
val IGNORE_TLS_CERTIFICATE = booleanPreferencesKey("ignore_tls_certificate")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class PreferenceRepository(context: Context) {
|
class PreferenceRepository(context: Context) {
|
||||||
|
@ -56,16 +48,6 @@ class PreferenceRepository(context: Context) {
|
||||||
val verboseLoggingFlow: Flow<Boolean> =
|
val verboseLoggingFlow: Flow<Boolean> =
|
||||||
dataStore.data.map { it[PreferenceKeys.VERBOSE_LOGGING] ?: false }
|
dataStore.data.map { it[PreferenceKeys.VERBOSE_LOGGING] ?: false }
|
||||||
|
|
||||||
// ---- Developer Options ----
|
|
||||||
val developerOptionsEnabledFlow: Flow<Boolean> =
|
|
||||||
dataStore.data.map { it[PreferenceKeys.DEVELOPER_OPTIONS_ENABLED] ?: false }
|
|
||||||
|
|
||||||
val experimentalDownloadWizardFlow: Flow<Boolean> =
|
|
||||||
dataStore.data.map { it[PreferenceKeys.EXPERIMENTAL_DOWNLOAD_WIZARD] ?: false }
|
|
||||||
|
|
||||||
val ignoreTLSCertificate: Flow<Boolean> =
|
|
||||||
dataStore.data.map { it[PreferenceKeys.IGNORE_TLS_CERTIFICATE] ?: false }
|
|
||||||
|
|
||||||
suspend fun <T> updatePreference(key: Preferences.Key<T>, value: T) {
|
suspend fun <T> updatePreference(key: Preferences.Key<T>, value: T) {
|
||||||
dataStore.edit {
|
dataStore.edit {
|
||||||
it[key] = value
|
it[key] = value
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
|
||||||
|
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M15.41,7.41L14,6l-6,6 6,6 1.41,-1.41L10.83,12z"/>
|
|
||||||
|
|
||||||
</vector>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
|
||||||
|
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z"/>
|
|
||||||
|
|
||||||
</vector>
|
|
|
@ -1,65 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/guideline"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:visibility="invisible"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/download_wizard_navigation"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/progress"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:indeterminate="true"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/guideline"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/download_wizard_navigation"
|
|
||||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:id="@+id/download_wizard_navigation"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:background="?attr/colorSurfaceContainer"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent">
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/download_wizard_back"
|
|
||||||
android:text="@string/download_wizard_back"
|
|
||||||
android:background="?attr/selectableItemBackground"
|
|
||||||
android:textColor="?attr/colorPrimary"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
app:icon="@drawable/ic_chevron_left"
|
|
||||||
app:iconGravity="start"
|
|
||||||
app:iconTint="?attr/colorPrimary"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/download_wizard_next"
|
|
||||||
android:text="@string/download_wizard_next"
|
|
||||||
android:background="?attr/selectableItemBackground"
|
|
||||||
android:textColor="?attr/colorPrimary"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
app:icon="@drawable/ic_chevron_right"
|
|
||||||
app:iconGravity="end"
|
|
||||||
app:iconTint="?attr/colorPrimary"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
|
@ -58,10 +58,6 @@
|
||||||
<string name="profile_download_low_nvram_title">This download may fail</string>
|
<string name="profile_download_low_nvram_title">This download may fail</string>
|
||||||
<string name="profile_download_low_nvram_message">This download may fail due to low remaining capacity.</string>
|
<string name="profile_download_low_nvram_message">This download may fail due to low remaining capacity.</string>
|
||||||
|
|
||||||
<string name="download_wizard">Download Wizard</string>
|
|
||||||
<string name="download_wizard_back">Back</string>
|
|
||||||
<string name="download_wizard_next">Next</string>
|
|
||||||
|
|
||||||
<string name="profile_rename_new_name">New nickname</string>
|
<string name="profile_rename_new_name">New nickname</string>
|
||||||
|
|
||||||
<string name="profile_delete_confirm">Are you sure you want to delete the profile %s? This operation is irreversible.</string>
|
<string name="profile_delete_confirm">Are you sure you want to delete the profile %s? This operation is irreversible.</string>
|
||||||
|
@ -101,9 +97,6 @@
|
||||||
<string name="logs_save">Save</string>
|
<string name="logs_save">Save</string>
|
||||||
<string name="logs_filename_template">Logs at %s</string>
|
<string name="logs_filename_template">Logs at %s</string>
|
||||||
|
|
||||||
<string name="developer_options_steps">You are %d steps away from being a developer.</string>
|
|
||||||
<string name="developer_options_enabled">You are now a developer!</string>
|
|
||||||
|
|
||||||
<string name="pref_settings">Settings</string>
|
<string name="pref_settings">Settings</string>
|
||||||
<string name="pref_notifications">Notifications</string>
|
<string name="pref_notifications">Notifications</string>
|
||||||
<string name="pref_notifications_desc">eSIM profile operations send notifications to the carrier. Fine-tune this behavior as needed here.</string>
|
<string name="pref_notifications_desc">eSIM profile operations send notifications to the carrier. Fine-tune this behavior as needed here.</string>
|
||||||
|
@ -120,11 +113,6 @@
|
||||||
<string name="pref_advanced_verbose_logging_desc">Enable verbose logs, which may contain sensitive information. Only share your logs with someone you trust after turning this on.</string>
|
<string name="pref_advanced_verbose_logging_desc">Enable verbose logs, which may contain sensitive information. Only share your logs with someone you trust after turning this on.</string>
|
||||||
<string name="pref_advanced_logs">Logs</string>
|
<string name="pref_advanced_logs">Logs</string>
|
||||||
<string name="pref_advanced_logs_desc">View recent debug logs of the application</string>
|
<string name="pref_advanced_logs_desc">View recent debug logs of the application</string>
|
||||||
<string name="pref_developer">Developer Options</string>
|
|
||||||
<string name="pref_developer_experimental_download_wizard">Experimental Download Wizard</string>
|
|
||||||
<string name="pref_developer_experimental_download_wizard_desc">Enable the experimental new download wizard. Note that it is not fully working yet.</string>
|
|
||||||
<string name="pref_developer_ignore_tls_certificate">Do not check SM-DP+ TLS certificate</string>
|
|
||||||
<string name="pref_developer_ignore_tls_certificate_desc">Do not check SM-DP+ TLS certificate, allow any RSP</string>
|
|
||||||
<string name="pref_info">Info</string>
|
<string name="pref_info">Info</string>
|
||||||
<string name="pref_info_app_version">App Version</string>
|
<string name="pref_info_app_version">App Version</string>
|
||||||
<string name="pref_info_source_code">Source Code</string>
|
<string name="pref_info_source_code">Source Code</string>
|
||||||
|
|
|
@ -41,26 +41,6 @@
|
||||||
app:iconSpaceReserved="false"
|
app:iconSpaceReserved="false"
|
||||||
app:title="@string/pref_advanced_logs"
|
app:title="@string/pref_advanced_logs"
|
||||||
app:summary="@string/pref_advanced_logs_desc" />
|
app:summary="@string/pref_advanced_logs_desc" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
|
||||||
|
|
||||||
<PreferenceCategory
|
|
||||||
app:key="pref_developer"
|
|
||||||
app:title="@string/pref_developer"
|
|
||||||
app:iconSpaceReserved="false">
|
|
||||||
|
|
||||||
<CheckBoxPreference
|
|
||||||
app:key="pref_developer_experimental_download_wizard"
|
|
||||||
app:iconSpaceReserved="false"
|
|
||||||
app:title="@string/pref_developer_experimental_download_wizard"
|
|
||||||
app:summary="@string/pref_developer_experimental_download_wizard_desc" />
|
|
||||||
|
|
||||||
<CheckBoxPreference
|
|
||||||
app:iconSpaceReserved="false"
|
|
||||||
app:key="pref_developer_ignore_tls_certificate"
|
|
||||||
app:summary="@string/pref_developer_ignore_tls_certificate_desc"
|
|
||||||
app:title="@string/pref_developer_ignore_tls_certificate" />
|
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
|
|
|
@ -35,8 +35,7 @@ class PrivilegedEuiccChannelFactory(context: Context) : DefaultEuiccChannelFacto
|
||||||
tm,
|
tm,
|
||||||
context.preferenceRepository.verboseLoggingFlow
|
context.preferenceRepository.verboseLoggingFlow
|
||||||
),
|
),
|
||||||
context.preferenceRepository.verboseLoggingFlow,
|
context.preferenceRepository.verboseLoggingFlow
|
||||||
context.preferenceRepository.ignoreTLSCertificate,
|
|
||||||
)
|
)
|
||||||
} catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
// Failed
|
// Failed
|
||||||
|
|
|
@ -9,14 +9,10 @@ import java.net.URL
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
import javax.net.ssl.HttpsURLConnection
|
import javax.net.ssl.HttpsURLConnection
|
||||||
import javax.net.ssl.SSLContext
|
import javax.net.ssl.SSLContext
|
||||||
import javax.net.ssl.SSLSocketFactory
|
|
||||||
import javax.net.ssl.TrustManager
|
import javax.net.ssl.TrustManager
|
||||||
import javax.net.ssl.TrustManagerFactory
|
import javax.net.ssl.TrustManagerFactory
|
||||||
|
|
||||||
class HttpInterfaceImpl(
|
class HttpInterfaceImpl(private val verboseLoggingFlow: Flow<Boolean>) : HttpInterface {
|
||||||
private val verboseLoggingFlow: Flow<Boolean>,
|
|
||||||
private val ignoreTLSCertificate: Flow<Boolean>
|
|
||||||
) : HttpInterface {
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "HttpInterfaceImpl"
|
private const val TAG = "HttpInterfaceImpl"
|
||||||
}
|
}
|
||||||
|
@ -40,6 +36,9 @@ class HttpInterfaceImpl(
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
val sslContext = SSLContext.getInstance("TLS")
|
||||||
|
sslContext.init(null, trustManagers, SecureRandom())
|
||||||
|
|
||||||
val conn = parsedUrl.openConnection() as HttpsURLConnection
|
val conn = parsedUrl.openConnection() as HttpsURLConnection
|
||||||
conn.connectTimeout = 2000
|
conn.connectTimeout = 2000
|
||||||
|
|
||||||
|
@ -48,7 +47,7 @@ class HttpInterfaceImpl(
|
||||||
conn.readTimeout = 1000
|
conn.readTimeout = 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
conn.sslSocketFactory = getSocketFactory()
|
conn.sslSocketFactory = sslContext.socketFactory
|
||||||
conn.requestMethod = "POST"
|
conn.requestMethod = "POST"
|
||||||
conn.doInput = true
|
conn.doInput = true
|
||||||
conn.doOutput = true
|
conn.doOutput = true
|
||||||
|
@ -80,18 +79,6 @@ class HttpInterfaceImpl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSocketFactory(): SSLSocketFactory {
|
|
||||||
val trustManagers =
|
|
||||||
if (runBlocking { ignoreTLSCertificate.first() }) {
|
|
||||||
arrayOf(IgnoreTLSCertificate())
|
|
||||||
} else {
|
|
||||||
this.trustManagers
|
|
||||||
}
|
|
||||||
val sslContext = SSLContext.getInstance("TLS")
|
|
||||||
sslContext.init(null, trustManagers, SecureRandom())
|
|
||||||
return sslContext.socketFactory
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun usePublicKeyIds(pkids: Array<String>) {
|
override fun usePublicKeyIds(pkids: Array<String>) {
|
||||||
val trustManagerFactory = TrustManagerFactory.getInstance("PKIX").apply {
|
val trustManagerFactory = TrustManagerFactory.getInstance("PKIX").apply {
|
||||||
init(keyIdToKeystore(pkids))
|
init(keyIdToKeystore(pkids))
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
package net.typeblog.lpac_jni.impl
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import java.security.cert.X509Certificate
|
|
||||||
import javax.net.ssl.X509TrustManager
|
|
||||||
|
|
||||||
@SuppressLint("CustomX509TrustManager")
|
|
||||||
class IgnoreTLSCertificate : X509TrustManager {
|
|
||||||
@SuppressLint("TrustAllX509TrustManager")
|
|
||||||
override fun checkClientTrusted(p0: Array<out X509Certificate>?, p1: String?) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("TrustAllX509TrustManager")
|
|
||||||
override fun checkServerTrusted(p0: Array<out X509Certificate>?, p1: String?) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getAcceptedIssuers(): Array<X509Certificate> {
|
|
||||||
return emptyArray()
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue