style: reformat all files #268

Merged
PeterCxy merged 4 commits from septs/OpenEUICC:editorconfig into master 2025-12-02 04:13:19 +01:00
180 changed files with 2040 additions and 1362 deletions

22
.editorconfig Normal file
View file

@ -0,0 +1,22 @@
root = true
[*]
charset = utf-8
indent_size = 2
indent_style = space
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
max_line_length = 120
[*.{kt,java}]
indent_size = 4
[*.gradle.kts]
indent_size = 4
[*.xml]
indent_size = 4
[.idea/**/*.xml]
indent_size = 2

View file

@ -1,3 +1,5 @@
name: Build Debug APKs
on:
push:
branches:
@ -7,7 +9,7 @@ on:
jobs:
build-debug:
runs-on: [docker, android-app-certs]
runs-on: [ docker, android-app-certs ]
container:
volumes:
- android-app-keystore:/keystore

View file

@ -1,10 +1,12 @@
name: Build Release
on:
push:
tags: '*'
jobs:
release:
runs-on: [docker, android-app-certs]
runs-on: [ docker, android-app-certs ]
container:
volumes:
- android-app-keystore:/keystore

View file

@ -120,4 +120,4 @@
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>
</component>

View file

@ -3,4 +3,4 @@
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>
</component>

2
.idea/compiler.xml generated
View file

@ -3,4 +3,4 @@
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="1.7" />
</component>
</project>
</project>

2
.idea/kotlinc.xml generated
View file

@ -3,4 +3,4 @@
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.9.24" />
</component>
</project>
</project>

2
.idea/migrations.xml generated
View file

@ -7,4 +7,4 @@
</set>
</option>
</component>
</project>
</project>

2
.idea/vcs.xml generated
View file

@ -4,4 +4,4 @@
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/libs/lpac-jni/src/main/jni/lpac" vcs="Git" />
</component>
</project>
</project>

View file

@ -5,7 +5,7 @@ A fully free and open-source Local Profile Assistant implementation for Android
There are two variants of this project, OpenEUICC and EasyEUICC:
| | OpenEUICC | EasyEUICC |
| :---------------------------- | :-----------------------------: | :-----------------: |
|:------------------------------|:-------------------------------:|:-------------------:|
| Privileged | Must be installed as system app | No |
| Internal eSIM | Supported | Unsupported |
| External eSIM [^1] | Supported | Supported |
@ -22,24 +22,31 @@ Some side notes:
1. When privileged, OpenEUICC supports any eUICC chip that implements the [SGP.22] standard, internal or external.
However, there is **no guarantee** that external (removable) eSIMs actually follow the standard.
Please **DO NOT** submit bug reports for non-functioning removable eSIMs.
They are **NOT** officially supported unless they also support / are supported by EasyEUICC, the unprivileged variant.
They are **NOT** officially supported unless they also support / are supported by EasyEUICC, the unprivileged
variant.
2. Both variants support accessing eUICC chips through USB CCID readers,
regardless of whether the chip contains the correct ARA-M hash to allow for unprivileged access.
However, only `T=0` readers that use the standard [USB CCID protocol][usb-ccid] are supported.
3. Prebuilt release-mode EasyEUICC apks can be downloaded [here][releases].
For OpenEUICC, no official release is currently provided and only debug mode APKs and Magisk modules can be found in the [CI page][actions].
For OpenEUICC, no official release is currently provided and only debug mode APKs and Magisk modules can be found in
the [CI page][actions].
4. For removable eSIM chip vendors: to have your chip supported by official builds of EasyEUICC when inserted,
include the ARA-M hash `2A2FA878BC7C3354C2CF82935A5945A3EDAE4AFA`.
[sgp.22]: https://www.gsma.com/solutions-and-impact/technologies/esim/gsma_resources/sgp-22-v2-2-2/ "SGP.22 v2.2.2"
[usb-ccid]: https://en.wikipedia.org/wiki/CCID_%28protocol%29 "USB CCID Protocol"
[releases]: https://gitea.angry.im/PeterCxy/OpenEUICC/releases "EasyEUICC Releases"
[actions]: https://gitea.angry.im/PeterCxy/OpenEUICC/actions "OpenEUICC Actions"
**This project is Free Software licensed under GNU GPL v3, WITHOUT the "or later" clause.**
Any modification and derivative work **MUST** be released under the SAME license, which means, at the very least, that the source code **MUST** be available upon request.
Any modification and derivative work **MUST** be released under the SAME license, which means, at the very least, that
the source code **MUST** be available upon request.
**If you are releasing a modification of this app, you are kindly asked to make changes to at least the app name and package name.**
**If you are releasing a modification of this app, you are kindly asked to make changes to at least the app name and
package name.**
# Building (Gradle)
@ -78,26 +85,39 @@ For EasyEUICC:
There are two ways to include OpenEUICC in your AOSP-based system image:
1. Include this project and its [dependencies](https://gitea.angry.im/PeterCxy/android_prebuilts_openeuicc-deps) inside the AOSP tree.
- If inclusion in `manifest.xml` is required, remember to set the `sync-s` option to clone submodules.
- The module name is `OpenEUICC`. You can include it in `PRODUCT_PACKAGES`, or simply build it standalone using `mm`.
- Compilation of this project is **only** tested against the latest AOSP release version. The app itself should be compatible with older AOSP versions, but the source may not compile against an older AOSP source tree.
2. If compilation against AOSP source tree is not possible, consider [building with gradle](#building-gradle) and import the apk as a prebuilt.
- No official `Android.bp` is provided for this case but it should be straightforward to write.
- You might want to include [`privapp_whitelist_im.angry.openeuicc.xml`] as well.
1. Include this project and its [dependencies](https://gitea.angry.im/PeterCxy/android_prebuilts_openeuicc-deps) inside
the AOSP tree.
- If inclusion in `manifest.xml` is required, remember to set the `sync-s` option to clone submodules.
- The module name is `OpenEUICC`. You can include it in `PRODUCT_PACKAGES`, or simply build it standalone using `mm`.
- Compilation of this project is **only** tested against the latest AOSP release version. The app itself should be
compatible with older AOSP versions, but the source may not compile against an older AOSP source tree.
2. If compilation against AOSP source tree is not possible, consider [building with gradle](#building-gradle) and import
the apk as a prebuilt.
- No official `Android.bp` is provided for this case but it should be straightforward to write.
- You might want to include [`privapp_whitelist_im.angry.openeuicc.xml`] as well.
[`privapp_whitelist_im.angry.openeuicc.xml`]: privapp_whitelist_im.angry.openeuicc.xml "OpenEUICC Privapp Whitelist"
# FAQs
- Q: Do you provide prebuilt binaries for OpenEUICC? \
A: Debug-mode APKs and Magisk modules are available continuously as an artifact of the [Actions] CI used by this project. However, these debug-mode APKs are **not** intended for inclusion inside system images, nor are they supported by the developer in any sense. If you are a custom ROM developer, either include the entire OpenEUICC repository in your AOSP source tree, or generate an APK using `gradle` and import that as a prebuilt system app. Note that you might want [`privapp_whitelist_im.angry.openeuicc.xml`] as well.
A: Debug-mode APKs and Magisk modules are available continuously as an artifact of the [Actions] CI used by this
project. However, these debug-mode APKs are **not** intended for inclusion inside system images, nor are they
supported by the developer in any sense. If you are a custom ROM developer, either include the entire OpenEUICC
repository in your AOSP source tree, or generate an APK using `gradle` and import that as a prebuilt system app. Note
that you might want [`privapp_whitelist_im.angry.openeuicc.xml`] as well.
- Q: Can EasyEUICC manage my phone's internal eSIM? \
A: No. For EasyEUICC to work, the eSIM chip MUST proactively grant access via its ARA-M field.
- Q: Removable eSIMs? Are they a joke? \
A: No, even though the name "removable embedded SIM" can sound like an oxymoron. In fact, there can be many advantages to these chips compared to fully embedded ones. For example, the ability to transfer eSIM profiles without carrier support or approval, or the ability to use eSIM on devices that do not and may never get the support, such as Wi-Fi hotspots.
A: No, even though the name "removable embedded SIM" can sound like an oxymoron. In fact, there can be many advantages
to these chips compared to fully embedded ones. For example, the ability to transfer eSIM profiles without carrier
support or approval, or the ability to use eSIM on devices that do not and may never get the support, such as Wi-Fi
hotspots.
# Copyright

View file

@ -1,13 +1,11 @@
package im.angry.openeuicc.common
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
@ -21,4 +19,4 @@ class ExampleInstrumentedTest {
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("im.angry.openeuicc.common.test", appContext.packageName)
}
}
}

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="im.angry.openeuicc.common">
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
@ -33,8 +33,8 @@
android:label="@string/isdr_aid_list" />
<activity
android:exported="true"
android:name="im.angry.openeuicc.ui.wizard.DownloadWizardActivity"
android:exported="true"
android:label="@string/download_wizard">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@ -46,14 +46,16 @@
<!-- for example: "LPA:1$..." -->
<!-- refs: https://www.iana.org/assignments/uri-schemes/prov/lpa -->
<data android:scheme="lpa" />
<data android:scheme="LPA" tools:ignore="AppLinkUrlError" />
<data
android:scheme="LPA"
tools:ignore="AppLinkUrlError" />
<data android:sspPrefix="1$" />
</intent-filter>
</activity>
<activity-alias
android:exported="true"
android:name="im.angry.openeuicc.ui.DirectProfileDownloadActivity"
android:exported="true"
android:targetActivity="im.angry.openeuicc.ui.wizard.DownloadWizardActivity" />
<activity
@ -63,7 +65,7 @@
<service
android:name="im.angry.openeuicc.service.EuiccChannelManagerService"
android:foregroundServiceType="shortService"
android:exported="false" />
android:exported="false"
android:foregroundServiceType="shortService" />
</application>
</manifest>

View file

@ -6,8 +6,12 @@ import android.util.Log
import im.angry.openeuicc.common.R
import im.angry.openeuicc.core.usb.UsbApduInterface
import im.angry.openeuicc.core.usb.UsbCcidContext
import im.angry.openeuicc.util.*
import java.lang.IllegalArgumentException
import im.angry.openeuicc.util.FakeUiccCardInfoCompat
import im.angry.openeuicc.util.FakeUiccPortInfoCompat
import im.angry.openeuicc.util.UiccPortInfoCompat
import im.angry.openeuicc.util.connectSEService
import im.angry.openeuicc.util.encodeHex
import im.angry.openeuicc.util.preferenceRepository
open class DefaultEuiccChannelFactory(protected val context: Context) : EuiccChannelFactory {
private var seService: SEService? = null
@ -91,4 +95,4 @@ open class DefaultEuiccChannelFactory(protected val context: Context) : EuiccCha
seService?.shutdown()
seService = null
}
}
}

