Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] Implement qr code generator #33381

Merged
merged 4 commits into from
May 10, 2024
Merged
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
Original file line number Diff line number Diff line change
@@ -122,7 +122,7 @@ class CHIPToolActivity :
startActivity(redirectIntent)
}

override fun SetNetworkType(type: ProvisionNetworkType) {
override fun setNetworkType(type: ProvisionNetworkType?) {
networkType = type
}

Original file line number Diff line number Diff line change
@@ -154,7 +154,7 @@ class SelectActionFragment : Fragment() {
/** Notifies listener of a click to manually input the CHIP device address. */
fun onShowDeviceAddressInput()

fun SetNetworkType(type: ProvisionNetworkType)
fun setNetworkType(type: ProvisionNetworkType?)
}

private fun showFragment(fragment: Fragment, showOnBack: Boolean = true) {
@@ -172,6 +172,7 @@ class SelectActionFragment : Fragment() {

/** Notifies listener of Scan QR code button click. */
private fun handleScanQrCodeClicked() {
getCallback()?.setNetworkType(null)
showFragment(BarcodeFragment.newInstance())
}

@@ -226,13 +227,13 @@ class SelectActionFragment : Fragment() {

/** Notifies listener of provision-WiFi-credentials button click. */
private fun handleProvisionWiFiCredentialsClicked() {
getCallback()?.SetNetworkType(ProvisionNetworkType.WIFI)
getCallback()?.setNetworkType(ProvisionNetworkType.WIFI)
showFragment(BarcodeFragment.newInstance())
}

/** Notifies listener of provision-Thread-credentials button click. */
private fun handleProvisionThreadCredentialsClicked() {
getCallback()?.SetNetworkType(ProvisionNetworkType.THREAD)
getCallback()?.setNetworkType(ProvisionNetworkType.THREAD)
showFragment(BarcodeFragment.newInstance())
}

Original file line number Diff line number Diff line change
@@ -18,7 +18,12 @@

package com.google.chip.chiptool.setuppayloadscanner

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -27,6 +32,10 @@ import androidx.fragment.app.Fragment
import com.google.chip.chiptool.R
import com.google.chip.chiptool.databinding.ChipDeviceInfoFragmentBinding
import com.google.chip.chiptool.util.FragmentUtil
import java.net.URLEncoder
import matter.onboardingpayload.OnboardingPayload
import matter.onboardingpayload.OnboardingPayloadException
import matter.onboardingpayload.QRCodeOnboardingPayloadGenerator

/** Show the [CHIPDeviceInfo]. */
class CHIPDeviceDetailsFragment : Fragment() {
@@ -35,6 +44,8 @@ class CHIPDeviceDetailsFragment : Fragment() {
private val binding
get() = _binding!!

private lateinit var onBoardingPayload: OnboardingPayload

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@@ -43,17 +54,13 @@ class CHIPDeviceDetailsFragment : Fragment() {
_binding = ChipDeviceInfoFragmentBinding.inflate(inflater, container, false)
deviceInfo = checkNotNull(requireArguments().getParcelable(ARG_DEVICE_INFO))

binding.versionTv.text = "${deviceInfo.version}"
binding.vendorIdTv.text = "${deviceInfo.vendorId}"
binding.productIdTv.text = "${deviceInfo.productId}"
binding.setupCodeTv.text = "${deviceInfo.setupPinCode}"
binding.discriminatorTv.text = "${deviceInfo.discriminator}"
binding.discoveryCapabilitiesTv.text =
requireContext()
.getString(
R.string.chip_device_info_discovery_capabilities_text,
deviceInfo.discoveryCapabilities
)
binding.versionEd.setText(deviceInfo.version.toString())
binding.vendorIdEd.setText(deviceInfo.vendorId.toString())
binding.productIdEd.setText(deviceInfo.productId.toString())
binding.setupCodeEd.setText(deviceInfo.setupPinCode.toString())
binding.discriminatorEd.setText(deviceInfo.discriminator.toString())
binding.serialNumberEd.setText(deviceInfo.serialNumber)
binding.discoveryCapabilitiesTv.text = "${deviceInfo.discoveryCapabilities}"

if (deviceInfo.optionalQrCodeInfoMap.isEmpty()) {
binding.vendorTagsLabelTv.visibility = View.GONE
@@ -70,7 +77,7 @@ class CHIPDeviceDetailsFragment : Fragment() {
}
}

binding.commissioningFlowTv.text = "${deviceInfo.commissioningFlow}"
binding.commissioningFlowEd.setText(deviceInfo.commissioningFlow.toString())

// commissioningFlow = 2 (Custom), read device info from Ledger
if (deviceInfo.commissioningFlow == 2) {
@@ -81,9 +88,74 @@ class CHIPDeviceDetailsFragment : Fragment() {
}
}

onBoardingPayload = deviceInfo.toSetupPayload()
binding.qrCodeTv.text =
QRCodeOnboardingPayloadGenerator(onBoardingPayload)
.payloadBase38RepresentationWithAutoTLVBuffer()

setDiscoveryCapabilitiesEditTextListener()
setQRCodeButtonListener()

return binding.root
}

private fun setDiscoveryCapabilitiesEditTextListener() {
binding.discoveryCapabilitiesEd.setText(onBoardingPayload.getRendezvousInformation().toString())
binding.discoveryCapabilitiesEd.addTextChangedListener(
object : TextWatcher {
override fun onTextChanged(value: CharSequence?, p1: Int, p2: Int, p3: Int) {
if (value.isNullOrEmpty()) {
return
}
onBoardingPayload.setRendezvousInformation(value.toString().toLong())
binding.discoveryCapabilitiesTv.text = "${onBoardingPayload.discoveryCapabilities}"
}

override fun afterTextChanged(p0: Editable?) {
// no_op
}

override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
// no_op
}
}
)
}

private fun setQRCodeButtonListener() {
binding.showQRCodeBtn.setOnClickListener {
onBoardingPayload.apply {
version = binding.versionEd.text.toString().toInt()
vendorId = binding.vendorIdEd.text.toString().toInt()
productId = binding.productIdEd.text.toString().toInt()
commissioningFlow = binding.commissioningFlowEd.text.toString().toInt()
setupPinCode = binding.setupCodeEd.text.toString().toLong()
discriminator = binding.discriminatorEd.text.toString().toInt()
val serialNumber = binding.serialNumberEd.text.toString()
try {
removeSerialNumber()
} catch (e: OnboardingPayloadException) {
Log.d(TAG, "Serial Number not set!", e)
}
if (serialNumber.isNotEmpty()) {
addSerialNumber(binding.serialNumberEd.text.toString())
}
}
val qrCode =
QRCodeOnboardingPayloadGenerator(onBoardingPayload)
.payloadBase38RepresentationWithAutoTLVBuffer()
Log.d(TAG, "QR Code : $qrCode")
binding.qrCodeTv.text = qrCode
}

binding.showQRCodeUriBtn.setOnClickListener {
val qrCodeEncode = URLEncoder.encode(binding.qrCodeTv.text.toString(), "UTF-8")
val qrCodeUri = getString(R.string.chip_device_info_qrcode_uri, qrCodeEncode)
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(qrCodeUri))
startActivity(intent)
}
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
@@ -96,6 +168,7 @@ class CHIPDeviceDetailsFragment : Fragment() {
}

companion object {
private const val TAG = "CHIPDeviceDetailsFragment"
private const val ARG_DEVICE_INFO = "device_info"

@JvmStatic
Original file line number Diff line number Diff line change
@@ -19,9 +19,11 @@
package com.google.chip.chiptool.setuppayloadscanner

import android.os.Parcelable
import android.util.Log
import kotlinx.parcelize.Parcelize
import matter.onboardingpayload.DiscoveryCapability
import matter.onboardingpayload.OnboardingPayload
import matter.onboardingpayload.OnboardingPayloadException

/** Class to hold the CHIP device information. */
@Parcelize
@@ -35,12 +37,40 @@ data class CHIPDeviceInfo(
val optionalQrCodeInfoMap: Map<Int, QrCodeInfo> = mapOf(),
val discoveryCapabilities: MutableSet<DiscoveryCapability> = mutableSetOf(),
val isShortDiscriminator: Boolean = false,
val serialNumber: String = "",
val ipAddress: String? = null,
val port: Int = 5540
) : Parcelable {

fun toSetupPayload(): OnboardingPayload {
val onboardingPayload =
OnboardingPayload(
version,
vendorId,
productId,
commissioningFlow,
discoveryCapabilities,
discriminator,
isShortDiscriminator,
setupPinCode
)
if (serialNumber.isNotEmpty()) {
onboardingPayload.addSerialNumber(serialNumber)
}
return onboardingPayload
}

companion object {
private const val TAG = "CHIPDeviceInfo"

fun fromSetupPayload(setupPayload: OnboardingPayload): CHIPDeviceInfo {
val serialNumber =
try {
setupPayload.getSerialNumber()
} catch (e: OnboardingPayloadException) {
Log.d(TAG, "serialNumber Exception", e)
""
}
return CHIPDeviceInfo(
setupPayload.version,
setupPayload.vendorId,
@@ -52,7 +82,8 @@ data class CHIPDeviceInfo(
QrCodeInfo(info.tag, info.type, info.data, info.int32)
},
setupPayload.discoveryCapabilities,
setupPayload.hasShortDiscriminator
setupPayload.hasShortDiscriminator,
serialNumber
)
}
}
Loading
Loading