Skip to content

Commit

Permalink
Get cluster info mapping (#10919)
Browse files Browse the repository at this point in the history
* basic code generation template, but not able to import to tool app

* create new public class under chip/clusterinfo

* change package

* no error code generation

* new design solution

* need to wait for cast-helper

* callback generation done

* on/off commands working

* revert .idea changes

* one more .idea change revert

* remove outline.java

* Restyled by whitespace

* Restyled by google-java-format

* Restyled by gn

* Restyled by google-java-format

* fix merge

* merge conflict

* fix comments

* Restyled by gn

* resolve type, nullable and format comments

* resolve build issues

* Restyled by gn

* update zap generated file

* add descriptive documentation on each new class

* Restyled by google-java-format

* modify description of each new added class

* Restyled by google-java-format

* add . at the end of class description

* Restyled by google-java-format

* rebase and regenerate script file

* merge with mbedos problem fixed

* rebase and try checks

* rebase master to see if pass checks

* retry checks

Co-authored-by: Restyled.io <commits@restyled.io>
  • Loading branch information
2 people authored and pull[bot] committed Nov 8, 2021
1 parent d05b85c commit edc87b1
Show file tree
Hide file tree
Showing 12 changed files with 7,457 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import chip.clusterinfo.ClusterCommandCallback
import chip.clusterinfo.ClusterInfo
import chip.clusterinfo.CommandInfo
import chip.devicecontroller.ChipDeviceController
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.GenericChipDeviceListener
Expand All @@ -15,12 +18,18 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import chip.devicecontroller.ClusterInfoMapping
import java.lang.Exception
import kotlinx.android.synthetic.main.cluster_interaction_fragment.view.getClusterMappingBtn
import kotlinx.coroutines.launch

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

private val scope = CoroutineScope(Dispatchers.Main + Job())
private lateinit var addressUpdateFragment: AddressUpdateFragment
private lateinit var clusterMap: Map<String, ClusterInfo>

override fun onCreateView(
inflater: LayoutInflater,
Expand All @@ -29,9 +38,43 @@ class ClusterInteractionFragment : Fragment() {
): View {
return inflater.inflate(R.layout.cluster_interaction_fragment, container, false).apply {
deviceController.setCompletionListener(ChipControllerCallback())
addressUpdateFragment =
childFragmentManager.findFragmentById(R.id.addressUpdateFragment) as AddressUpdateFragment
clusterMap = ClusterInfoMapping().clusterMap;
getClusterMappingBtn.setOnClickListener { scope.launch { getClusterMapping() } }
}
}

private suspend fun getClusterMapping() {
// In real code: "OnOff" would be selected by the user.
val methodSelected = "onOff"
showMessage(methodSelected + " is initialized")
val selectedClusterInfo = clusterMap[methodSelected]!!
val devicePtr =
ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId)
val endpointId = 1
val selectedCluster = selectedClusterInfo.createClusterFunction.create(devicePtr, endpointId)
// Imagine user wants to execute the command "OffWithEffect", pass the string here
val selectedCommandInfo: CommandInfo = selectedClusterInfo.commands["on"]!!

var selectedCommandCallback = selectedCommandInfo.commandCallbackSupplier.get()
selectedCommandCallback?.setCallbackDelegate(object : ClusterCommandCallback {
override fun onSuccess(responseValues: List<Any>) {
showMessage("Command success")
// Populate UI based on response values. We know the types from CommandInfo.getCommandResponses().
responseValues.forEach { Log.d(TAG, it.toString()) }
}

override fun onFailure(exception: Exception) {
showMessage("Command failed")
Log.e(TAG, exception.toString())
}
})

var commandArguments: HashMap<String, Any> = HashMap<String, Any>()
selectedCommandInfo.getCommandFunction().invokeCommand(selectedCluster, selectedCommandCallback, commandArguments)
}

private fun showMessage(msg: String) {
requireActivity().runOnUiThread {
Toast.makeText(requireContext(), msg, Toast.LENGTH_SHORT).show()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/clusterInteraction"
android:layout_width="match_parent"
android:layout_height="match_parent">

<Button
android:id="@+id/getClusterMappingBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="132dp"
android:layout_marginStart="16dp"
android:text="Button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<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_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/endpointList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="180dp"
android:clipToPadding="false"
android:layout_marginTop="48dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/addressUpdateFragment" />

Expand Down
6 changes: 6 additions & 0 deletions src/controller/java/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,19 @@ android_library("java") {
]

sources = [
"src/chip/clusterinfo/ClusterCommandCallback.java",
"src/chip/clusterinfo/ClusterInfo.java",
"src/chip/clusterinfo/CommandInfo.java",
"src/chip/clusterinfo/CommandParameterInfo.java",
"src/chip/clusterinfo/DelegatedClusterCallback.java",
"src/chip/devicecontroller/ChipClusterException.java",
"src/chip/devicecontroller/ChipCommandType.java",
"src/chip/devicecontroller/ChipDeviceController.java",
"src/chip/devicecontroller/ChipDeviceControllerException.java",
"src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java",
"src/chip/devicecontroller/PaseVerifierParams.java",
"zap-generated/chip/devicecontroller/ChipClusters.java",
"zap-generated/chip/devicecontroller/ClusterInfoMapping.java",
]

javac_flags = [ "-Xlint:deprecation" ]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package chip.clusterinfo;

import java.util.List;

/**
* Interface for making customized callback that implements both onSuccess and onFailure functions.
*/
public interface ClusterCommandCallback {
void onSuccess(List<Object> responseValues);

void onFailure(Exception exception);
}
33 changes: 33 additions & 0 deletions src/controller/java/src/chip/clusterinfo/ClusterInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package chip.clusterinfo;

import chip.devicecontroller.ChipClusters.BaseChipCluster;
import java.util.Map;

/** ClusterInfo maps commands and provides a constructor function for a cluster. */
public class ClusterInfo {
private final ClusterConstructor createClusterFunction;
private final Map<String, CommandInfo> commands;

public ClusterInfo(ClusterConstructor createClusterFunction, Map<String, CommandInfo> commands) {
this.createClusterFunction = createClusterFunction;
this.commands = commands;
}

public ClusterConstructor getCreateClusterFunction() {
return createClusterFunction;
}

public Map<String, CommandInfo> getCommands() {
return commands;
}

/**
* The functional interface provides a uniform way to create cluster through create function. In
* ClusterInfoMapping, each ClusterConstructor was generated using the intended function. Using
* lambda function, it only needs to have ptr and endpointId to create the intended cluster.
*/
@FunctionalInterface
public interface ClusterConstructor {
BaseChipCluster create(Long devicePtr, int endpointId);
}
}
49 changes: 49 additions & 0 deletions src/controller/java/src/chip/clusterinfo/CommandInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package chip.clusterinfo;

import chip.devicecontroller.ChipClusters.BaseChipCluster;
import java.util.Map;
import java.util.function.Supplier;

/**
* CommandInfo has a functional interface to invoke arbitrary commands based on cluster, callback
* and a map of arguments, a Supplier that provides {@link DelegatedClusterCallback}, and maps the
* parameter and commandParametersInfo.
*/
public class CommandInfo {
public ClusterCommandFunction commandFunction;
private Supplier<DelegatedClusterCallback> commandCallbackSupplier;
private Map<String, CommandParameterInfo> commandParameters;

public CommandInfo(
ClusterCommandFunction commandFunction,
Supplier<DelegatedClusterCallback> commandCallbackSupplier,
Map<String, CommandParameterInfo> commandParameters) {
this.commandFunction = commandFunction;
this.commandCallbackSupplier = commandCallbackSupplier;
this.commandParameters = commandParameters;
}

public ClusterCommandFunction getCommandFunction() {
return commandFunction;
}

public Supplier<DelegatedClusterCallback> getCommandCallbackSupplier() {
return commandCallbackSupplier;
}

public Map<String, CommandParameterInfo> getCommandParameters() {
return commandParameters;
}

/**
* The functional interface provides a uniform way to invoke commands through invokeCommand
* function. In ClusterInfoMapping, each ClusterCommandFunction was generated using the intended
* function. By using lambda function, the app component only needs to have cluster, callback,
* commandArguments to execute the correct function.
*/
@FunctionalInterface
public interface ClusterCommandFunction {
void invokeCommand(
BaseChipCluster cluster, Object callback, Map<String, Object> commandArguments);
}
}
14 changes: 14 additions & 0 deletions src/controller/java/src/chip/clusterinfo/CommandParameterInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package chip.clusterinfo;

/** CommandParameterInfo captures the name and type of a parameter */
public class CommandParameterInfo {
public CommandParameterInfo() {}

public CommandParameterInfo(String name, Class<?> type) {
this.name = name;
this.type = type;
}

public String name;
public Class<?> type;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package chip.clusterinfo;

/** Interface for a callback that delegates to {@link ClusterCommandCallback}. */
public interface DelegatedClusterCallback {
void setCallbackDelegate(ClusterCommandCallback callback);
}
Loading

0 comments on commit edc87b1

Please sign in to comment.