Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] Add isUrgent option in Android #25301

Merged
merged 3 commits into from
Feb 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import android.view.ViewGroup
import android.widget.Button
import android.widget.EditText
import android.widget.Spinner
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import chip.devicecontroller.ChipDeviceController
Expand Down Expand Up @@ -114,7 +115,7 @@ class WildcardFragment : Fragment() {
return stringBuilder.toString()
}

private suspend fun subscribe(type: Int, minInterval: Int, maxInterval: Int, keepSubscriptions: Boolean, isFabricFiltered: Boolean) {
private suspend fun subscribe(type: Int, minInterval: Int, maxInterval: Int, keepSubscriptions: Boolean, isFabricFiltered: Boolean, isUrgent: Boolean) {
val subscriptionEstablishedCallback =
SubscriptionEstablishedCallback { Log.i(TAG, "Subscription to device established") }

Expand All @@ -141,7 +142,7 @@ class WildcardFragment : Fragment() {
keepSubscriptions,
isFabricFiltered)
} else if (type == EVENT) {
val eventPath = ChipEventPath.newInstance(endpointId, clusterId, eventId)
val eventPath = ChipEventPath.newInstance(endpointId, clusterId, eventId, isUrgent)
deviceController.subscribeToPath(subscriptionEstablishedCallback,
resubscriptionAttemptCallback,
reportCallback,
Expand Down Expand Up @@ -199,6 +200,15 @@ class WildcardFragment : Fragment() {

private fun showSubscribeDialog(type: Int) {
val dialogView = requireActivity().layoutInflater.inflate(R.layout.subscribe_dialog, null)
val isUrgentTv = dialogView.findViewById<TextView>(R.id.titleisUrgent)
val isUrgentSp = dialogView.findViewById<Spinner>(R.id.isUrgentSp)
if (type == EVENT) {
isUrgentTv.visibility = View.VISIBLE
isUrgentSp.visibility = View.VISIBLE
} else {
isUrgentTv.visibility = View.GONE
isUrgentSp.visibility = View.GONE
}
val dialog = AlertDialog.Builder(requireContext()).apply {
setView(dialogView)
}.create()
Expand All @@ -215,7 +225,8 @@ class WildcardFragment : Fragment() {
minIntervalEd.text.toString().toInt(),
maxIntervalEd.text.toString().toInt(),
keepSubscriptionsSp.selectedItem.toString().toBoolean(),
isFabricFilteredSp.selectedItem.toString().toBoolean()
isFabricFilteredSp.selectedItem.toString().toBoolean(),
isUrgentSp.selectedItem.toString().toBoolean(),
)
} else {
Log.e(TAG, "minInterval or maxInterval is empty!" )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,28 @@
android:layout_marginBottom="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/minIntervalEd" />
<TextView
android:id="@+id/titleisUrgent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/subscribe_dialog_is_urgent_hint"
android:textSize="16sp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/maxIntervalEd"
/>
<Spinner
android:id="@+id/isUrgentSp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/subscribe_dialog_is_urgent_hint"
android:entries="@array/chip_select_menu"
android:inputType="text"
android:spinnerMode="dropdown"
android:textSize="16sp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleisUrgent" />
<TextView
android:id="@+id/titleKeepSubscriptions"
android:layout_width="match_parent"
Expand All @@ -42,7 +64,7 @@
android:textSize="16sp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/maxIntervalEd"
app:layout_constraintTop_toBottomOf="@id/isUrgentSp"
/>
<Spinner
android:id="@+id/keepSubscriptionsSp"
Expand All @@ -56,7 +78,6 @@
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleKeepSubscriptions" />

<TextView
android:id="@+id/titleIsFabricFilter"
android:layout_width="match_parent"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@
<string name="subscribe_dialog_subscribe_btn_text">Subscribe</string>
<string name="subscribe_dialog_min_interval_hint">Minimum interval (seconds)</string>
<string name="subscribe_dialog_max_interval_hint">Maximum interval (seconds)</string>
<string name="subscribe_dialog_is_urgent_hint">is Urgent Event (bool)</string>
<string name="subscribe_dialog_keep_subscriptions_hint">keep subscriptions (bool)</string>
<string name="subscribe_dialog_is_fabric_filtered_hint">is Fabric Filtered (bool)</string>

Expand Down
15 changes: 11 additions & 4 deletions src/controller/java/CHIPDeviceController-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ static CHIP_ERROR ParseAttributePathList(jobject attributePathList,
static CHIP_ERROR ParseAttributePath(jobject attributePath, EndpointId & outEndpointId, ClusterId & outClusterId,
AttributeId & outAttributeId);
static CHIP_ERROR ParseEventPathList(jobject eventPathList, std::vector<app::EventPathParams> & outEventPathParamsList);
static CHIP_ERROR ParseEventPath(jobject eventPath, EndpointId & outEndpointId, ClusterId & outClusterId, EventId & outEventId);
static CHIP_ERROR ParseEventPath(jobject eventPath, EndpointId & outEndpointId, ClusterId & outClusterId, EventId & outEventId,
bool & outIsUrgent);
static CHIP_ERROR IsWildcardChipPathId(jobject chipPathId, bool & isWildcard);
static CHIP_ERROR CreateDeviceAttestationDelegateBridge(JNIEnv * env, jlong handle, jobject deviceAttestationDelegate,
jint failSafeExpiryTimeoutSecs,
Expand Down Expand Up @@ -1376,34 +1377,39 @@ CHIP_ERROR ParseEventPathList(jobject eventPathList, std::vector<app::EventPathP
EndpointId endpointId;
ClusterId clusterId;
EventId eventId;
ReturnErrorOnFailure(ParseEventPath(eventPathItem, endpointId, clusterId, eventId));
outEventPathParamsList.push_back(app::EventPathParams(endpointId, clusterId, eventId));
bool isUrgent;
ReturnErrorOnFailure(ParseEventPath(eventPathItem, endpointId, clusterId, eventId, isUrgent));
outEventPathParamsList.push_back(app::EventPathParams(endpointId, clusterId, eventId, isUrgent));
}

return CHIP_NO_ERROR;
}

CHIP_ERROR ParseEventPath(jobject eventPath, EndpointId & outEndpointId, ClusterId & outClusterId, EventId & outEventId)
CHIP_ERROR ParseEventPath(jobject eventPath, EndpointId & outEndpointId, ClusterId & outClusterId, EventId & outEventId,
bool & outIsUrgent)
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();

jmethodID getEndpointIdMethod = nullptr;
jmethodID getClusterIdMethod = nullptr;
jmethodID getEventIdMethod = nullptr;
jmethodID isUrgentMethod = nullptr;

ReturnErrorOnFailure(JniReferences::GetInstance().FindMethod(
env, eventPath, "getEndpointId", "()Lchip/devicecontroller/model/ChipPathId;", &getEndpointIdMethod));
ReturnErrorOnFailure(JniReferences::GetInstance().FindMethod(
env, eventPath, "getClusterId", "()Lchip/devicecontroller/model/ChipPathId;", &getClusterIdMethod));
ReturnErrorOnFailure(JniReferences::GetInstance().FindMethod(env, eventPath, "getEventId",
"()Lchip/devicecontroller/model/ChipPathId;", &getEventIdMethod));
ReturnErrorOnFailure(JniReferences::GetInstance().FindMethod(env, eventPath, "isUrgent", "()Z", &isUrgentMethod));

jobject endpointIdObj = env->CallObjectMethod(eventPath, getEndpointIdMethod);
VerifyOrReturnError(endpointIdObj != nullptr, CHIP_ERROR_INCORRECT_STATE);
jobject clusterIdObj = env->CallObjectMethod(eventPath, getClusterIdMethod);
VerifyOrReturnError(clusterIdObj != nullptr, CHIP_ERROR_INCORRECT_STATE);
jobject eventIdObj = env->CallObjectMethod(eventPath, getEventIdMethod);
VerifyOrReturnError(eventIdObj != nullptr, CHIP_ERROR_INCORRECT_STATE);
jboolean isUrgent = env->CallBooleanMethod(eventPath, isUrgentMethod);

uint32_t endpointId = 0;
ReturnErrorOnFailure(GetChipPathIdValue(endpointIdObj, kInvalidEndpointId, endpointId));
Expand All @@ -1415,6 +1421,7 @@ CHIP_ERROR ParseEventPath(jobject eventPath, EndpointId & outEndpointId, Cluster
outEndpointId = static_cast<EndpointId>(endpointId);
outClusterId = static_cast<ClusterId>(clusterId);
outEventId = static_cast<EventId>(eventId);
outIsUrgent = (isUrgent == JNI_TRUE);

return CHIP_NO_ERROR;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@
/** An event path that should be used for requests. */
public class ChipEventPath {
private ChipPathId endpointId, clusterId, eventId;
private boolean isUrgent;

private ChipEventPath(ChipPathId endpointId, ChipPathId clusterId, ChipPathId eventId) {
private ChipEventPath(
ChipPathId endpointId, ChipPathId clusterId, ChipPathId eventId, boolean isUrgent) {
this.endpointId = endpointId;
this.clusterId = clusterId;
this.eventId = eventId;
this.isUrgent = isUrgent;
}

public ChipPathId getEndpointId() {
Expand All @@ -42,36 +45,64 @@ public ChipPathId getEventId() {
return eventId;
}

public boolean isUrgent() {
return isUrgent;
}

@Override
public boolean equals(Object object) {
if (object instanceof ChipEventPath) {
ChipEventPath that = (ChipEventPath) object;
return Objects.equals(this.endpointId, that.endpointId)
&& Objects.equals(this.clusterId, that.clusterId)
&& Objects.equals(this.eventId, that.eventId);
&& Objects.equals(this.eventId, that.eventId)
&& (this.isUrgent == that.isUrgent);
}
return false;
}

@Override
public int hashCode() {
return Objects.hash(endpointId, clusterId, eventId);
return Objects.hash(endpointId, clusterId, eventId, isUrgent);
}

@Override
public String toString() {
return String.format(
Locale.ENGLISH, "Endpoint %s, cluster %s, event %s", endpointId, clusterId, eventId);
Locale.ENGLISH,
"Endpoint %s, cluster %s, event %s, isUrgent %s",
endpointId,
clusterId,
eventId,
isUrgent ? "true" : "false");
}

public static ChipEventPath newInstance(
ChipPathId endpointId, ChipPathId clusterId, ChipPathId eventId) {
return new ChipEventPath(endpointId, clusterId, eventId);
return new ChipEventPath(endpointId, clusterId, eventId, false);
}

/** Create a new {@link ChipEventPath} with only concrete ids. */
public static ChipEventPath newInstance(long endpointId, long clusterId, long eventId) {
return new ChipEventPath(
ChipPathId.forId(endpointId), ChipPathId.forId(clusterId), ChipPathId.forId(eventId));
ChipPathId.forId(endpointId),
ChipPathId.forId(clusterId),
ChipPathId.forId(eventId),
false);
}

public static ChipEventPath newInstance(
ChipPathId endpointId, ChipPathId clusterId, ChipPathId eventId, boolean isUrgent) {
return new ChipEventPath(endpointId, clusterId, eventId, isUrgent);
}

/** Create a new {@link ChipEventPath} with only concrete ids. */
public static ChipEventPath newInstance(
long endpointId, long clusterId, long eventId, boolean isUrgent) {
return new ChipEventPath(
ChipPathId.forId(endpointId),
ChipPathId.forId(clusterId),
ChipPathId.forId(eventId),
isUrgent);
}
}