View file

@ -6,10 +6,16 @@ import android.hardware.usb.UsbManager
import android.telephony.SubscriptionManager
import android.util.Log
import im.angry.openeuicc.core.usb.UsbCcidContext
import im.angry.openeuicc.core.usb.smartCard
import im.angry.openeuicc.core.usb.interfaces
import im.angry.openeuicc.core.usb.smartCard
import im.angry.openeuicc.di.AppContainer
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.FakeUiccCardInfoCompat
import im.angry.openeuicc.util.UiccCardInfoCompat
import im.angry.openeuicc.util.UiccPortInfoCompat
import im.angry.openeuicc.util.VendorAidDecider
import im.angry.openeuicc.util.activeModemCountCompat
import im.angry.openeuicc.util.parseIsdrAidList
import im.angry.openeuicc.util.queryVendorAidListTransformation
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
@ -382,4 +388,4 @@ open class DefaultEuiccChannelManager(
channelCache.clear()
euiccChannelFactory.cleanup()
}
}
}

View file

@ -2,7 +2,7 @@ package im.angry.openeuicc.core
import android.os.Parcel
import android.os.Parcelable
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.UiccPortInfoCompat
import net.typeblog.lpac_jni.ApduInterface
import net.typeblog.lpac_jni.LocalProfileAssistant
@ -95,4 +95,4 @@ interface EuiccChannel {
val isdrAid: ByteArray
fun close()
}
}

View file

@ -1,12 +1,16 @@
package im.angry.openeuicc.core
import im.angry.openeuicc.core.usb.UsbCcidContext
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.UiccPortInfoCompat
// This class is here instead of inside DI because it contains a bit more logic than just
// "dumb" dependency injection.
interface EuiccChannelFactory {
suspend fun tryOpenEuiccChannel(port: UiccPortInfoCompat, isdrAid: ByteArray, seId: EuiccChannel.SecureElementId): EuiccChannel?
suspend fun tryOpenEuiccChannel(
port: UiccPortInfoCompat,
isdrAid: ByteArray,
seId: EuiccChannel.SecureElementId
): EuiccChannel?
fun tryOpenUsbEuiccChannel(
ccidCtx: UsbCcidContext,
@ -20,4 +24,4 @@ interface EuiccChannelFactory {
* re-acquired when this happens
*/
fun cleanup()
}
}

View file

@ -75,7 +75,7 @@ interface EuiccChannelManager {
*/
suspend fun findAvailablePorts(physicalSlotId: Int): List<Int>
class EuiccChannelNotFoundException: Exception("EuiccChannel not found")
class EuiccChannelNotFoundException : Exception("EuiccChannel not found")
/**
* Find a EuiccChannel by its slot and port, then run a callback with a reference to it.
@ -115,4 +115,4 @@ interface EuiccChannelManager {
suspend fun notifyEuiccProfilesChanged(logicalSlotId: Int) {
// no-op by default
}
}
}

View file

@ -1,6 +1,6 @@
package im.angry.openeuicc.core
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.UiccPortInfoCompat
import net.typeblog.lpac_jni.ApduInterface
import net.typeblog.lpac_jni.LocalProfileAssistant
@ -52,4 +52,4 @@ class EuiccChannelWrapper(orig: EuiccChannel) : EuiccChannel {
(lpa as LocalProfileAssistantWrapper).invalidateWrapper()
}
}
}
}

View file

@ -4,7 +4,9 @@ import android.se.omapi.Channel
import android.se.omapi.SEService
import android.se.omapi.Session
import android.util.Log
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.UiccPortInfoCompat
import im.angry.openeuicc.util.encodeHex
import im.angry.openeuicc.util.getUiccReaderCompat
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
@ -15,7 +17,7 @@ class OmapiApduInterface(
private val service: SEService,
private val port: UiccPortInfoCompat,
private val verboseLoggingFlow: Flow<Boolean>
): ApduInterface, ApduInterfaceAtrProvider {
) : ApduInterface, ApduInterfaceAtrProvider {
companion object {
const val TAG = "OmapiApduInterface"
}
@ -83,4 +85,4 @@ class OmapiApduInterface(
throw e
}
}
}
}

View file

@ -2,7 +2,8 @@ package im.angry.openeuicc.core.usb
import android.util.Log
import im.angry.openeuicc.core.ApduInterfaceAtrProvider
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.decodeHex
import im.angry.openeuicc.util.encodeHex
import net.typeblog.lpac_jni.ApduInterface
class UsbApduInterface(
@ -155,4 +156,4 @@ class UsbApduInterface(
return resp
}
}
}

View file

@ -4,7 +4,7 @@ import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbEndpoint
import android.os.SystemClock
import android.util.Log
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.encodeHex
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
@ -342,4 +342,4 @@ class UsbCcidTransceiver(
)
sendRaw(iccPowerCommand, 0, iccPowerCommand.size)
}
}
}

View file

@ -5,7 +5,7 @@ import android.telephony.TelephonyManager
import im.angry.openeuicc.core.EuiccChannelFactory
import im.angry.openeuicc.core.EuiccChannelManager
import im.angry.openeuicc.core.EuiccChannelManagerFactory
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.PreferenceRepository
interface AppContainer {
val telephonyManager: TelephonyManager
@ -16,4 +16,4 @@ interface AppContainer {
val uiComponentFactory: UiComponentFactory
val euiccChannelFactory: EuiccChannelFactory
val customizableTextProvider: CustomizableTextProvider
}
}

View file

@ -8,7 +8,7 @@ import im.angry.openeuicc.core.DefaultEuiccChannelManager
import im.angry.openeuicc.core.DefaultEuiccChannelManagerFactory
import im.angry.openeuicc.core.EuiccChannelManager
import im.angry.openeuicc.core.EuiccChannelManagerFactory
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.PreferenceRepository
open class DefaultAppContainer(context: Context) : AppContainer {
override val telephonyManager by lazy {
@ -42,4 +42,4 @@ open class DefaultAppContainer(context: Context) : AppContainer {
override val customizableTextProvider by lazy {
DefaultCustomizableTextProvider(context)
}
}
}

View file

@ -1,7 +1,6 @@
package im.angry.openeuicc.di
import androidx.fragment.app.Fragment
import androidx.preference.PreferenceFragmentCompat
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.ui.EuiccManagementFragment
import im.angry.openeuicc.ui.NoEuiccPlaceholderFragment
@ -18,4 +17,4 @@ open class DefaultUiComponentFactory : UiComponentFactory {
override fun createNoEuiccPlaceholderFragment(): Fragment = NoEuiccPlaceholderFragment()
override fun createSettingsFragment(): Fragment = SettingsFragment()
}
}

View file

@ -1,7 +1,6 @@
package im.angry.openeuicc.di
import androidx.fragment.app.Fragment
import androidx.preference.PreferenceFragmentCompat
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.ui.EuiccManagementFragment
@ -14,4 +13,4 @@ interface UiComponentFactory {
fun createNoEuiccPlaceholderFragment(): Fragment
fun createSettingsFragment(): Fragment
}
}

View file

@ -14,7 +14,9 @@ import androidx.lifecycle.lifecycleScope
import im.angry.openeuicc.common.R
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.core.EuiccChannelManager
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.OpenEuiccContextMarker
import im.angry.openeuicc.util.beginTrackedOperation
import im.angry.openeuicc.util.switchProfile
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.channels.BufferOverflow
@ -533,4 +535,4 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
preferenceRepository.notificationDeleteFlow.first()
}
}
}
}

View file

@ -1,7 +1,6 @@
package im.angry.openeuicc.ui
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
@ -36,7 +35,7 @@ abstract class BaseEuiccAccessActivity : AppCompatActivity() {
bindService(
Intent(this, EuiccChannelManagerService::class.java),
euiccChannelManagerServiceConnection,
Context.BIND_AUTO_CREATE
BIND_AUTO_CREATE
)
}
@ -49,4 +48,4 @@ abstract class BaseEuiccAccessActivity : AppCompatActivity() {
* When called, euiccChannelManager is guaranteed to have been initialized
*/
abstract fun onInit()
}
}

