Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# SonarQube Quality Metrics
| 🟢 Quality Gate | 📊 Code Metrics | 🛡️ Code Quality | 🔐 Security & Reliability | 🤖 AI Code Assurance |
|----------------|----------------|----------------|---------------------------|----------------------|
| [![Quality Gate Status](https://sonarqube.corp.clover.com/api/project_badges/measure?project=com.clover.clover-android-sdk&metric=alert_status&token=sqb_757e1c7773a84cd8c994f14951b2dbf73d94d461)](https://sonarqube.corp.clover.com/dashboard?id=com.clover.clover-android-sdk)<br>[![Quality Gate Status](https://sonarqube.corp.clover.com/api/project_badges/quality_gate?project=com.clover.clover-android-sdk&token=sqb_757e1c7773a84cd8c994f14951b2dbf73d94d461)](https://sonarqube.corp.clover.com/dashboard?id=com.clover.clover-android-sdk) | [![Coverage](https://sonarqube.corp.clover.com/api/project_badges/measure?project=com.clover.clover-android-sdk&metric=coverage&token=sqb_757e1c7773a84cd8c994f14951b2dbf73d94d461)](https://sonarqube.corp.clover.com/dashboard?id=com.clover.clover-android-sdk)<br>[![Duplicated Lines (%)](https://sonarqube.corp.clover.com/api/project_badges/measure?project=com.clover.clover-android-sdk&metric=duplicated_lines_density&token=sqb_757e1c7773a84cd8c994f14951b2dbf73d94d461)](https://sonarqube.corp.clover.com/dashboard?id=com.clover.clover-android-sdk)<br>[![Lines of Code](https://sonarqube.corp.clover.com/api/project_badges/measure?project=com.clover.clover-android-sdk&metric=ncloc&token=sqb_757e1c7773a84cd8c994f14951b2dbf73d94d461)](https://sonarqube.corp.clover.com/dashboard?id=com.clover.clover-android-sdk)<br>[![Technical Debt](https://sonarqube.corp.clover.com/api/project_badges/measure?project=com.clover.clover-android-sdk&metric=sqale_index&token=sqb_757e1c7773a84cd8c994f14951b2dbf73d94d461)](https://sonarqube.corp.clover.com/dashboard?id=com.clover.clover-android-sdk) | [![Bugs](https://sonarqube.corp.clover.com/api/project_badges/measure?project=com.clover.clover-android-sdk&metric=bugs&token=sqb_757e1c7773a84cd8c994f14951b2dbf73d94d461)](https://sonarqube.corp.clover.com/dashboard?id=com.clover.clover-android-sdk)<br>[![Code Smells](https://sonarqube.corp.clover.com/api/project_badges/measure?project=com.clover.clover-android-sdk&metric=code_smells&token=sqb_757e1c7773a84cd8c994f14951b2dbf73d94d461)](https://sonarqube.corp.clover.com/dashboard?id=com.clover.clover-android-sdk)<br>[![Maintainability Rating](https://sonarqube.corp.clover.com/api/project_badges/measure?project=com.clover.clover-android-sdk&metric=sqale_rating&token=sqb_757e1c7773a84cd8c994f14951b2dbf73d94d461)](https://sonarqube.corp.clover.com/dashboard?id=com.clover.clover-android-sdk) | [![Security Hotspots](https://sonarqube.corp.clover.com/api/project_badges/measure?project=com.clover.clover-android-sdk&metric=security_hotspots&token=sqb_757e1c7773a84cd8c994f14951b2dbf73d94d461)](https://sonarqube.corp.clover.com/dashboard?id=com.clover.clover-android-sdk)<br>[![Vulnerabilities](https://sonarqube.corp.clover.com/api/project_badges/measure?project=com.clover.clover-android-sdk&metric=vulnerabilities&token=sqb_757e1c7773a84cd8c994f14951b2dbf73d94d461)](https://sonarqube.corp.clover.com/dashboard?id=com.clover.clover-android-sdk)<br>[![Reliability Rating](https://sonarqube.corp.clover.com/api/project_badges/measure?project=com.clover.clover-android-sdk&metric=reliability_rating&token=sqb_757e1c7773a84cd8c994f14951b2dbf73d94d461)](https://sonarqube.corp.clover.com/dashboard?id=com.clover.clover-android-sdk)<br>[![Security Rating](https://sonarqube.corp.clover.com/api/project_badges/measure?project=com.clover.clover-android-sdk&metric=security_rating&token=sqb_757e1c7773a84cd8c994f14951b2dbf73d94d461)](https://sonarqube.corp.clover.com/dashboard?id=com.clover.clover-android-sdk) | [![AI Code Assurance](https://sonarqube.corp.clover.com/api/project_badges/ai_code_assurance?project=com.clover.clover-android-sdk&token=sqb_757e1c7773a84cd8c994f14951b2dbf73d94d461)](https://sonarqube.corp.clover.com/dashboard?id=com.clover.clover-android-sdk) |

Clover SDK for Android
======================

Expand Down
2 changes: 1 addition & 1 deletion clover-android-connector-sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
* limitations under the License.
*/
group = 'com.clover.sdk'
version = '329'
version = '333'


apply from: file("${project.rootDir}/lib.gradle")
Expand Down
2 changes: 1 addition & 1 deletion clover-android-loyalty-kit/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
* limitations under the License.
*/
group = 'com.clover.sdk'
version = '329'
version = '333'


apply from: file("${project.rootDir}/lib.gradle")
Expand Down
2 changes: 1 addition & 1 deletion clover-android-sdk-examples/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
* limitations under the License.
*/
group = 'com.clover.sdk'
version = '329'
version = '333'

apply from: file("${project.rootDir}/app.gradle")
apply plugin: 'kotlin-android'
Expand Down
10 changes: 10 additions & 0 deletions clover-android-sdk-examples/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ xmlns:tools="http://schemas.android.com/tools"
android:theme="@style/Theme.AppCompat.Light"
android:label="@string/mifare_card_reader_test" />

<activity android:name=".NfcReaderTestActivity"
android:theme="@style/Theme.AppCompat.Light"
android:label="@string/nfc_reader_test" />

<activity
android:name="com.clover.android.sdk.examples.ReceiptRegistrationTestActivity"
Expand Down Expand Up @@ -264,5 +267,12 @@ xmlns:tools="http://schemas.android.com/tools"
android:name="com.clover.android.sdk.examples.FILTER_OUT_ACTIVITY"
android:value="true" />
</activity>

<activity android:name=".nfc.NfcReaderStatusActivity"
android:theme="@style/Theme.AppCompat.Light" >
<meta-data
android:name="com.clover.android.sdk.examples.FILTER_OUT_ACTIVITY"
android:value="true" />
</activity>
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.clover.android.sdk.examples

import android.content.Intent
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import com.clover.android.sdk.examples.mifare.MifareCardReaderType
import com.clover.android.sdk.examples.nfc.NfcReaderStatusActivity
import com.clover.android.sdk.examples.nfc.NfcReaderOperationIds

class NfcReaderTestActivity : AppCompatActivity() {

var nfcReaderOperationId = NfcReaderOperationIds.FELICA_UUID

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContentView(R.layout.activity_nfc_reader_test)

findViewById<Button>(R.id.button_felica_uuid).setOnClickListener {
nfcReaderOperationId = NfcReaderOperationIds.FELICA_UUID
startNfcReaderStatusActivity()
}

findViewById<Button>(R.id.button_felica_suica_read).setOnClickListener {
nfcReaderOperationId = NfcReaderOperationIds.FELICA_COMMAND
startNfcReaderStatusActivity()
}
}

private fun startNfcReaderStatusActivity() {
startActivity(Intent(this, NfcReaderStatusActivity::class.java).apply {
putExtra("NFC_READER_OPERATION_ID", nfcReaderOperationId.type)
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.clover.android.sdk.examples.nfc

enum class NfcReaderOperationIds(val type: Int) {
FELICA_UUID(0),
FELICA_COMMAND(1),
CANCEL(6)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
package com.clover.android.sdk.examples.nfc

import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.clover.android.sdk.examples.NfcReaderTestActivity
import com.clover.android.sdk.examples.R
import com.clover.sdk.v3.nfc.connector.NfcReaderClient
import com.clover.sdk.v3.nfc.listener.INfcReaderClientListener
import com.clover.sdk.v3.nfc.model.FelicaCardCommand
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class NfcReaderStatusActivity : AppCompatActivity() {

private var isNfcServiceConnected = false

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_nfc_reader_status)
findViewById<Button>(R.id.button_cancel).setOnClickListener {
if (isNfcServiceConnected) {
NfcReaderClient.getInstance(application).cancel()
}
finish()
}
}

override fun onStart() {
super.onStart()
lifecycleScope.launch(Dispatchers.IO) {
NfcReaderClient.getInstance(application).connect(object : INfcReaderClientListener {
override fun onConnected() {
isNfcServiceConnected = true
startNfc()
}

override fun onDisconnect() {
isNfcServiceConnected = false
}
})
}
}

@OptIn(ExperimentalStdlibApi::class)
private fun startNfc() {
val nfcReaderOPerationExtra = intent.extras?.getInt("NFC_READER_OPERATION_ID")
val nfcReaderOperationId = when (nfcReaderOPerationExtra) {
0 -> NfcReaderOperationIds.FELICA_UUID
1 -> NfcReaderOperationIds.FELICA_COMMAND
else -> NfcReaderOperationIds.FELICA_UUID
}

val nfcStatusText = findViewById<TextView>(R.id.text_nfc_status)

if (nfcReaderOperationId == NfcReaderOperationIds.FELICA_UUID) {
if (isNfcServiceConnected) {
lifecycleScope.launch(Dispatchers.IO) {
NfcReaderClient.getInstance(application)
.felicaUuid()?.felicaCardUuid?.let { uuidString ->
withContext(Dispatchers.Main) {
nfcStatusText.text = uuidString + "\n\nID: " + uuidString.substring(
0,
16
) + "\nPMm: " + uuidString.substring(16, uuidString.length)
}
} ?: run {
withContext(Dispatchers.Main) {
nfcStatusText.text = "Felica card UUID read failed"
}
Log.d(
NfcReaderTestActivity::class.simpleName,
"Felica card UUID no response received"
)
}
}
} else {
Log.d(
NfcReaderTestActivity::class.simpleName,
"Felica Service is disconnected, please restart activity"
)
}
}

if (nfcReaderOperationId == NfcReaderOperationIds.FELICA_COMMAND) {
if (isNfcServiceConnected) {
lifecycleScope.launch(Dispatchers.IO) {
NfcReaderClient.getInstance(application).felicaCommand(
FelicaCardCommand("0000030107")
)?.cardRsp?.let { felicaCardRspData ->
withContext(Dispatchers.Main) {
nfcStatusText.text = felicaCardRspData
}
} ?: run {
withContext(Dispatchers.Main) {
nfcStatusText.text =
"Felica command failed. Please check the card and try again."
}
Log.d(
NfcReaderTestActivity::class.simpleName,
"Felica command NO response received"
)
}

NfcReaderClient.getInstance(application).felicaCommand(
FelicaCardCommand("06010F090A8000800180028003800480058006800780088009")
)?.cardRsp?.let { felicaCardRspData ->
withContext(Dispatchers.Main) {

// parse Suica card transaction data
var xatDetailsAll: String = ""
val felicaCardRspDataByteArray = felicaCardRspData.hexToByteArray()
xatDetailsAll = felicaCardRspData + "\n"
for (index in 0 until felicaCardRspDataByteArray.get(2)) {
// each transaction is 16 bytes
val xatDetails = suicaParseTransaction(
felicaCardRspDataByteArray,
3 + index * 16
)
xatDetailsAll = xatDetailsAll + xatDetails + "\n"
}
nfcStatusText.text = xatDetailsAll
}
} ?: run {
withContext(Dispatchers.Main) {
nfcStatusText.text =
"Felica command failed. Please check the card and try again."
}
Log.d(
NfcReaderTestActivity::class.simpleName,
"Felica command NO response received"
)
}
}
}
}
}

override fun onStop() {
NfcReaderClient.getInstance(application).disconnect()
super.onStop()
}

// this is for Suica transaction data parsing
// Define the valid IDs as private constants at the top of your class
private val SHOPPING_PROC_IDS = setOf(70, 73, 74, 75, 198, 203)
private val BUS_PROC_IDS = setOf(13, 15, 31, 35)

/**
* Checks if the process ID corresponds to a shopping transaction.
*/
private fun suicaIsShopping(procId: Int): Boolean {
return procId in SHOPPING_PROC_IDS
}

/**
* Checks if the process ID corresponds to a bus transaction.
*/
private fun suicaIsBus(procId: Int): Boolean {
return procId in BUS_PROC_IDS
}

private fun suicaParseTransaction(xatData: ByteArray, dataOffset: Int): String {
val balance = toInt(xatData, dataOffset, 11, 10)
val xatDate = toInt(xatData, dataOffset, 4, 5)
val xatYear = (xatDate shr 9) and 0x007F
val xatMonth = (xatDate shr 5) and 0x000F
val xatDay = xatDate and 0x001F

val xatKind = xatData[dataOffset + 1]
var xatKindText = "JR"
if (suicaIsShopping(xatKind.toInt())) {
xatKindText = "物販"
} else {
if (suicaIsBus(xatKind.toInt())) {
xatKindText = "バス"
} else {
if (xatData[dataOffset + 1] >= 0x80) {
xatKindText = "公営/私鉄"
}
}
}

return "残高:¥$balance 日付:${2000 + xatYear}年${xatMonth}月${xatDay}日 処理:$xatKindText"
}

private fun toInt(res: ByteArray, off: Int, vararg idx: Int): Int {
var num = 0
for (j in idx) {
num = num shl 8
num += (res[off + j].toInt()) and 0x0ff
}
return num
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".nfc.NfcReaderStatusActivity">

<ImageView
android:id="@+id/image_contactless"
android:layout_gravity="center_horizontal"
android:layout_marginTop="60dp"
android:layout_width="148dp"
android:layout_height="74dp"
android:src="@drawable/contactless_black" />

<TextView
android:id="@+id/text_nfc_status_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginStart="16dp"
android:gravity="center"
android:layout_marginEnd="16dp"
android:layout_gravity="center_horizontal"
android:textStyle="bold"
android:textSize="20sp"
android:text="Please tap NFC card on the screen"/>

<TextView
android:id="@+id/text_nfc_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:gravity="center"
android:layout_gravity="center_horizontal"
android:layout_marginTop="18dp"
android:text=""
android:textSize="15sp"/>

</LinearLayout>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal | bottom"
android:layout_marginBottom="80dp"
android:textSize="20sp"
android:text="Cancel"
android:id="@+id/button_cancel"/>
</FrameLayout>
Loading