Skip to content

Commit f290f6e

Browse files
yufengwangcaDavid Lechner
authored and
David Lechner
committed
[Andriod] Remove extra sub-interface layer from DeviceAttestationDelegate interface (project-chip#24771)
* Remove DeviceAttestationCompletionCallback and DeviceAttestationFailureCallback sub-interfaces from DeviceAttestationDelegate * Address review comments * Move DeviceController init from onCreateView() to onCreate()
1 parent 65e0159 commit f290f6e

File tree

5 files changed

+107
-123
lines changed

5 files changed

+107
-123
lines changed

examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt

+67-31
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ import androidx.appcompat.app.AlertDialog
3030
import androidx.fragment.app.Fragment
3131
import androidx.lifecycle.lifecycleScope
3232
import chip.devicecontroller.AttestationInfo
33-
import chip.devicecontroller.DeviceAttestationDelegate.DeviceAttestationCompletionCallback
34-
import chip.devicecontroller.DeviceAttestationDelegate.DeviceAttestationFailureCallback
33+
import chip.devicecontroller.ChipDeviceController
34+
import chip.devicecontroller.DeviceAttestationDelegate
3535
import chip.devicecontroller.NetworkCredentials
3636
import com.google.chip.chiptool.NetworkCredentialsParcelable
3737
import com.google.chip.chiptool.ChipClient
@@ -57,15 +57,23 @@ class DeviceProvisioningFragment : Fragment() {
5757
private val networkCredentialsParcelable: NetworkCredentialsParcelable?
5858
get() = arguments?.getParcelable(ARG_NETWORK_CREDENTIALS)
5959

60+
private lateinit var deviceController: ChipDeviceController
61+
6062
private lateinit var scope: CoroutineScope
6163

64+
override fun onCreate(savedInstanceState: Bundle?) {
65+
super.onCreate(savedInstanceState)
66+
deviceController = ChipClient.getDeviceController(requireContext())
67+
}
68+
6269
override fun onCreateView(
6370
inflater: LayoutInflater,
6471
container: ViewGroup?,
6572
savedInstanceState: Bundle?
6673
): View {
6774
scope = viewLifecycleOwner.lifecycleScope
6875
deviceInfo = checkNotNull(requireArguments().getParcelable(ARG_DEVICE_INFO))
76+
6977
return inflater.inflate(R.layout.single_fragment_container, container, false).apply {
7078
if (savedInstanceState == null) {
7179
if (deviceInfo.ipAddress != null) {
@@ -82,13 +90,65 @@ class DeviceProvisioningFragment : Fragment() {
8290
gatt = null
8391
}
8492

93+
override fun onDestroy() {
94+
super.onDestroy()
95+
deviceController.close()
96+
deviceController.setDeviceAttestationDelegate(0, EmptyAttestationDelegate())
97+
}
98+
99+
private class EmptyAttestationDelegate : DeviceAttestationDelegate {
100+
override fun onDeviceAttestationCompleted(
101+
devicePtr: Long,
102+
attestationInfo: AttestationInfo,
103+
errorCode: Int) {}
104+
}
105+
106+
private fun setAttestationDelegate() {
107+
deviceController.setDeviceAttestationDelegate(DEVICE_ATTESTATION_FAILED_TIMEOUT
108+
) { devicePtr, attestationInfo, errorCode ->
109+
Log.i(TAG, "Device attestation errorCode: $errorCode, " +
110+
"Look at 'src/credentials/attestation_verifier/DeviceAttestationVerifier.h' " +
111+
"AttestationVerificationResult enum to understand the errors")
112+
113+
val activity = requireActivity()
114+
115+
if (errorCode == STATUS_PAIRING_SUCCESS) {
116+
activity.runOnUiThread(Runnable {
117+
deviceController.continueCommissioning(devicePtr, true)
118+
})
119+
120+
return@setDeviceAttestationDelegate
121+
}
122+
123+
activity.runOnUiThread(Runnable {
124+
val dialog = AlertDialog.Builder(activity)
125+
.setPositiveButton("Continue",
126+
DialogInterface.OnClickListener { dialog, id ->
127+
deviceController.continueCommissioning(devicePtr, true)
128+
})
129+
.setNegativeButton("No",
130+
DialogInterface.OnClickListener { dialog, id ->
131+
deviceController.continueCommissioning(devicePtr, false)
132+
})
133+
.setTitle("Device Attestation")
134+
.setMessage("Device Attestation failed for device under commissioning. Do you wish to continue pairing?")
135+
.create()
136+
137+
dialog.show()
138+
})
139+
}
140+
}
141+
85142
private fun pairDeviceWithAddress() {
86143
// IANA CHIP port
87144
val port = 5540
88145
val id = DeviceIdUtil.getNextAvailableId(requireContext())
89-
val deviceController = ChipClient.getDeviceController(requireContext())
146+
90147
DeviceIdUtil.setNextAvailableId(requireContext(), id + 1)
91148
deviceController.setCompletionListener(ConnectionCallback())
149+
150+
setAttestationDelegate()
151+
92152
deviceController.pairDeviceWithAddress(
93153
id,
94154
deviceInfo.ipAddress,
@@ -103,9 +163,7 @@ class DeviceProvisioningFragment : Fragment() {
103163
if (gatt != null) {
104164
return
105165
}
106-
107166
scope.launch {
108-
val deviceController = ChipClient.getDeviceController(requireContext())
109167
val bluetoothManager = BluetoothManager()
110168

111169
showMessage(
@@ -135,36 +193,14 @@ class DeviceProvisioningFragment : Fragment() {
135193
if (wifi != null) {
136194
network = NetworkCredentials.forWiFi(NetworkCredentials.WiFiCredentials(wifi.ssid, wifi.password))
137195
}
196+
138197
val thread = networkParcelable.threadCredentials
139198
if (thread != null) {
140199
network = NetworkCredentials.forThread(NetworkCredentials.ThreadCredentials(thread.operationalDataset))
141200
}
142-
deviceController.setDeviceAttestationFailureCallback(DEVICE_ATTESTATION_FAILED_TIMEOUT
143-
) { devicePtr, errorCode ->
144-
Log.i(TAG, "Device attestation errorCode: $errorCode, " +
145-
"Look at 'src/credentials/attestation_verifier/DeviceAttestationVerifier.h' " +
146-
"AttestationVerificationResult enum to understand the errors")
147-
requireActivity().runOnUiThread(Runnable {
148-
val alertDialog: AlertDialog? = activity?.let {
149-
val builder = AlertDialog.Builder(it)
150-
builder.apply {
151-
setPositiveButton("Continue",
152-
DialogInterface.OnClickListener { dialog, id ->
153-
deviceController.continueCommissioning(devicePtr, true)
154-
})
155-
setNegativeButton("No",
156-
DialogInterface.OnClickListener { dialog, id ->
157-
deviceController.continueCommissioning(devicePtr, false)
158-
})
159-
}
160-
builder.setTitle("Device Attestation")
161-
builder.setMessage("Device Attestation failed for device under commissioning. Do you wish to continue pairing?")
162-
// Create the AlertDialog
163-
builder.create()
164-
}
165-
alertDialog?.show()
166-
})
167-
}
201+
202+
setAttestationDelegate()
203+
168204
deviceController.pairDevice(gatt, connId, deviceId, deviceInfo.setupPinCode, network)
169205
DeviceIdUtil.setNextAvailableId(requireContext(), deviceId + 1)
170206
}

src/controller/java/CHIPDeviceController-JNI.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -1555,14 +1555,14 @@ CHIP_ERROR CreateDeviceAttestationDelegateBridge(JNIEnv * env, jlong handle, job
15551555
CHIP_ERROR err = CHIP_NO_ERROR;
15561556
chip::Optional<uint16_t> timeoutSecs = chip::MakeOptional(static_cast<uint16_t>(failSafeExpiryTimeoutSecs));
15571557
bool shouldWaitAfterDeviceAttestation = false;
1558-
jclass completionCallbackCls = nullptr;
1558+
jclass deviceAttestationDelegateCls = nullptr;
15591559
jobject deviceAttestationDelegateRef = env->NewGlobalRef(deviceAttestationDelegate);
1560+
15601561
VerifyOrExit(deviceAttestationDelegateRef != nullptr, err = CHIP_JNI_ERROR_NULL_OBJECT);
1561-
JniReferences::GetInstance().GetClassRef(
1562-
env, "chip/devicecontroller/DeviceAttestationDelegate$DeviceAttestationCompletionCallback", completionCallbackCls);
1563-
VerifyOrExit(completionCallbackCls != nullptr, err = CHIP_JNI_ERROR_TYPE_NOT_FOUND);
1562+
JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/DeviceAttestationDelegate", deviceAttestationDelegateCls);
1563+
VerifyOrExit(deviceAttestationDelegateCls != nullptr, err = CHIP_JNI_ERROR_TYPE_NOT_FOUND);
15641564

1565-
if (env->IsInstanceOf(deviceAttestationDelegate, completionCallbackCls))
1565+
if (env->IsInstanceOf(deviceAttestationDelegate, deviceAttestationDelegateCls))
15661566
{
15671567
shouldWaitAfterDeviceAttestation = true;
15681568
}

src/controller/java/DeviceAttestationDelegateBridge.cpp

+8-23
Original file line numberDiff line numberDiff line change
@@ -71,19 +71,15 @@ void DeviceAttestationDelegateBridge::OnDeviceAttestationCompleted(
7171
mResult = attestationResult;
7272
if (mDeviceAttestationDelegate != nullptr)
7373
{
74-
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
75-
jclass completionCallbackCls = nullptr;
76-
JniReferences::GetInstance().GetClassRef(
77-
env, "chip/devicecontroller/DeviceAttestationDelegate$DeviceAttestationCompletionCallback", completionCallbackCls);
78-
VerifyOrReturn(completionCallbackCls != nullptr,
79-
ChipLogError(Controller, "Could not find device attestation completion callback class."));
80-
jclass failureCallbackCls = nullptr;
81-
JniReferences::GetInstance().GetClassRef(
82-
env, "chip/devicecontroller/DeviceAttestationDelegate$DeviceAttestationFailureCallback", failureCallbackCls);
83-
VerifyOrReturn(failureCallbackCls != nullptr,
84-
ChipLogError(Controller, "Could not find device attestation failure callback class."));
74+
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
75+
jclass deviceAttestationDelegateCls = nullptr;
8576

86-
if (env->IsInstanceOf(mDeviceAttestationDelegate, completionCallbackCls))
77+
JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/DeviceAttestationDelegate",
78+
deviceAttestationDelegateCls);
79+
VerifyOrReturn(deviceAttestationDelegateCls != nullptr,
80+
ChipLogError(Controller, "Could not find device attestation delegate class."));
81+
82+
if (env->IsInstanceOf(mDeviceAttestationDelegate, deviceAttestationDelegateCls))
8783
{
8884
jmethodID onDeviceAttestationCompletedMethod;
8985
JniReferences::GetInstance().FindMethod(env, mDeviceAttestationDelegate, "onDeviceAttestationCompleted",
@@ -98,17 +94,6 @@ void DeviceAttestationDelegateBridge::OnDeviceAttestationCompleted(
9894
env->CallVoidMethod(mDeviceAttestationDelegate, onDeviceAttestationCompletedMethod, reinterpret_cast<jlong>(device),
9995
javaAttestationInfo, static_cast<jint>(attestationResult));
10096
}
101-
else if ((attestationResult != chip::Credentials::AttestationVerificationResult::kSuccess) &&
102-
env->IsInstanceOf(mDeviceAttestationDelegate, failureCallbackCls))
103-
{
104-
jmethodID onDeviceAttestationFailedMethod;
105-
JniReferences::GetInstance().FindMethod(env, mDeviceAttestationDelegate, "onDeviceAttestationFailed", "(JI)V",
106-
&onDeviceAttestationFailedMethod);
107-
VerifyOrReturn(onDeviceAttestationFailedMethod != nullptr,
108-
ChipLogError(Controller, "Could not find deviceAttestation failed method"));
109-
env->CallVoidMethod(mDeviceAttestationDelegate, onDeviceAttestationFailedMethod, reinterpret_cast<jlong>(device),
110-
static_cast<jint>(attestationResult));
111-
}
11297
}
11398
}
11499

src/controller/java/src/chip/devicecontroller/ChipDeviceController.java

+10-29
Original file line numberDiff line numberDiff line change
@@ -85,42 +85,23 @@ public void setNOCChainIssuer(NOCChainIssuer issuer) {
8585
}
8686

8787
/**
88-
* If DeviceAttestationCompletionCallback is setted, then it will always be called when device
89-
* attestation completes.
88+
* If DeviceAttestationDelegate is setted, then it will always be called when device attestation
89+
* completes. In case the device attestation fails, the client can decide to continue or stop the
90+
* commissioning.
9091
*
91-
* <p>When {@link
92-
* DeviceAttestationDelegate.DeviceAttestationCompletionCallback#onDeviceAttestationCompleted(long,
93-
* long, AttestationInfo, int)} is received, {@link #continueCommissioning(long, boolean)} must be
92+
* <p>When {@link DeviceAttestationDelegate#onDeviceAttestationCompleted(long, long,
93+
* AttestationInfo, int)} is received, {@link #continueCommissioning(long, boolean)} must be
9494
* called.
9595
*
9696
* @param failSafeExpiryTimeoutSecs the value to set for the fail-safe timer before
9797
* onDeviceAttestationCompleted is invoked. The unit is seconds.
98-
* @param completionCallback the callback will be invoked when deviceattestation completed with
99-
* device info for additional verification.
98+
* @param deviceAttestationDelegate the delegate for device attestation completed with device info
99+
* for additional verification.
100100
*/
101-
public void setDeviceAttestationCompletionCallback(
102-
int failSafeExpiryTimeoutSecs,
103-
DeviceAttestationDelegate.DeviceAttestationCompletionCallback completionCallback) {
101+
public void setDeviceAttestationDelegate(
102+
int failSafeExpiryTimeoutSecs, DeviceAttestationDelegate deviceAttestationDelegate) {
104103
setDeviceAttestationDelegate(
105-
deviceControllerPtr, failSafeExpiryTimeoutSecs, completionCallback);
106-
}
107-
108-
/**
109-
* If DeviceAttestationFailureCallback is setted, then it will be called when device attestation
110-
* fails, and the client can decide to continue or stop the commissioning.
111-
*
112-
* <p>When {@link
113-
* DeviceAttestationDelegate.DeviceAttestationFailureCallback#onDeviceAttestationFailed(long,
114-
* long, int)} is received, {@link #continueCommissioning(long, boolean)} must be called.
115-
*
116-
* @param failSafeExpiryTimeoutSecs the value to set for the fail-safe timer before
117-
* onDeviceAttestationFailed is invoked. The unit is seconds.
118-
* @param failureCallback the callback will be invoked when device attestation failed.
119-
*/
120-
public void setDeviceAttestationFailureCallback(
121-
int failSafeExpiryTimeoutSecs,
122-
DeviceAttestationDelegate.DeviceAttestationFailureCallback failureCallback) {
123-
setDeviceAttestationDelegate(deviceControllerPtr, failSafeExpiryTimeoutSecs, failureCallback);
104+
deviceControllerPtr, failSafeExpiryTimeoutSecs, deviceAttestationDelegate);
124105
}
125106

126107
public void pairDevice(
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
package chip.devicecontroller;
22

33
/**
4-
* Only one of the following delegate callbacks should be implemented.
4+
* Delegate for device attestation verifiers.
55
*
6-
* <p>If one of the following callbacks is implemented, {@link
7-
* ChipDeviceController#continueCommissioning(long, boolean)} is expected to be called if
8-
* commissioning should continue.
6+
* <p>If DeviceAttestationDelegate is implemented, then onDeviceAttestationCompleted will always be
7+
* called when device attestation completes.
98
*
10-
* <p>If DeviceAttestationCompletionCallback is implemented, then it will always be called when
11-
* device attestation completes.
12-
*
13-
* <p>If DeviceAttestationFailureCallback is implemented, then it will be called when device
14-
* attestation fails, and the client can decide to continue or stop the commissioning.
9+
* <p>If device attestation fails, {@link ChipDeviceController#continueCommissioning(long, boolean)}
10+
* is expected to be called to continue or stop the commissioning.
1511
*
1612
* <p>For example:
1713
*
@@ -24,30 +20,16 @@
2420
* </pre>
2521
*/
2622
public interface DeviceAttestationDelegate {
27-
28-
public interface DeviceAttestationCompletionCallback extends DeviceAttestationDelegate {
29-
/**
30-
* The callback will be invoked when device attestation completed with device info for
31-
* additional verification.
32-
*
33-
* <p>This allows the callback to stop commissioning after examining the device info (DAC, PAI,
34-
* CD).
35-
*
36-
* @param devicePtr Handle of device being commissioned
37-
* @param attestationInfo Attestation information for the device
38-
* @param errorCode Error code on attestation failure. 0 if success.
39-
*/
40-
void onDeviceAttestationCompleted(
41-
long devicePtr, AttestationInfo attestationInfo, int errorCode);
42-
}
43-
44-
public interface DeviceAttestationFailureCallback extends DeviceAttestationDelegate {
45-
/**
46-
* The callback will be invoked when device attestation failed
47-
*
48-
* @param devicePtr Handle of device being commissioned
49-
* @param errorCode Error code for the failure.
50-
*/
51-
void onDeviceAttestationFailed(long devicePtr, int errorCode);
52-
}
23+
/**
24+
* The callback will be invoked when device attestation completed with device info for additional
25+
* verification.
26+
*
27+
* <p>This allows the callback to stop commissioning after examining the device info (DAC, PAI,
28+
* CD).
29+
*
30+
* @param devicePtr Handle of device being commissioned
31+
* @param attestationInfo Attestation information for the device, null is errorCode is 0.
32+
* @param errorCode Error code on attestation failure. 0 if succeed.
33+
*/
34+
void onDeviceAttestationCompleted(long devicePtr, AttestationInfo attestationInfo, int errorCode);
5335
}

0 commit comments

Comments
 (0)