View file

@ -9,7 +9,7 @@ import androidx.fragment.app.DialogFragment
import com.google.android.material.color.DynamicColors
import im.angry.openeuicc.common.R
abstract class BaseMaterialDialogFragment: DialogFragment() {
abstract class BaseMaterialDialogFragment : DialogFragment() {
override fun onGetLayoutInflater(savedInstanceState: Bundle?): LayoutInflater {
val inflater = super.onGetLayoutInflater(savedInstanceState)
val wrappedContext = ContextThemeWrapper(requireContext(), R.style.Theme_OpenEUICC)
@ -23,4 +23,4 @@ abstract class BaseMaterialDialogFragment: DialogFragment() {
it.window?.setBackgroundDrawableResource(R.drawable.dialog_background)
}
}
}
}

View file

@ -22,7 +22,14 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import im.angry.openeuicc.common.R
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.core.EuiccChannelManager
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.EUICC_DEFAULT_ISDR_AID
import im.angry.openeuicc.util.OpenEuiccContextMarker
import im.angry.openeuicc.util.decodeHex
import im.angry.openeuicc.util.encodeHex
import im.angry.openeuicc.util.formatFreeSpace
import im.angry.openeuicc.util.setupRootViewInsets
import im.angry.openeuicc.util.setupToolbarInsets
import im.angry.openeuicc.util.tryParseEuiccVendorInfo
import kotlinx.coroutines.launch
import net.typeblog.lpac_jni.impl.PKID_GSMA_LIVE_CI
import net.typeblog.lpac_jni.impl.PKID_GSMA_TEST_CI
@ -46,7 +53,7 @@ class EuiccInfoActivity : BaseEuiccAccessActivity(), OpenEuiccContextMarker {
private var seId: EuiccChannel.SecureElementId = EuiccChannel.SecureElementId.DEFAULT
data class Item(
@StringRes
@get:StringRes
val titleResId: Int,
val content: String?,
val copiedToastResId: Int? = null,
@ -121,17 +128,11 @@ class EuiccInfoActivity : BaseEuiccAccessActivity(), OpenEuiccContextMarker {
add(Item(R.string.euicc_info_isdr_aid, channel.isdrAid.encodeHex()))
}
channel.tryParseEuiccVendorInfo()?.let { vendorInfo ->
// @formatter:off
vendorInfo.skuName?.let { add(Item(R.string.euicc_info_sku, it)) }
vendorInfo.serialNumber?.let {
add(
Item(
R.string.euicc_info_sn,
it,
copiedToastResId = R.string.toast_sn_copied
)
)
}
vendorInfo.serialNumber?.let { add(Item(R.string.euicc_info_sn, it, copiedToastResId = R.string.toast_sn_copied)) }
vendorInfo.firmwareVersion?.let { add(Item(R.string.euicc_info_fw_ver, it)) }
// @formatter:on
}
channel.lpa.euiccInfo2?.let { info ->
add(Item(R.string.euicc_info_sgp22_version, info.sgp22Version.toString()))
@ -215,4 +216,4 @@ class EuiccInfoActivity : BaseEuiccAccessActivity(), OpenEuiccContextMarker {
holder.bind(euiccInfoItems[position])
}
}
}
}

View file

@ -29,21 +29,34 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.google.android.material.floatingactionbutton.FloatingActionButton
import net.typeblog.lpac_jni.LocalProfileInfo
import im.angry.openeuicc.common.R
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.service.EuiccChannelManagerService
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.EuiccChannelFragmentMarker
import im.angry.openeuicc.util.EuiccProfilesChangedListener
import im.angry.openeuicc.util.displayName
import im.angry.openeuicc.util.enabled
import im.angry.openeuicc.util.ensureEuiccChannelManager
import im.angry.openeuicc.util.euiccChannelManager
import im.angry.openeuicc.util.euiccChannelManagerService
import im.angry.openeuicc.util.isEnabled
import im.angry.openeuicc.util.isUsb
import im.angry.openeuicc.util.newInstanceEuicc
import im.angry.openeuicc.util.operational
import im.angry.openeuicc.util.portId
import im.angry.openeuicc.util.seId
import im.angry.openeuicc.util.setupRootViewInsets
import im.angry.openeuicc.util.slotId
import im.angry.openeuicc.util.withEuiccChannel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import net.typeblog.lpac_jni.LocalProfileInfo
open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener,
EuiccChannelFragmentMarker {
@ -417,7 +430,7 @@ open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener,
// cannot cross profile class enable profile
// e.g: testing -> operational or operational -> testing
canEnable = enabledProfile == null ||
enabledProfile.profileClass == profile.profileClass
enabledProfile.profileClass == profile.profileClass
}
private fun showOptionsMenu() {
@ -529,4 +542,4 @@ open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener,
override fun getItemCount(): Int = profiles.size + footerViews.size
}
}
}

View file

@ -8,13 +8,11 @@ import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import im.angry.openeuicc.common.R
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.service.EuiccChannelManagerService.Companion.waitDone
import im.angry.openeuicc.util.EuiccChannelFragmentMarker
import im.angry.openeuicc.util.EuiccProfilesChangedListener
import im.angry.openeuicc.util.ensureEuiccChannelManager
import im.angry.openeuicc.util.euiccChannelManagerService
import im.angry.openeuicc.util.newInstanceEuicc

View file

@ -13,7 +13,11 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import im.angry.openeuicc.common.R
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.readSelfLog
import im.angry.openeuicc.util.selfAppVersion
import im.angry.openeuicc.util.setupLogSaving
import im.angry.openeuicc.util.setupRootViewInsets
import im.angry.openeuicc.util.setupToolbarInsets
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -84,10 +88,12 @@ class LogsActivity : AppCompatActivity() {
finish()
true
}
R.id.save -> {
saveLogs()
true
}
else -> super.onOptionsItemSelected(item)
}
@ -107,4 +113,4 @@ class LogsActivity : AppCompatActivity() {
scrollView.fullScroll(View.FOCUS_DOWN)
}
}
}
}

View file

@ -28,7 +28,8 @@ import com.google.android.material.tabs.TabLayoutMediator
import im.angry.openeuicc.common.R
import im.angry.openeuicc.core.EuiccChannelManager
import im.angry.openeuicc.ui.wizard.DownloadWizardActivity
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.OpenEuiccContextMarker
import im.angry.openeuicc.util.setupToolbarInsets
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.first
@ -251,4 +252,4 @@ open class MainActivity : BaseEuiccAccessActivity(), OpenEuiccContextMarker {
.build()
return listOf(downloadShortcut)
}
}
}

