Skip to content

Commit e079364

Browse files
authored
[Android][ICD]Implement Android ICD sending using buffer (#33377)
* Implement Android ICD Queue sending * Kotlin detect config
1 parent 1dd9495 commit e079364

File tree

3 files changed

+119
-21
lines changed

3 files changed

+119
-21
lines changed

examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/AddressUpdateFragment.kt

+21-6
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import com.google.chip.chiptool.ChipClient
2121
import com.google.chip.chiptool.databinding.AddressUpdateFragmentBinding
2222
import com.google.chip.chiptool.util.DeviceIdUtil
2323
import kotlin.coroutines.resume
24-
import kotlin.coroutines.resumeWithException
2524
import kotlin.coroutines.suspendCoroutine
2625
import kotlinx.coroutines.CoroutineScope
2726
import kotlinx.coroutines.launch
@@ -55,6 +54,8 @@ class AddressUpdateFragment : ICDCheckInCallback, Fragment() {
5554

5655
private val handler = Handler(Looper.getMainLooper())
5756

57+
private var externalICDCheckInMessageCallback: ICDCheckInMessageCallback? = null
58+
5859
override fun onCreateView(
5960
inflater: LayoutInflater,
6061
container: ViewGroup?,
@@ -128,11 +129,12 @@ class AddressUpdateFragment : ICDCheckInCallback, Fragment() {
128129
}
129130

130131
val cluster = ChipClusters.IcdManagementCluster(devicePtr, 0)
131-
val duration = suspendCoroutine { cont ->
132+
val retDuration = suspendCoroutine { cont ->
132133
cluster.stayActiveRequest(
133134
object : ChipClusters.IcdManagementCluster.StayActiveResponseCallback {
134135
override fun onError(error: Exception) {
135-
cont.resumeWithException(error)
136+
Log.d(TAG, "onError", error)
137+
cont.resume(0L)
136138
}
137139

138140
override fun onSuccess(promisedActiveDuration: Long) {
@@ -143,12 +145,11 @@ class AddressUpdateFragment : ICDCheckInCallback, Fragment() {
143145
)
144146
}
145147
isSendingStayActiveCommand = false
146-
return duration
148+
return retDuration
147149
}
148150

149151
private fun updateUIForICDInteractionSwitch(isEnabled: Boolean): Boolean {
150-
val isICD =
151-
deviceController.icdClientInfo.firstOrNull { info -> info.peerNodeId == deviceId } != null
152+
val isICD = isICDDevice()
152153
if (isEnabled && !isICD) {
153154
binding.icdInteractionSwitch.isChecked = false
154155
return false
@@ -188,7 +189,13 @@ class AddressUpdateFragment : ICDCheckInCallback, Fragment() {
188189
return binding.deviceIdEd.text.toString().toULong(16)
189190
}
190191

192+
fun isICDDevice(): Boolean {
193+
return deviceController.icdClientInfo.firstOrNull { info -> info.peerNodeId == deviceId } !=
194+
null
195+
}
196+
191197
override fun notifyCheckInMessage(info: ICDClientInfo) {
198+
externalICDCheckInMessageCallback?.notifyCheckInMessage()
192199
if (info.peerNodeId != icdDeviceId) {
193200
return
194201
}
@@ -206,6 +213,14 @@ class AddressUpdateFragment : ICDCheckInCallback, Fragment() {
206213
}
207214
}
208215

216+
fun setNotifyCheckInMessageCallback(callback: ICDCheckInMessageCallback?) {
217+
externalICDCheckInMessageCallback = callback
218+
}
219+
220+
interface ICDCheckInMessageCallback {
221+
fun notifyCheckInMessage()
222+
}
223+
209224
private fun turnOnActiveMode() {
210225
requireActivity().runOnUiThread {
211226
binding.icdProgressBar.max = (icdTotalRemainStayActiveTimeMs / 1000).toInt()

examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt

+97-15
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import matter.tlv.AnonymousTag
4545
import matter.tlv.TlvReader
4646
import matter.tlv.TlvWriter
4747

48-
class WildcardFragment : Fragment() {
48+
class WildcardFragment : Fragment(), AddressUpdateFragment.ICDCheckInMessageCallback {
4949
private var _binding: WildcardFragmentBinding? = null
5050
private val binding
5151
get() = _binding!!
@@ -63,6 +63,23 @@ class WildcardFragment : Fragment() {
6363
private val invokePath = ArrayList<InvokeElement>()
6464
private val subscribeIdList = ArrayList<ULong>()
6565

66+
data class ReadICDConfig(val isFabricFiltered: Boolean, val eventMin: Long?)
67+
68+
data class SubscribeICDConfig(
69+
val minInterval: Int,
70+
val maxInterval: Int,
71+
val keepSubscriptions: Boolean,
72+
val isFabricFiltered: Boolean,
73+
val eventMin: Long?
74+
)
75+
76+
data class WriteInvokeICDConfig(val timedRequestTimeoutMs: Int, val imTimeoutMs: Int)
77+
78+
private var readICDConfig: ReadICDConfig? = null
79+
private var subscribeICDConfig: SubscribeICDConfig? = null
80+
private var writeICDConfig: WriteInvokeICDConfig? = null
81+
private var invokeICDConfig: WriteInvokeICDConfig? = null
82+
6683
private val reportCallback =
6784
object : ReportCallback {
6885
override fun onError(
@@ -173,6 +190,45 @@ class WildcardFragment : Fragment() {
173190
return binding.root
174191
}
175192

193+
override fun onResume() {
194+
super.onResume()
195+
addressUpdateFragment.setNotifyCheckInMessageCallback(this)
196+
}
197+
198+
override fun onPause() {
199+
addressUpdateFragment.setNotifyCheckInMessageCallback(null)
200+
super.onPause()
201+
}
202+
203+
override fun notifyCheckInMessage() {
204+
Log.d(TAG, "notifyCheckInMessage")
205+
if (attributePath.isNotEmpty() || eventPath.isNotEmpty()) {
206+
if (binding.readRadioBtn.isChecked && readICDConfig != null) {
207+
scope.launch { read(readICDConfig!!.isFabricFiltered, readICDConfig!!.eventMin) }
208+
} else if (binding.subscribeRadioBtn.isChecked && subscribeICDConfig != null) {
209+
scope.launch {
210+
subscribe(
211+
subscribeICDConfig!!.minInterval,
212+
subscribeICDConfig!!.maxInterval,
213+
subscribeICDConfig!!.keepSubscriptions,
214+
subscribeICDConfig!!.isFabricFiltered,
215+
subscribeICDConfig!!.eventMin
216+
)
217+
}
218+
}
219+
} else if (
220+
binding.writeRadioBtn.isChecked && writePath.isNotEmpty() && writeICDConfig != null
221+
) {
222+
scope.launch { write(writeICDConfig!!.timedRequestTimeoutMs, writeICDConfig!!.imTimeoutMs) }
223+
} else if (
224+
binding.invokeRadioBtn.isChecked && invokePath.isNotEmpty() && invokeICDConfig != null
225+
) {
226+
scope.launch {
227+
invoke(invokeICDConfig!!.timedRequestTimeoutMs, invokeICDConfig!!.imTimeoutMs)
228+
}
229+
}
230+
}
231+
176232
private fun setVisibilityEachView(radioBtnId: Int) {
177233
val readBtnOn = (radioBtnId == R.id.readRadioBtn)
178234
val subscribeBtnOn = (radioBtnId == R.id.subscribeRadioBtn)
@@ -520,7 +576,12 @@ class WildcardFragment : Fragment() {
520576
if (eventPath.isNotEmpty() && eventMinEd.text.isNotBlank()) {
521577
eventMin = eventMinEd.text.toString().toULong().toLong()
522578
}
523-
read(isFabricFilteredEd.selectedItem.toString().toBoolean(), eventMin)
579+
if (addressUpdateFragment.isICDDevice()) {
580+
readICDConfig =
581+
ReadICDConfig(isFabricFilteredEd.selectedItem.toString().toBoolean(), eventMin)
582+
} else {
583+
read(isFabricFilteredEd.selectedItem.toString().toBoolean(), eventMin)
584+
}
524585
requireActivity().runOnUiThread { dialog.dismiss() }
525586
}
526587
}
@@ -537,18 +598,23 @@ class WildcardFragment : Fragment() {
537598
dialogView.findViewById<EditText>(R.id.timedRequestTimeoutEd).text.toString()
538599
val imTimeout = dialogView.findViewById<EditText>(R.id.imTimeoutEd).text.toString()
539600
scope.launch {
540-
write(
601+
val timedRequestTimeoutInt =
541602
if (timedRequestTimeoutMs.isEmpty()) {
542603
0
543604
} else {
544605
timedRequestTimeoutMs.toInt()
545-
},
606+
}
607+
val imTimeoutInt =
546608
if (imTimeout.isEmpty()) {
547609
0
548610
} else {
549611
imTimeout.toInt()
550612
}
551-
)
613+
if (addressUpdateFragment.isICDDevice()) {
614+
writeICDConfig = WriteInvokeICDConfig(timedRequestTimeoutInt, imTimeoutInt)
615+
} else {
616+
write(timedRequestTimeoutInt, imTimeoutInt)
617+
}
552618
requireActivity().runOnUiThread { dialog.dismiss() }
553619
}
554620
}
@@ -588,13 +654,24 @@ class WildcardFragment : Fragment() {
588654
if (eventPath.isNotEmpty() && eventMinEd.text.isNotBlank()) {
589655
eventMin = eventMinEd.text.toString().toULong().toLong()
590656
}
591-
subscribe(
592-
minIntervalEd.text.toString().toInt(),
593-
maxIntervalEd.text.toString().toInt(),
594-
keepSubscriptionsSp.selectedItem.toString().toBoolean(),
595-
isFabricFilteredSp.selectedItem.toString().toBoolean(),
596-
eventMin,
597-
)
657+
if (addressUpdateFragment.isICDDevice()) {
658+
subscribeICDConfig =
659+
SubscribeICDConfig(
660+
minIntervalEd.text.toString().toInt(),
661+
maxIntervalEd.text.toString().toInt(),
662+
keepSubscriptionsSp.selectedItem.toString().toBoolean(),
663+
isFabricFilteredSp.selectedItem.toString().toBoolean(),
664+
eventMin
665+
)
666+
} else {
667+
subscribe(
668+
minIntervalEd.text.toString().toInt(),
669+
maxIntervalEd.text.toString().toInt(),
670+
keepSubscriptionsSp.selectedItem.toString().toBoolean(),
671+
isFabricFilteredSp.selectedItem.toString().toBoolean(),
672+
eventMin
673+
)
674+
}
598675
} else {
599676
Log.e(TAG, "minInterval or maxInterval is empty!")
600677
}
@@ -614,18 +691,23 @@ class WildcardFragment : Fragment() {
614691
dialogView.findViewById<EditText>(R.id.timedRequestTimeoutEd).text.toString()
615692
val imTimeout = dialogView.findViewById<EditText>(R.id.imTimeoutEd).text.toString()
616693
scope.launch {
617-
invoke(
694+
val timedRequestTimeoutInt =
618695
if (timedRequestTimeoutMs.isEmpty()) {
619696
0
620697
} else {
621698
timedRequestTimeoutMs.toInt()
622-
},
699+
}
700+
val imTimeoutInt =
623701
if (imTimeout.isEmpty()) {
624702
0
625703
} else {
626704
imTimeout.toInt()
627705
}
628-
)
706+
if (addressUpdateFragment.isICDDevice()) {
707+
invokeICDConfig = WriteInvokeICDConfig(timedRequestTimeoutInt, imTimeoutInt)
708+
} else {
709+
invoke(timedRequestTimeoutInt, imTimeoutInt)
710+
}
629711
requireActivity().runOnUiThread { dialog.dismiss() }
630712
}
631713
}

kotlin-detect-config.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ complexity:
343343
- "**/src/controller/java/tests/matter/tlv/TlvReaderTest.kt"
344344
LargeClass:
345345
excludes:
346+
- "**/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt"
346347
- "**/src/controller/java/generated/java/**/*"
347348
- "**/src/controller/java/tests/matter/tlv/TlvReadWriteTest.kt"
348349
- "**/src/controller/java/tests/matter/jsontlv/JsonToTlvToJsonTest.kt"

0 commit comments

Comments
 (0)