Skip to content

Commit

Permalink
Implement unpairDevice API in android and chip-tool (#24127)
Browse files Browse the repository at this point in the history
* Implement unpairDevice

* Check restyle

* Delete unused file

* Add default value

* Update from review

* Modify from reviewer comments

* Modify from comment

* Fix clang-tidy validation

* Change check state
  • Loading branch information
joonhaengHeo authored and pull[bot] committed Feb 8, 2024
1 parent eafdd5e commit 3769891
Show file tree
Hide file tree
Showing 18 changed files with 634 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import com.google.chip.chiptool.provisioning.AddressCommissioningFragment
import com.google.chip.chiptool.provisioning.DeviceProvisioningFragment
import com.google.chip.chiptool.provisioning.EnterNetworkFragment
import com.google.chip.chiptool.provisioning.ProvisionNetworkType
import com.google.chip.chiptool.provisioning.UnpairDeviceFragment
import com.google.chip.chiptool.setuppayloadscanner.BarcodeFragment
import com.google.chip.chiptool.setuppayloadscanner.CHIPDeviceDetailsFragment
import com.google.chip.chiptool.setuppayloadscanner.CHIPDeviceInfo
Expand Down Expand Up @@ -191,6 +192,10 @@ class CHIPToolActivity :
showFragment(BarcodeFragment.newInstance())
}

override fun handleUnpairDeviceClicked() {
showFragment(UnpairDeviceFragment.newInstance())
}

private fun showFragment(fragment: Fragment, showOnBack: Boolean = true) {
val fragmentTransaction = supportFragmentManager
.beginTransaction()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class SelectActionFragment : Fragment() {
clusterInteractionBtn.setOnClickListener { getCallback()?.handleClusterInteractionClicked() }
provisionCustomFlowBtn.setOnClickListener{ getCallback()?.handleCustomFlowClicked() }
wildcardBtn.setOnClickListener { getCallback()?.handleWildcardClicked() }
unpairDeviceBtn.setOnClickListener{ getCallback()?.handleUnpairDeviceClicked() }
}
}