View file

@ -7,7 +7,7 @@ import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import im.angry.openeuicc.common.R
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.OpenEuiccContextMarker
class NoEuiccPlaceholderFragment : Fragment(), OpenEuiccContextMarker {
override fun onCreateView(
@ -20,4 +20,4 @@ class NoEuiccPlaceholderFragment : Fragment(), OpenEuiccContextMarker {
textView.text = appContainer.customizableTextProvider.noEuiccExplanation
return view
}
}
}

View file

@ -23,7 +23,10 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import im.angry.openeuicc.common.R
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.core.EuiccChannelManager
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.OpenEuiccContextMarker
import im.angry.openeuicc.util.displayName
import im.angry.openeuicc.util.setupRootViewInsets
import im.angry.openeuicc.util.setupToolbarInsets
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -271,4 +274,4 @@ class NotificationsActivity : BaseEuiccAccessActivity(), OpenEuiccContextMarker
holder.updateNotification(notifications[position])
}
}
}

View file

@ -11,7 +11,14 @@ import androidx.lifecycle.lifecycleScope
import im.angry.openeuicc.common.R
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.service.EuiccChannelManagerService.Companion.waitDone
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.EuiccChannelFragmentMarker
import im.angry.openeuicc.util.ensureEuiccChannelManager
import im.angry.openeuicc.util.euiccChannelManagerService
import im.angry.openeuicc.util.newInstanceEuicc
import im.angry.openeuicc.util.notifyEuiccProfilesChanged
import im.angry.openeuicc.util.portId
import im.angry.openeuicc.util.seId
import im.angry.openeuicc.util.slotId
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
@ -25,7 +32,7 @@ class ProfileDeleteFragment : DialogFragment(), EuiccChannelFragmentMarker {
newInstanceEuicc(ProfileDeleteFragment::class.java, slotId, portId, seId) {
putString(FIELD_ICCID, iccid)
putString(FIELD_NAME, name)
}
}
}
private val iccid by lazy {
@ -97,4 +104,4 @@ class ProfileDeleteFragment : DialogFragment(), EuiccChannelFragmentMarker {
.waitDone()
}
}
}
}

View file

@ -14,7 +14,15 @@ import com.google.android.material.textfield.TextInputLayout
import im.angry.openeuicc.common.R
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.service.EuiccChannelManagerService.Companion.waitDone
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.EuiccChannelFragmentMarker
import im.angry.openeuicc.util.ensureEuiccChannelManager
import im.angry.openeuicc.util.euiccChannelManagerService
import im.angry.openeuicc.util.newInstanceEuicc
import im.angry.openeuicc.util.notifyEuiccProfilesChanged
import im.angry.openeuicc.util.portId
import im.angry.openeuicc.util.seId
import im.angry.openeuicc.util.setWidthPercent
import im.angry.openeuicc.util.slotId
import kotlinx.coroutines.launch
import net.typeblog.lpac_jni.LocalProfileAssistant
@ -25,11 +33,13 @@ class ProfileRenameFragment : BaseMaterialDialogFragment(), EuiccChannelFragment
const val TAG = "ProfileRenameFragment"
fun newInstance(slotId: Int, portId: Int, seId: EuiccChannel.SecureElementId, iccid: String, currentName: String) =
newInstanceEuicc(ProfileRenameFragment::class.java, slotId, portId, seId) {
putString(FIELD_ICCID, iccid)
putString(FIELD_CURRENT_NAME, currentName)
}
fun newInstance(
slotId: Int, portId: Int, seId: EuiccChannel.SecureElementId,
iccid: String, currentName: String
) = newInstanceEuicc(ProfileRenameFragment::class.java, slotId, portId, seId) {
putString(FIELD_ICCID, iccid)
putString(FIELD_CURRENT_NAME, currentName)
}
}
private lateinit var toolbar: Toolbar
@ -129,4 +139,4 @@ class ProfileRenameFragment : BaseMaterialDialogFragment(), EuiccChannelFragment
}
}
}
}
}

View file

@ -6,9 +6,9 @@ import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import im.angry.openeuicc.OpenEuiccApplication
import im.angry.openeuicc.common.R
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.setupToolbarInsets
class SettingsActivity: AppCompatActivity() {
class SettingsActivity : AppCompatActivity() {
private val appContainer
get() = (application as OpenEuiccApplication).appContainer
@ -31,6 +31,7 @@ class SettingsActivity: AppCompatActivity() {
finish()
true
}
else -> super.onOptionsItemSelected(item)
}
}
}

View file

@ -13,12 +13,15 @@ import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat
import im.angry.openeuicc.common.R
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.PreferenceFlowWrapper
import im.angry.openeuicc.util.preferenceRepository
import im.angry.openeuicc.util.selfAppVersion
import im.angry.openeuicc.util.setupRootViewInsets
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
open class SettingsFragment: PreferenceFragmentCompat() {
open class SettingsFragment : PreferenceFragmentCompat() {
private lateinit var developerPref: PreferenceCategory
// Hidden developer options switch
@ -164,4 +167,4 @@ open class SettingsFragment: PreferenceFragmentCompat() {
overlayCat.parent?.removePreference(overlayCat)
}
}
}

View file

@ -22,7 +22,7 @@ import androidx.lifecycle.lifecycleScope
import im.angry.openeuicc.common.R
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.core.EuiccChannelManager
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.OpenEuiccContextMarker
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -169,4 +169,4 @@ class UsbCcidReaderFragment : Fragment(), OpenEuiccContextMarker {
permissionButton.visibility = View.GONE
}
}
}
}

View file

@ -7,10 +7,10 @@ import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceViewHolder
@Suppress("unused")
class LongSummaryPreferenceCategory: PreferenceCategory {
constructor(ctx: Context): super(ctx)
constructor(ctx: Context, attrs: AttributeSet): super(ctx, attrs)
constructor(ctx: Context, attrs: AttributeSet, defStyle: Int): super(ctx, attrs, defStyle)
class LongSummaryPreferenceCategory : PreferenceCategory {
constructor(ctx: Context) : super(ctx)
constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)
constructor(ctx: Context, attrs: AttributeSet, defStyle: Int) : super(ctx, attrs, defStyle)
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)

View file

@ -17,10 +17,10 @@ import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import im.angry.openeuicc.common.R
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.core.EuiccChannelManager
import im.angry.openeuicc.ui.BaseEuiccAccessActivity
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.LPAString
import im.angry.openeuicc.util.OpenEuiccContextMarker
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import net.typeblog.lpac_jni.LocalProfileAssistant
@ -99,8 +99,8 @@ class DownloadWizardActivity : BaseEuiccAccessActivity() {
ViewCompat.setOnApplyWindowInsetsListener(navigation) { v, insets ->
val bars = insets.getInsets(
WindowInsetsCompat.Type.systemBars()
or WindowInsetsCompat.Type.displayCutout()
or WindowInsetsCompat.Type.ime()
or WindowInsetsCompat.Type.displayCutout()
or WindowInsetsCompat.Type.ime()
)
v.updatePadding(bars.left, 0, bars.right, bars.bottom)
val newParams = navigation.layoutParams
@ -113,7 +113,7 @@ class DownloadWizardActivity : BaseEuiccAccessActivity() {
ViewCompat.setOnApplyWindowInsetsListener(fragmentRoot) { v, insets ->
val bars = insets.getInsets(
WindowInsetsCompat.Type.systemBars()
or WindowInsetsCompat.Type.displayCutout()
or WindowInsetsCompat.Type.displayCutout()
)
v.updatePadding(bars.left, bars.top, bars.right, 0)
WindowInsetsCompat.CONSUMED
@ -335,4 +335,4 @@ class DownloadWizardActivity : BaseEuiccAccessActivity() {
open fun beforeNext() {}
}
}
}

View file

@ -7,7 +7,8 @@ import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import im.angry.openeuicc.common.R
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.encodeHex
import im.angry.openeuicc.util.setupLogSaving
import org.json.JSONObject
import java.util.Date
@ -138,4 +139,4 @@ class DownloadWizardDiagnosticsFragment : DownloadWizardActivity.DownloadWizardS
ret.toString()
}
}
}

View file

@ -19,7 +19,9 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanOptions
import im.angry.openeuicc.common.R
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.LPAString
import im.angry.openeuicc.util.decodeQrFromBitmap
import im.angry.openeuicc.util.use
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -170,4 +172,4 @@ class DownloadWizardMethodSelectFragment : DownloadWizardActivity.DownloadWizard
}
}
}
}

