diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPDeviceDetailsFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPDeviceDetailsFragment.kt index b2b27ee31da900..168d46159f2424 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPDeviceDetailsFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPDeviceDetailsFragment.kt @@ -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,6 +88,59 @@ class CHIPDeviceDetailsFragment : Fragment() { } } + onBoardingPayload = deviceInfo.toSetupPayload() + binding.qrCodeTv.text = + QRCodeOnboardingPayloadGenerator(onBoardingPayload) + .payloadBase38RepresentationWithAutoTLVBuffer() + + 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?) {} + + override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {} + } + ) + 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!") + } + 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) + } + return binding.root } @@ -96,6 +156,7 @@ class CHIPDeviceDetailsFragment : Fragment() { } companion object { + private const val TAG = "CHIPDeviceDetailsFragment" private const val ARG_DEVICE_INFO = "device_info" @JvmStatic diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPDeviceInfo.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPDeviceInfo.kt index d8fb51bbb3d844..e5a0791ba98bbb 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPDeviceInfo.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/setuppayloadscanner/CHIPDeviceInfo.kt @@ -22,6 +22,7 @@ import android.os.Parcelable 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 +36,37 @@ data class CHIPDeviceInfo( val optionalQrCodeInfoMap: Map = mapOf(), val discoveryCapabilities: MutableSet = 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 { fun fromSetupPayload(setupPayload: OnboardingPayload): CHIPDeviceInfo { + val serialNumber = + try { + setupPayload.getSerialNumber() + } catch (e: OnboardingPayloadException) { + "" + } return CHIPDeviceInfo( setupPayload.version, setupPayload.vendorId, @@ -52,7 +78,8 @@ data class CHIPDeviceInfo( QrCodeInfo(info.tag, info.type, info.data, info.int32) }, setupPayload.discoveryCapabilities, - setupPayload.hasShortDiscriminator + setupPayload.hasShortDiscriminator, + serialNumber ) } } diff --git a/examples/android/CHIPTool/app/src/main/res/layout/chip_device_info_fragment.xml b/examples/android/CHIPTool/app/src/main/res/layout/chip_device_info_fragment.xml index 6e326a65008edb..4997681993ca29 100644 --- a/examples/android/CHIPTool/app/src/main/res/layout/chip_device_info_fragment.xml +++ b/examples/android/CHIPTool/app/src/main/res/layout/chip_device_info_fragment.xml @@ -1,5 +1,6 @@ @@ -26,16 +27,18 @@ android:layout_below="@id/titleTv" android:layout_alignParentStart="true" android:textSize="20sp"/> - + android:textSize="11sp" + android:autofillHints="@string/chip_device_info_version_label" + android:inputType="number" + tools:ignore="LabelFor" /> - + android:textSize="11sp" + android:autofillHints="@string/chip_device_info_vendor_id_label" + android:inputType="number" + tools:ignore="LabelFor" /> - + android:textSize="11sp" + android:autofillHints="@string/chip_device_info_product_id_label" + android:inputType="number" + tools:ignore="LabelFor" /> - + android:textSize="11sp" + android:autofillHints="@string/chip_device_info_discriminator_label" + android:inputType="number" + tools:ignore="LabelFor" /> - + android:textSize="11sp" + android:autofillHints="@string/chip_device_info_setup_code_label" + android:inputType="number" + tools:ignore="LabelFor" /> + + @@ -152,27 +184,82 @@ android:layout_below="@id/discoveryCapabilitiesTv" android:layout_alignParentStart="true" android:textSize="20sp"/> - + + +