Expand Down Expand Up @@ -157,6 +158,8 @@ class SelectActionFragment : Fragment() {
fun handleWildcardClicked()
/** Notifies listener of provision-custom-flow button click. */
fun handleCustomFlowClicked()
/** Notifies listener of unpair button click. */
fun handleUnpairDeviceClicked()
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.google.chip.chiptool.provisioning

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import chip.devicecontroller.ChipDeviceController
import chip.devicecontroller.UnpairDeviceCallback
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.R
import com.google.chip.chiptool.clusterclient.AddressUpdateFragment
import kotlinx.android.synthetic.main.unpair_device_fragment.view.unpairDeviceBtn
import kotlinx.coroutines.*

class UnpairDeviceFragment : Fragment() {
private val deviceController: ChipDeviceController
get() = ChipClient.getDeviceController(requireContext())

private lateinit var scope: CoroutineScope

private lateinit var addressUpdateFragment: AddressUpdateFragment

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
scope = viewLifecycleOwner.lifecycleScope

return inflater.inflate(R.layout.unpair_device_fragment, container, false).apply {
addressUpdateFragment =
childFragmentManager.findFragmentById(R.id.addressUpdateFragment) as AddressUpdateFragment

unpairDeviceBtn.setOnClickListener { scope.launch { unpairDeviceClick() } }
}
}

inner class ChipUnpairDeviceCallback : UnpairDeviceCallback {
override fun onError(status: Int, remoteDeviceId: Long) {
Log.d(TAG, "onError : $remoteDeviceId, $status")
}

override fun onSuccess(remoteDeviceId: Long) {
Log.d(TAG, "onSuccess : $remoteDeviceId")
}
}

private fun unpairDeviceClick() {
deviceController.unpairDeviceCallback(addressUpdateFragment.deviceId, ChipUnpairDeviceCallback())
}


companion object {
private const val TAG = "UnpairDeviceFragment"
fun newInstance(): UnpairDeviceFragment = UnpairDeviceFragment()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@
android:layout_marginTop="8dp"
android:text="@string/cluster_interaction_tool" />

<Button
android:id="@+id/unpairDeviceBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/unpair_device_btn_text" />

</LinearLayout>

</ScrollView>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">

<androidx.fragment.app.FragmentContainerView
android:id="@+id/addressUpdateFragment"
android:name="com.google.chip.chiptool.clusterclient.AddressUpdateFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

<Button
android:id="@+id/unpairDeviceBtn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/unpair_device_btn_text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/addressUpdateFragment"/>

</androidx.constraintlayout.widget.ConstraintLayout>
2 changes: 2 additions & 0 deletions examples/android/CHIPTool/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,6 @@
<string name="select_a_cluster">Select a cluster</string>
<string name="endpoint_name">Endpoint: </string>
<string name="wifi_connect_btn_text">Connect</string>

<string name="unpair_device_btn_text">Unpair</string>
</resources>
22 changes: 19 additions & 3 deletions examples/chip-tool/commands/pairing/PairingCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,8 @@ CHIP_ERROR PairingCommand::PairWithMdns(NodeId remoteId)

CHIP_ERROR PairingCommand::Unpair(NodeId remoteId)
{
CHIP_ERROR err = CurrentCommissioner().UnpairDevice(remoteId);
SetCommandExitStatus(err);
return err;
mCurrentFabricRemover = Platform::MakeUnique<Controller::CurrentFabricRemover>(&CurrentCommissioner());
return mCurrentFabricRemover->RemoveCurrentFabric(remoteId, &mCurrentFabricRemoveCallback);
}

void PairingCommand::OnStatusUpdate(DevicePairingDelegate::Status status)
Expand Down Expand Up @@ -265,3 +264,20 @@ void PairingCommand::OnDiscoveredDevice(const chip::Dnssd::DiscoveredNodeData &
SetCommandExitStatus(err);
}
}

void PairingCommand::OnCurrentFabricRemove(void * context, NodeId nodeId, CHIP_ERROR err)
{
PairingCommand * command = reinterpret_cast<PairingCommand *>(context);
VerifyOrReturn(command != nullptr, ChipLogError(chipTool, "OnCurrentFabricRemove: context is null"));

if (err == CHIP_NO_ERROR)
{
ChipLogProgress(chipTool, "Device unpair completed with success: " ChipLogFormatX64, ChipLogValueX64(nodeId));
}
else
{
ChipLogProgress(chipTool, "Device unpair Failure: " ChipLogFormatX64 " %s", ChipLogValueX64(nodeId), ErrorStr(err));
}

command->SetCommandExitStatus(err);
}
10 changes: 9 additions & 1 deletion examples/chip-tool/commands/pairing/PairingCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "../common/CHIPCommand.h"
#include <controller/CommissioningDelegate.h>
#include <controller/CurrentFabricRemover.h>
#include <zap-generated/CHIPClusters.h>

#include <commands/common/CredentialIssuerCommands.h>
Expand Down Expand Up @@ -55,7 +56,8 @@ class PairingCommand : public CHIPCommand,
chip::Dnssd::DiscoveryFilterType filterType = chip::Dnssd::DiscoveryFilterType::kNone) :
CHIPCommand(commandName, credIssuerCmds),
mPairingMode(mode), mNetworkType(networkType),
mFilterType(filterType), mRemoteAddr{ IPAddress::Any, chip::Inet::InterfaceId::Null() }
mFilterType(filterType), mRemoteAddr{ IPAddress::Any, chip::Inet::InterfaceId::Null() },
mCurrentFabricRemoveCallback(OnCurrentFabricRemove, this)
{
AddArgument("node-id", 0, UINT64_MAX, &mNodeId);

Expand Down Expand Up @@ -184,4 +186,10 @@ class PairingCommand : public CHIPCommand,
char * mOnboardingPayload;
uint64_t mDiscoveryFilterCode;
char * mDiscoveryFilterInstanceName;

// For unpair
chip::Platform::UniquePtr<chip::Controller::CurrentFabricRemover> mCurrentFabricRemover;
chip::Callback::Callback<chip::Controller::OnCurrentFabricRemove> mCurrentFabricRemoveCallback;

static void OnCurrentFabricRemove(void * context, NodeId remoteNodeId, CHIP_ERROR status);
};
2 changes: 2 additions & 0 deletions src/controller/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ static_library("controller") {
"CommissioningDelegate.cpp",
"CommissioningWindowOpener.cpp",
"CommissioningWindowOpener.h",
"CurrentFabricRemover.cpp",
"CurrentFabricRemover.h",
"DeviceDiscoveryDelegate.h",
"DevicePairingDelegate.h",
"EmptyDataModelHandler.cpp",
Expand Down
7 changes: 5 additions & 2 deletions src/controller/CHIPDeviceController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include <app/InteractionModelEngine.h>
#include <app/OperationalSessionSetup.h>
#include <app/util/error-mapping.h>
#include <controller/CurrentFabricRemover.h>
#include <credentials/CHIPCert.h>
#include <credentials/DeviceAttestationCredsProvider.h>
#include <crypto/CHIPCryptoPAL.h>
Expand Down Expand Up @@ -894,8 +895,10 @@ CHIP_ERROR DeviceCommissioner::StopPairing(NodeId remoteDeviceId)

CHIP_ERROR DeviceCommissioner::UnpairDevice(NodeId remoteDeviceId)
{
// TODO: Send unpairing message to the remote device.
return CHIP_NO_ERROR;
MATTER_TRACE_EVENT_SCOPE("UnpairDevice", "DeviceCommissioner");
VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE);

return AutoCurrentFabricRemover::RemoveCurrentFabric(this, remoteDeviceId);
}

void DeviceCommissioner::RendezvousCleanup(CHIP_ERROR status)
Expand Down
Loading

0 comments on commit 3769891

Please sign in to comment.