View file

@ -14,7 +14,9 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import im.angry.openeuicc.common.R
import im.angry.openeuicc.service.EuiccChannelManagerService
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.ensureEuiccChannelManager
import im.angry.openeuicc.util.euiccChannelManager
import im.angry.openeuicc.util.euiccChannelManagerService
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@ -264,4 +266,4 @@ class DownloadWizardProgressFragment : DownloadWizardActivity.DownloadWizardStep
holder.bind(progressItems[position])
}
}
}
}

View file

@ -15,7 +15,11 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder
import im.angry.openeuicc.common.R
import im.angry.openeuicc.core.EuiccChannel
import im.angry.openeuicc.core.EuiccChannelManager
import im.angry.openeuicc.util.*
import im.angry.openeuicc.util.displayName
import im.angry.openeuicc.util.enabled
import im.angry.openeuicc.util.ensureEuiccChannelManager
import im.angry.openeuicc.util.euiccChannelManager
import im.angry.openeuicc.util.formatFreeSpace
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.flatMapConcat
import kotlinx.coroutines.flow.map
@ -223,4 +227,4 @@ class DownloadWizardSlotSelectFragment : DownloadWizardActivity.DownloadWizardSt
holder.bind(slots[position], position)
}
}
}
}

View file

@ -167,8 +167,8 @@ enum class SimplifiedErrorMessages(
private fun fromAPDUResponse(resp: ByteArray): SimplifiedErrorMessages? {
val isSuccess = resp.size >= 2 &&
resp[resp.size - 2] == 0x90.toByte() &&
resp[resp.size - 1] == 0x00.toByte()
resp[resp.size - 2] == 0x90.toByte() &&
resp[resp.size - 1] == 0x00.toByte()
if (isSuccess) return null
return CardInternalError
}

View file

@ -26,7 +26,7 @@ fun <T> newInstanceEuicc(
seId: EuiccChannel.SecureElementId,
addArguments: BundleSetter = {}
): T
where T : Fragment, T : EuiccChannelFragmentMarker =
where T : Fragment, T : EuiccChannelFragmentMarker =
clazz.getDeclaredConstructor().newInstance().apply {
arguments = Bundle()
arguments!!.putInt(FIELD_SLOT_ID, slotId)
@ -39,13 +39,13 @@ fun <T> newInstanceEuicc(
// `channel` requires that the channel actually exists in EuiccChannelManager, which is
// not always the case during operations such as switching
val <T> T.slotId: Int
where T : Fragment, T : EuiccChannelFragmentMarker
where T : Fragment, T : EuiccChannelFragmentMarker
get() = requireArguments().getInt(FIELD_SLOT_ID)
val <T> T.portId: Int
where T : Fragment, T : EuiccChannelFragmentMarker
where T : Fragment, T : EuiccChannelFragmentMarker
get() = requireArguments().getInt(FIELD_PORT_ID)
val <T> T.seId: EuiccChannel.SecureElementId
where T : Fragment, T : EuiccChannelFragmentMarker
where T : Fragment, T : EuiccChannelFragmentMarker
get() =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
requireArguments().getParcelable(
@ -57,30 +57,25 @@ val <T> T.seId: EuiccChannel.SecureElementId
requireArguments().getParcelable(FIELD_SE_ID)!!
}
val <T> T.isUsb: Boolean
where T : Fragment, T : EuiccChannelFragmentMarker
where T : Fragment, T : EuiccChannelFragmentMarker
get() = slotId == EuiccChannelManager.USB_CHANNEL_ID
private fun <T> T.requireEuiccActivity(): BaseEuiccAccessActivity
where T : Fragment, T : OpenEuiccContextMarker =
where T : Fragment, T : OpenEuiccContextMarker =
requireActivity() as BaseEuiccAccessActivity
val <T> T.euiccChannelManager: EuiccChannelManager
where T : Fragment, T : OpenEuiccContextMarker
where T : Fragment, T : OpenEuiccContextMarker
get() = requireEuiccActivity().euiccChannelManager
val <T> T.euiccChannelManagerService: EuiccChannelManagerService
where T : Fragment, T : OpenEuiccContextMarker
where T : Fragment, T : OpenEuiccContextMarker
get() = requireEuiccActivity().euiccChannelManagerService
suspend fun <T, R> T.withEuiccChannel(fn: suspend (EuiccChannel) -> R): R
where T : Fragment, T : EuiccChannelFragmentMarker {
where T : Fragment, T : EuiccChannelFragmentMarker {
ensureEuiccChannelManager()
return euiccChannelManager.withEuiccChannel(
slotId,
portId,
seId,
fn
)
return euiccChannelManager.withEuiccChannel(slotId, portId, seId, fn)
}
suspend fun <T> T.ensureEuiccChannelManager() where T : Fragment, T : OpenEuiccContextMarker =
@ -95,4 +90,4 @@ fun <T> T.notifyEuiccProfilesChanged() where T : Fragment {
interface EuiccProfilesChangedListener {
fun onEuiccProfilesChanged()
}
}

View file

@ -1,16 +1,9 @@
package im.angry.openeuicc.util
import android.content.Context
import android.os.Build
import android.se.omapi.Reader
import android.se.omapi.SEService
import android.telephony.TelephonyManager
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
val TelephonyManager.activeModemCountCompat: Int
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
@ -55,16 +48,11 @@ interface UiccPortInfoCompat {
val logicalSlotIndex: Int
}
data class FakeUiccCardInfoCompat(
override val physicalSlotIndex: Int,
): UiccCardInfoCompat {
override val ports: Collection<UiccPortInfoCompat> =
listOf(FakeUiccPortInfoCompat(this))
data class FakeUiccCardInfoCompat(override val physicalSlotIndex: Int) : UiccCardInfoCompat {
override val ports: Collection<UiccPortInfoCompat> = listOf(FakeUiccPortInfoCompat(this))
}
data class FakeUiccPortInfoCompat(
override val card: UiccCardInfoCompat
): UiccPortInfoCompat {
data class FakeUiccPortInfoCompat(override val card: UiccCardInfoCompat) : UiccPortInfoCompat {
override val portIndex: Int = 0
override val logicalSlotIndex: Int = card.physicalSlotIndex
}
}

View file

@ -47,7 +47,7 @@ fun AppCompatActivity.setupToolbarInsets() {
ViewCompat.setOnApplyWindowInsetsListener(requireViewById(R.id.toolbar)) { v, insets ->
val bars = insets.getInsets(
WindowInsetsCompat.Type.systemBars()
or WindowInsetsCompat.Type.displayCutout()
or WindowInsetsCompat.Type.displayCutout()
)
v.updateLayoutParams<ViewGroup.MarginLayoutParams> {
@ -69,7 +69,7 @@ fun setupRootViewInsets(view: ViewGroup) {
ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
val bars = insets.getInsets(
WindowInsetsCompat.Type.systemBars()
or WindowInsetsCompat.Type.displayCutout()
or WindowInsetsCompat.Type.displayCutout()
)
v.updatePadding(bars.left, v.paddingTop, bars.right, bars.bottom)
@ -121,4 +121,4 @@ fun <T : ActivityResultCaller> T.setupLogSaving(
lastFileName = getLogFileName()
launchSaveIntent.launch(lastFileName)
}
}
}

View file

@ -17,7 +17,6 @@ import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import kotlin.RuntimeException
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
@ -96,13 +95,12 @@ inline fun <T> Bitmap.use(f: (Bitmap) -> T): T =
recycle()
}
fun decodeQrFromBitmap(bmp: Bitmap): String? =
runCatching {
val pixels = IntArray(bmp.width * bmp.height)
bmp.getPixels(pixels, 0, bmp.width, 0, 0, bmp.width, bmp.height)
fun decodeQrFromBitmap(bmp: Bitmap): String? = runCatching {
val pixels = IntArray(bmp.width * bmp.height)
bmp.getPixels(pixels, 0, bmp.width, 0, 0, bmp.width, bmp.height)
val luminanceSource = RGBLuminanceSource(bmp.width, bmp.height, pixels)
val binaryBmp = BinaryBitmap(HybridBinarizer(luminanceSource))
val luminanceSource = RGBLuminanceSource(bmp.width, bmp.height, pixels)
val binaryBmp = BinaryBitmap(HybridBinarizer(luminanceSource))
QRCodeReader().decode(binaryBmp).text
}.getOrNull()
QRCodeReader().decode(binaryBmp).text
}.getOrNull()

View file

@ -1,7 +1,6 @@
package im.angry.openeuicc.util
import android.util.Log
import im.angry.openeuicc.core.ApduInterfaceAtrProvider
import im.angry.openeuicc.core.EuiccChannel
import net.typeblog.lpac_jni.Version
@ -145,4 +144,4 @@ class SIMLink : EuiccVendor {
return EuiccVendorInfo(skuName = skuName)
}
}
}

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_shortAnimTime"
android:interpolator="@android:anim/decelerate_interpolator"
android:fromXDelta="-100%"
android:interpolator="@android:anim/decelerate_interpolator"
android:toXDelta="0%" />

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_shortAnimTime"
android:interpolator="@android:anim/decelerate_interpolator"
android:fromXDelta="100%"
android:interpolator="@android:anim/decelerate_interpolator"
android:toXDelta="0%" />

View file

@ -1,6 +1,6 @@
<!-- res/anim/slide_out.xml -->
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_shortAnimTime"
android:interpolator="@android:anim/decelerate_interpolator"
android:fromXDelta="0%"
android:interpolator="@android:anim/decelerate_interpolator"
android:toXDelta="-100%" />

View file

@ -1,6 +1,6 @@
<!-- res/anim/slide_out.xml -->
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_shortAnimTime"
android:interpolator="@android:anim/decelerate_interpolator"
android:fromXDelta="0%"
android:interpolator="@android:anim/decelerate_interpolator"
android:toXDelta="100%" />

View file

@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="?attr/colorSurface"/>
<corners
android:radius="?attr/dialogCornerRadius" />
</shape>
<solid android:color="?attr/colorSurface" />
<corners android:radius="?attr/dialogCornerRadius" />
</shape>

View file

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#FFFFFF"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" />
</vector>

View file

@ -1,10 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z" />
</vector>

View file

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M16.59,7.58L10,14.17l-3.59,-3.58L5,12l5,5 8,-8zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M16.59,7.58L10,14.17l-3.59,-3.58L5,12l5,5 8,-8zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z" />
</vector>

View file

@ -1,5 +1,12 @@
<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 xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#000000"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M15.41,7.41L14,6l-6,6 6,6 1.41,-1.41L10.83,12z" />
</vector>

View file

@ -1,5 +1,12 @@
<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 xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#000000"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z" />
</vector>

View file

@ -1,5 +1,12 @@
<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="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#000000"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z" />
</vector>

View file

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M11,15h2v2h-2zM11,7h2v6h-2zM11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M11,15h2v2h-2zM11,7h2v6h-2zM11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z" />
</vector>

View file

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M22,16L22,4c0,-1.1 -0.9,-2 -2,-2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2zM11,12l2.03,2.71L16,11l4,5L8,16l3,-4zM2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6L2,6z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M22,16L22,4c0,-1.1 -0.9,-2 -2,-2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2zM11,12l2.03,2.71L16,11l4,5L8,16l3,-4zM2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6L2,6z" />
</vector>

View file

@ -1,5 +1,11 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="?attr/colorControlNormal" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,19h-2v-2h2v2zM15.07,11.25l-0.9,0.92C13.45,12.9 13,13.5 13,15h-2v-0.5c0,-1.1 0.45,-2.1 1.17,-2.83l1.24,-1.26c0.37,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,9c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,0.88 -0.36,1.68 -0.93,2.25z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:autoMirrored="true"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,19h-2v-2h2v2zM15.07,11.25l-0.9,0.92C13.45,12.9 13,13.5 13,15h-2v-0.5c0,-1.1 0.45,-2.1 1.17,-2.83l1.24,-1.26c0.37,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,9c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,0.88 -0.36,1.68 -0.93,2.25z" />
</vector>

View file

@ -1,10 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" />
</vector>

View file

@ -1,7 +1,16 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="?attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M5,5h2v3h10V5h2v6h2V5c0,-1.1 -0.9,-2 -2,-2h-4.18C14.4,1.84 13.3,1 12,1S9.6,1.84 9.18,3H5C3.9,3 3,3.9 3,5v14c0,1.1 0.9,2 2,2h5v-2H5V5zM12,3c0.55,0 1,0.45 1,1s-0.45,1 -1,1s-1,-0.45 -1,-1S11.45,3 12,3z"/>
<path android:fillColor="@android:color/white" android:pathData="M18.01,13l-1.42,1.41l1.58,1.58l-6.17,0l0,2l6.17,0l-1.58,1.59l1.42,1.41l3.99,-4z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M5,5h2v3h10V5h2v6h2V5c0,-1.1 -0.9,-2 -2,-2h-4.18C14.4,1.84 13.3,1 12,1S9.6,1.84 9.18,3H5C3.9,3 3,3.9 3,5v14c0,1.1 0.9,2 2,2h5v-2H5V5zM12,3c0.55,0 1,0.45 1,1s-0.45,1 -1,1s-1,-0.45 -1,-1S11.45,3 12,3z" />
<path
android:fillColor="@android:color/white"
android:pathData="M18.01,13l-1.42,1.41l1.58,1.58l-6.17,0l0,2l6.17,0l-1.58,1.59l1.42,1.41l3.99,-4z" />
</vector>

View file

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z" />
</vector>

View file

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M21,12.4V7l-4,-4H5C3.89,3 3,3.9 3,5v14c0,1.1 0.89,2 2,2h7.4L21,12.4zM15,15c0,1.66 -1.34,3 -3,3s-3,-1.34 -3,-3s1.34,-3 3,-3S15,13.34 15,15zM6,6h9v4H6V6zM19.99,16.25l1.77,1.77L16.77,23H15v-1.77L19.99,16.25zM23.25,16.51l-0.85,0.85l-1.77,-1.77l0.85,-0.85c0.2,-0.2 0.51,-0.2 0.71,0l1.06,1.06C23.45,16 23.45,16.32 23.25,16.51z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M21,12.4V7l-4,-4H5C3.89,3 3,3.9 3,5v14c0,1.1 0.89,2 2,2h7.4L21,12.4zM15,15c0,1.66 -1.34,3 -3,3s-3,-1.34 -3,-3s1.34,-3 3,-3S15,13.34 15,15zM6,6h9v4H6V6zM19.99,16.25l1.77,1.77L16.77,23H15v-1.77L19.99,16.25zM23.25,16.51l-0.85,0.85l-1.77,-1.77l0.85,-0.85c0.2,-0.2 0.51,-0.2 0.71,0l1.06,1.06C23.45,16 23.45,16.32 23.25,16.51z" />
</vector>

View file

@ -1,10 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M9.5,6.5v3h-3v-3H9.5M11,5H5v6h6V5L11,5zM9.5,14.5v3h-3v-3H9.5M11,13H5v6h6V13L11,13zM17.5,6.5v3h-3v-3H17.5M19,5h-6v6h6V5L19,5zM13,13h1.5v1.5H13V13zM14.5,14.5H16V16h-1.5V14.5zM16,13h1.5v1.5H16V13zM13,16h1.5v1.5H13V16zM14.5,17.5H16V19h-1.5V17.5zM16,16h1.5v1.5H16V16zM17.5,14.5H19V16h-1.5V14.5zM17.5,17.5H19V19h-1.5V17.5zM22,7h-2V4h-3V2h5V7zM22,22v-5h-2v3h-3v2H22zM2,22h5v-2H4v-3H2V22zM2,2v5h2V4h3V2H2z"/>
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M9.5,6.5v3h-3v-3H9.5M11,5H5v6h6V5L11,5zM9.5,14.5v3h-3v-3H9.5M11,13H5v6h6V13L11,13zM17.5,6.5v3h-3v-3H17.5M19,5h-6v6h6V5L19,5zM13,13h1.5v1.5H13V13zM14.5,14.5H16V16h-1.5V14.5zM16,13h1.5v1.5H16V13zM13,16h1.5v1.5H13V16zM14.5,17.5H16V19h-1.5V17.5zM16,16h1.5v1.5H16V16zM17.5,14.5H19V16h-1.5V14.5zM17.5,17.5H19V19h-1.5V17.5zM22,7h-2V4h-3V2h5V7zM22,22v-5h-2v3h-3v2H22zM2,22h5v-2H4v-3H2V22zM2,2v5h2V4h3V2H2z" />
</vector>

View file

@ -1,5 +1,12 @@
<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="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#000000"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z" />
</vector>

View file

@ -1,5 +1,12 @@
<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="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#000000"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z" />
</vector>

View file

@ -1,5 +1,12 @@
<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="M18,2h-8L4,8v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V4C20,2.9 19.1,2 18,2zM12,17l-4,-4h3V9.02L13,9v4h3L12,17z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#000000"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M18,2h-8L4,8v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V4C20,2.9 19.1,2 18,2zM12,17l-4,-4h3V9.02L13,9v4h3L12,17z" />
</vector>

View file

@ -1,5 +1,12 @@
<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="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#000000"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z" />
</vector>

View file

@ -1,5 +1,12 @@
<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="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#000000"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" />
</vector>

View file

@ -1,17 +1,17 @@
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/step_fragment_container"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/download_wizard_navigation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/guideline"
@ -25,14 +25,14 @@
<ProgressBar
android:id="@+id/progress"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:indeterminate="true"
app:layout_constraintBottom_toTopOf="@id/download_wizard_navigation"
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" />
app:layout_constraintTop_toBottomOf="@id/guideline" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/download_wizard_navigation"
@ -40,16 +40,16 @@
android:layout_height="48dp"
android:background="?attr/colorSurfaceContainer"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="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"
android:background="?attr/selectableItemBackground"
android:text="@string/download_wizard_back"
android:textColor="?attr/colorPrimary"
app:icon="@drawable/ic_chevron_left"
app:iconGravity="start"
app:iconTint="?attr/colorPrimary"
@ -58,11 +58,11 @@
<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"
android:background="?attr/selectableItemBackground"
android:text="@string/download_wizard_next"
android:textColor="?attr/colorPrimary"
app:icon="@drawable/ic_chevron_right"
app:iconGravity="end"
app:iconTint="?attr/colorPrimary"
@ -71,4 +71,4 @@
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,8 +1,8 @@
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:layout_height="match_parent">
<include layout="@layout/toolbar_activity" />
@ -10,10 +10,10 @@
android:id="@+id/swipe_refresh"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
@ -22,4 +22,4 @@
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
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">
@ -12,13 +12,13 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:fontFamily="monospace"
android:gravity="top|start"
android:importantForAutofill="no"
android:inputType="textMultiLine"
android:gravity="top|start"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar"
tools:ignore="LabelFor" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,9 +1,9 @@
<?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:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:layout_height="match_parent">
<include layout="@layout/toolbar_activity" />
@ -11,10 +11,10 @@
android:id="@+id/swipe_refresh"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar">
<ScrollView
android:id="@+id/scroll_view"
@ -25,17 +25,17 @@
android:id="@+id/log_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:textIsSelectable="true"
android:focusable="true"
android:textSize="10sp"
android:fontFamily="monospace"
android:lineSpacingMultiplier="1.1"
android:longClickable="true"
android:padding="10dp"
android:textIsSelectable="true"
android:textSize="10sp"
tools:ignore="SmallSp" />
</ScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,7 +1,6 @@
<?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:layout_width="match_parent"
android:layout_height="match_parent">
@ -9,24 +8,24 @@
<com.google.android.material.tabs.TabLayout
android:id="@+id/main_tabs"
android:background="?attr/colorSurfaceVariant"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorSurfaceVariant"
android:visibility="gone"
app:tabTextColor="?attr/colorOnSurfaceVariant"
app:tabSelectedTextColor="?attr/colorOnSurfaceVariant"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintStart_toStartOf="parent" />
app:tabSelectedTextColor="?attr/colorOnSurfaceVariant"
app:tabTextColor="?attr/colorOnSurfaceVariant" />
<ProgressBar
android:id="@+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/main_tabs"
app:layout_constraintBottom_toBottomOf="parent" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/main_tabs" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
@ -36,6 +35,6 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/main_tabs"/>
app:layout_constraintTop_toBottomOf="@id/main_tabs" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,8 +1,8 @@
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:layout_height="match_parent">
<include layout="@layout/toolbar_activity" />
@ -10,10 +10,10 @@
android:id="@+id/swipe_refresh"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
@ -22,4 +22,4 @@
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,8 +1,8 @@
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:layout_height="match_parent">
<include layout="@layout/toolbar_activity" />
@ -15,4 +15,4 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,19 +1,19 @@
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:padding="20dp"
android:background="?attr/selectableItemBackground">
android:background="?attr/selectableItemBackground"
android:padding="20dp">
<ImageView
android:id="@+id/download_method_icon"
android:layout_width="30dp"
android:layout_height="30dp"
app:tint="?attr/colorAccent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="?attr/colorAccent" />
<TextView
android:id="@+id/download_method_title"
@ -21,24 +21,24 @@
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:textSize="15sp"
android:maxLines="1"
android:ellipsize="marquee"
app:layout_constraintTop_toTopOf="parent"
android:maxLines="1"
android:textSize="15sp"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/download_method_icon"
app:layout_constraintEnd_toStartOf="@id/download_method_chevron"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constrainedWidth="true" />
app:layout_constraintStart_toEndOf="@id/download_method_icon"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/download_method_chevron"
android:src="@drawable/ic_chevron_right"
android:layout_width="30dp"
android:layout_height="30dp"
app:tint="?attr/colorAccent"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/ic_chevron_right"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="?attr/colorAccent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -48,8 +48,8 @@
android:id="@+id/download_progress_item_error_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="10dp"
android:textColor="?attr/colorError"
@ -78,4 +78,4 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/download_progress_item_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -3,11 +3,11 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="20sp"
android:paddingTop="10sp"
android:background="?attr/selectableItemBackground"
android:paddingStart="20sp"
android:paddingTop="10sp"
android:paddingEnd="20sp"
android:background="?attr/selectableItemBackground">
android:paddingBottom="20sp">
<TextView
android:id="@+id/slot_item_title"
@ -83,7 +83,6 @@
android:layout_marginTop="20sp"
android:layout_marginEnd="10sp"
app:constraint_referenced_ids="slot_item_type_label,slot_item_type,slot_item_eid_label,slot_item_eid,slot_item_active_profile_label,slot_item_active_profile,slot_item_free_space_label,slot_item_free_space"
app:flow_wrapMode="aligned"
app:flow_horizontalAlign="start"
app:flow_horizontalBias="1"
app:flow_horizontalGap="10sp"
@ -92,6 +91,7 @@
app:flow_verticalBias="0"
app:flow_verticalGap="16sp"
app:flow_verticalStyle="packed"
app:flow_wrapMode="aligned"
app:layout_constraintEnd_toStartOf="@id/slot_checkbox"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/slot_item_title" />
@ -105,4 +105,4 @@
app:layout_constraintStart_toEndOf="@id/flow1"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,9 +1,9 @@
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:background="?android:attr/selectableItemBackground">
<TextView
android:id="@+id/euicc_info_title"
@ -12,8 +12,8 @@
android:layout_marginHorizontal="24dp"
android:layout_marginVertical="12dp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
@ -22,9 +22,9 @@
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginVertical="12dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/euicc_info_title"
app:layout_constraintBottom_toBottomOf="parent" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/euicc_info_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -20,16 +20,16 @@
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="16sp"
android:singleLine="true"
android:ellipsize="marquee"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/profile_menu"
app:layout_constraintTop_toTopOf="parent"
android:singleLine="true"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toTopOf="@+id/state"
app:layout_constraintHorizontal_bias="0"
app:layout_constrainedWidth="true" />
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/profile_menu"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/profile_menu"
@ -37,98 +37,98 @@
android:layout_height="25dp"
android:background="?selectableItemBackground"
android:src="@drawable/ic_menu_black"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:includeFontPadding="true"
android:singleLine="true"
android:textSize="14sp"
android:textStyle="italic"
android:singleLine="true"
android:includeFontPadding="true"
app:layout_constraintBottom_toTopOf="@+id/provider_label"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/name"
app:layout_constraintBottom_toTopOf="@+id/provider_label"/>
app:layout_constraintTop_toBottomOf="@id/name" />
<TextView
android:id="@+id/provider_label"
android:text="@string/profile_provider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:singleLine="true"
android:text="@string/profile_provider"
android:textSize="14sp"
android:textStyle="bold"
android:singleLine="true"
app:layout_constraintBottom_toTopOf="@+id/profile_class_label"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/state"
app:layout_constraintBottom_toTopOf="@+id/profile_class_label"/>
app:layout_constraintTop_toBottomOf="@id/state" />
<TextView
android:id="@+id/provider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:layout_marginStart="7dp"
android:textSize="14sp"
android:layout_marginTop="6dp"
android:singleLine="true"
android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@+id/profile_class"
app:layout_constraintLeft_toRightOf="@id/provider_label"
app:layout_constraintTop_toBottomOf="@id/state"
app:layout_constraintBottom_toTopOf="@+id/profile_class"/>
app:layout_constraintTop_toBottomOf="@id/state" />
<TextView
android:id="@+id/profile_class_label"
android:text="@string/profile_class"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:singleLine="true"
android:text="@string/profile_class"
android:textSize="14sp"
android:textStyle="bold"
android:singleLine="true"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/iccid_label"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/provider_label"
app:layout_constraintBottom_toTopOf="@+id/iccid_label"/>
app:layout_constraintTop_toBottomOf="@id/provider_label" />
<TextView
android:id="@+id/profile_class"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:layout_marginStart="7dp"
android:textSize="14sp"
android:layout_marginTop="6dp"
android:singleLine="true"
android:textSize="14sp"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/iccid"
app:layout_constraintLeft_toRightOf="@id/profile_class_label"
app:layout_constraintTop_toBottomOf="@id/provider"
app:layout_constraintBottom_toTopOf="@+id/iccid"/>
app:layout_constraintTop_toBottomOf="@id/provider" />
<TextView
android:id="@+id/iccid_label"
android:text="@string/profile_iccid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:singleLine="true"
android:text="@string/profile_iccid"
android:textSize="14sp"
android:textStyle="bold"
android:singleLine="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/profile_class_label"
app:layout_constraintBottom_toBottomOf="parent"/>
app:layout_constraintTop_toBottomOf="@id/profile_class_label" />
<TextView
android:id="@+id/iccid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:layout_marginStart="7dp"
android:textSize="14sp"
android:layout_marginTop="6dp"
android:singleLine="true"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@id/iccid_label"
app:layout_constraintTop_toBottomOf="@id/profile_class"
app:layout_constraintBottom_toBottomOf="parent"/>
app:layout_constraintTop_toBottomOf="@id/profile_class" />
<TextView
android:id="@+id/profile_sequence_number"
@ -142,4 +142,4 @@
</com.google.android.material.card.MaterialCardView>
</FrameLayout>
</FrameLayout>

View file

@ -8,14 +8,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:layout_marginEnd="40dp"
android:layout_marginTop="6dp"
android:layout_marginEnd="40dp"
android:gravity="center"
android:text="@string/no_profile"
android:textStyle="italic"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -11,18 +11,18 @@
<TextView
android:id="@+id/download_wizard_details_title"
android:text="@string/download_wizard_details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="20sp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_marginStart="60dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="60dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginBottom="20dp"
android:gravity="center_horizontal"
android:text="@string/download_wizard_details"
android:textSize="20sp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textfield.TextInputLayout
@ -32,10 +32,10 @@
android:hint="@string/profile_download_server">
<com.google.android.material.textfield.TextInputEditText
android:maxLines="1"
android:inputType="text"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
android:inputType="text"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
@ -47,10 +47,10 @@
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:maxLines="1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="textPassword" />
android:inputType="textPassword"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
@ -62,10 +62,10 @@
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:maxLines="1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="textPassword" />
android:inputType="textPassword"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
@ -79,26 +79,26 @@
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:maxLines="1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="numberPassword" />
android:inputType="numberPassword"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginHorizontal="20dp"
android:orientation="vertical"
app:constraint_referenced_ids="profile_download_server,profile_download_code,profile_download_confirmation_code,profile_download_imei"
app:flow_verticalGap="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/download_wizard_details_title"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constrainedWidth="true" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/download_wizard_details_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</ScrollView>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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"
xmlns:tools="http://schemas.android.com/tools"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
@ -12,48 +12,48 @@
<TextView
android:id="@+id/download_wizard_diagnostics_title"
android:text="@string/download_wizard_diagnostics"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="20sp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_marginStart="60dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="60dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginBottom="20dp"
android:gravity="center_horizontal"
android:text="@string/download_wizard_diagnostics"
android:textSize="20sp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/download_wizard_diagnostics_save"
android:src="@drawable/ic_save_as_black"
android:layout_margin="20dp"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_margin="20dp"
android:contentDescription="@string/download_wizard_diagnostics_save"
app:tint="?attr/colorAccent"
android:src="@drawable/ic_save_as_black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
app:tint="?attr/colorAccent" />
<TextView
android:id="@+id/download_wizard_diagnostics_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:textIsSelectable="true"
android:focusable="true"
android:textSize="10sp"
android:fontFamily="monospace"
android:lineSpacingMultiplier="1.1"
android:longClickable="true"
app:layout_constraintTop_toBottomOf="@id/download_wizard_diagnostics_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:padding="10dp"
android:textIsSelectable="true"
android:textSize="10sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/download_wizard_diagnostics_title"
tools:ignore="SmallSp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</ScrollView>

View file

@ -1,33 +1,33 @@
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:layout_height="match_parent">
<TextView
android:id="@+id/download_method_select_title"
android:text="@string/download_wizard_method_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="20sp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_marginStart="60dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="60dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginBottom="20dp"
android:gravity="center_horizontal"
android:text="@string/download_wizard_method_select"
android:textSize="20sp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/download_method_list"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/download_method_select_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constrainedHeight="true" />
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/download_method_select_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,33 +1,33 @@
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:layout_height="match_parent">
<TextView
android:id="@+id/download_progress_title"
android:text="@string/download_wizard_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="20sp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_marginStart="60dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="60dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginBottom="20dp"
android:gravity="center_horizontal"
android:text="@string/download_wizard_progress"
android:textSize="20sp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/download_progress_list"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/download_progress_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constrainedHeight="true" />
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/download_progress_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,33 +1,33 @@
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:layout_height="match_parent">
<TextView
android:id="@+id/download_slot_select_title"
android:text="@string/download_wizard_slot_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="20sp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_marginStart="60dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="60dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginBottom="20dp"
android:gravity="center_horizontal"
android:text="@string/download_wizard_slot_select"
android:textSize="20sp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/download_slot_list"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/download_slot_select_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constrainedHeight="true" />
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/download_slot_select_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -8,16 +8,16 @@
android:id="@+id/swipe_refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
app:layout_constraintTop_toTopOf="parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/profile_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="6dp"/>
android:paddingTop="6dp" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
@ -29,7 +29,7 @@
android:layout_marginBottom="16dp"
android:contentDescription="@string/profile_download"
android:src="@drawable/ic_add"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -2,6 +2,7 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/no_euicc_placeholder"
android:layout_width="match_parent"
@ -10,4 +11,4 @@
android:layout_marginEnd="40dp"
android:gravity="center"
android:text="@string/no_euicc" />
</FrameLayout>
</FrameLayout>

View file

@ -8,8 +8,8 @@
android:id="@+id/toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="1"
app:navigationIcon="?homeAsUpIndicator" />
@ -25,14 +25,14 @@
<ProgressBar
android:id="@+id/progress"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintBottom_toTopOf="@id/guideline"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/guideline"
style="@style/Widget.AppCompat.ProgressBar.Horizontal" />
app:layout_constraintTop_toBottomOf="@id/toolbar" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/profile_rename_new_name"
@ -40,10 +40,10 @@
android:layout_height="wrap_content"
android:layout_marginVertical="15dp"
android:hint="@string/profile_rename_new_name"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintWidth_percent=".8">
<com.google.android.material.textfield.TextInputEditText
@ -52,4 +52,4 @@
</com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -9,10 +9,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/usb_reader_text"
@ -21,27 +21,27 @@
android:layout_marginHorizontal="40dp"
android:gravity="center"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/usb_grant_permission"
android:text="@string/usb_permission"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="@string/usb_permission"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/usb_reader_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
app:layout_constraintTop_toBottomOf="@id/usb_reader_text" />
<FrameLayout
android:id="@+id/child_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,9 +1,9 @@
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:background="?android:attr/selectableItemBackground">
<TextView
android:id="@+id/notification_address"
@ -11,8 +11,8 @@
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginVertical="12dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
@ -30,11 +30,11 @@
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginVertical="12dp"
android:maxLines="1"
android:ellipsize="marquee"
app:layout_constraintStart_toStartOf="parent"
android:maxLines="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/notification_address"
app:layout_constraintBottom_toBottomOf="parent" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/notification_address" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -3,4 +3,4 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingHorizontal="10dp"
android:paddingVertical="8dp"/>
android:paddingVertical="8dp" />

Some files were not shown because too many files have changed in this diff Show more