Skip to content

Commit

Permalink
[Android] Add isUrgent option in Android (#25301)
Browse files Browse the repository at this point in the history
* Implement Android isUrgent flag

* Support isUrgent in Android

* Restyle
  • Loading branch information
joonhaengHeo authored Feb 28, 2023
1 parent 73ada56 commit d4647c3
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 15 deletions.
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 @@ -1436,34 +1437,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 @@ -1475,6 +1481,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);
}
}

0 comments on commit d4647c3

Please sign in to comment.