Skip to content

Commit

Permalink
AND-9232 added NfcReader enabling api
Browse files Browse the repository at this point in the history
  • Loading branch information
kozarezvlad committed Nov 26, 2024
1 parent 94ddd48 commit 2dd9d5f
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 27 deletions.
39 changes: 20 additions & 19 deletions tangem-sdk-android/src/main/java/com/tangem/sdk/nfc/NfcManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class NfcManager : NfcAdapter.ReaderCallback, ReadingActiveListener, DefaultLife
private val onTagDiscoveredListeners: MutableList<VoidCallback> = mutableListOf()
private var activity: Activity? = null
private var nfcAdapter: NfcAdapter? = null
private var isReaderModeEnabled: Boolean = false

private val mBroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Expand All @@ -62,6 +63,14 @@ class NfcManager : NfcAdapter.ReaderCallback, ReadingActiveListener, DefaultLife
onTagDiscoveredListeners.remove(listener)
}

override fun onForceEnableReadingMode() {
enableReaderModeIfNfcEnabled()
}

override fun onForceDisableReadingMode() {
disableReaderMode()
}

fun setCurrentActivity(activity: Activity) {
this.activity = activity
nfcAdapter = NfcAdapter.getDefaultAdapter(activity)
Expand All @@ -75,29 +84,15 @@ class NfcManager : NfcAdapter.ReaderCallback, ReadingActiveListener, DefaultLife

override fun onStart(owner: LifecycleOwner) {
reader.listener = this
}

override fun onResume(owner: LifecycleOwner) {
super.onResume(owner)
enableReaderModeIfNfcEnabled()
}

override fun onPause(owner: LifecycleOwner) {
super.onPause(owner)
disableReaderMode()
}

override fun onStop(owner: LifecycleOwner) {
disableReaderMode()
reader.stopSession(true)
reader.listener = null
}

override fun onStartSession() {
disableReaderMode()
Thread.sleep(DELAY_BEFORE_ENABLE)
enableReaderModeIfNfcEnabled()
}

override fun onDestroy(owner: LifecycleOwner) {
activity?.unregisterReceiver(mBroadcastReceiver)
activity = null
Expand All @@ -113,16 +108,22 @@ class NfcManager : NfcAdapter.ReaderCallback, ReadingActiveListener, DefaultLife
}

private fun enableReaderMode() {
Log.nfc { "enableReaderMode" }
Log.nfc { "enableReaderMode isReaderModeEnabled $isReaderModeEnabled" }
if (activity?.isDestroyed == false) {
if (isReaderModeEnabled) {
disableReaderMode()
Thread.sleep(DELAY_BEFORE_ENABLE)
}
nfcAdapter?.enableReaderMode(activity, this, READER_FLAGS, Bundle())
isReaderModeEnabled = true
}
}

private fun disableReaderMode() {
Log.nfc { "disableReaderMode" }
if (activity?.isDestroyed == false) {
Log.nfc { "disableReaderMode $isReaderModeEnabled" }
if (activity?.isDestroyed == false && isReaderModeEnabled) {
nfcAdapter?.disableReaderMode(activity)
isReaderModeEnabled = false
}
}

Expand All @@ -144,6 +145,6 @@ class NfcManager : NfcAdapter.ReaderCallback, ReadingActiveListener, DefaultLife
NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS

const val IGNORE_DEBOUNCE_MS = 1_500
private const val DELAY_BEFORE_ENABLE = 200L
private const val DELAY_BEFORE_ENABLE = 300L
}
}
19 changes: 12 additions & 7 deletions tangem-sdk-android/src/main/java/com/tangem/sdk/nfc/NfcReader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ class NfcReader : CardReader {
scope?.launchWithLock(readerMutex) {
Log.nfc { "start NFC session, thread ${Thread.currentThread().id}" }
nfcTag = null
listener?.onStartSession()
listener?.readingIsActive = true
}
}
Expand All @@ -63,7 +62,6 @@ class NfcReader : CardReader {
override fun resumeSession() {
scope?.launchWithLock(readerMutex) {
Log.nfc { "resume NFC session, thread ${Thread.currentThread().id}" }
listener?.onStartSession()
listener?.readingIsActive = true
}
}
Expand All @@ -76,14 +74,11 @@ class NfcReader : CardReader {
}
IsoDep.get(tag)?.let { isoDep ->
connect(
isoDep,
isoDep = isoDep,
onSuccess = {
nfcTag = NfcTag(TagType.Nfc, isoDep)
},
onError = {
nfcTag = null
},
)
) { }
}
}
}
Expand Down Expand Up @@ -209,6 +204,16 @@ class NfcReader : CardReader {
}
}

override fun forceEnableReaderMode() {
Log.nfc { "forceEnableReaderMode" }
listener?.onForceEnableReadingMode()
}

override fun forceDisableReaderMode() {
Log.nfc { "forceDisableReaderMode" }
listener?.onForceDisableReadingMode()
}

private fun CoroutineScope.launchWithLock(mutex: Mutex, action: suspend () -> Unit) {
this.launch {
mutex.withLock(null) {
Expand Down
18 changes: 18 additions & 0 deletions tangem-sdk-core/src/main/java/com/tangem/TangemSdk.kt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,24 @@ class TangemSdk(
CryptoUtils.initCrypto()
}

/**
* This method enables [NfcAdapter] reader mode if it was disabled
* Use carefully, by default sdk enables reader mode automatically
* but some devices could disable it in some cases out of lifecycle
* For example: launch qr code scanner on Samsung
*/
fun forceEnableReaderMode() {
reader.forceEnableReaderMode()
}

/**
* This method disables [NfcAdapter] reader mode if it was enabled
* Don't forget call [forceEnableReaderMode] after this
*/
fun forceDisableReaderMode() {
reader.forceDisableReaderMode()
}

// region Card operations
/**
* This method launches a [ScanTask] on a new thread.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,23 @@ interface CardReader {
fun resumeSession()

fun readSlixTag(callback: CompletionCallback<ResponseApdu>)

/**
* Some devices (Samsung) could disable reader mode when open camera inside app,
* after this we should call [forceEnableReaderMode] manually
*/
fun forceEnableReaderMode()

/**
* Use for some cases when you need to [forceDisableReaderMode] manually,
* don't forget call [forceEnableReaderMode] after this
*/
fun forceDisableReaderMode()
}

interface ReadingActiveListener {
var readingIsActive: Boolean

fun onStartSession()
fun onForceEnableReadingMode()
fun onForceDisableReadingMode()
}

0 comments on commit 2dd9d5f

Please sign in to comment.