Skip to content

Commit 6d33ca4

Browse files
authored
Merge branch 'master' into feature/app-install-flow-public
2 parents bffb446 + d856745 commit 6d33ca4

File tree

6 files changed

+156
-64
lines changed

6 files changed

+156
-64
lines changed

examples/fabric-bridge-app/linux/Dockerfile

-25
This file was deleted.

examples/tv-app/android/App/platform-app/src/main/AndroidManifest.xml

+3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
tools:ignore="QueryAllPackagesPermission" />
2727
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
2828

29+
<uses-permission android:name="android.permission.GET_TASKS" />
30+
31+
2932
<application
3033
android:allowBackup="true"
3134
android:extractNativeLibs="true"

examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java

+40
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
package com.matter.tv.server.handlers;
22

3+
import android.app.ActivityManager;
34
import android.content.Context;
5+
import android.content.Intent;
46
import android.util.Log;
7+
import com.matter.tv.app.api.Clusters;
58
import com.matter.tv.server.model.ContentApp;
69
import com.matter.tv.server.receivers.ContentAppDiscoveryService;
710
import com.matter.tv.server.service.ContentAppAgentService;
811
import com.matter.tv.server.tvapp.ContentAppEndpointManager;
912
import com.matter.tv.server.utils.EndpointsDataStore;
1013
import java.util.Collection;
14+
import java.util.List;
1115

1216
public class ContentAppEndpointManagerImpl implements ContentAppEndpointManager {
1317

@@ -18,6 +22,31 @@ public ContentAppEndpointManagerImpl(Context context) {
1822
this.context = context;
1923
}
2024

25+
private boolean isForegroundCommand(long clusterId, long commandId) {
26+
switch ((int) clusterId) {
27+
case Clusters.ContentLauncher.Id:
28+
return commandId == Clusters.ContentLauncher.Commands.LaunchContent.ID
29+
|| commandId == Clusters.ContentLauncher.Commands.LaunchURL.ID;
30+
case Clusters.TargetNavigator.Id:
31+
return commandId == Clusters.TargetNavigator.Commands.NavigateTarget.ID;
32+
default:
33+
return false;
34+
}
35+
}
36+
37+
private boolean isAppInForeground(String contentAppPackageName) {
38+
ActivityManager activityManager =
39+
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
40+
List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(1);
41+
if (tasks != null && !tasks.isEmpty()) {
42+
ActivityManager.RunningTaskInfo taskInfo = tasks.get(0);
43+
String packageName =
44+
taskInfo.topActivity != null ? taskInfo.topActivity.getPackageName() : "";
45+
return packageName.equals(contentAppPackageName);
46+
}
47+
return false;
48+
}
49+
2150
public String sendCommand(int endpointId, long clusterId, long commandId, String commandPayload) {
2251
Log.d(TAG, "Received a command for endpointId " + endpointId + ". Message " + commandPayload);
2352

@@ -26,6 +55,17 @@ public String sendCommand(int endpointId, long clusterId, long commandId, String
2655
ContentAppDiscoveryService.getReceiverInstance().getDiscoveredContentApps().values(),
2756
endpointId);
2857
if (discoveredApp != null) {
58+
// Intercept NavigateTarget and LaunchContent commands and launch content app if necessary
59+
if (isForegroundCommand(clusterId, commandId)) {
60+
// Check if contentapp main/launch activity is already in foreground before launching.
61+
if (!isAppInForeground(discoveredApp.getAppName())) {
62+
Intent launchIntent =
63+
context.getPackageManager().getLaunchIntentForPackage(discoveredApp.getAppName());
64+
if (launchIntent != null) {
65+
context.startActivity(launchIntent);
66+
}
67+
}
68+
}
2969
Log.d(TAG, "Sending a command for endpointId " + endpointId + ". Message " + commandPayload);
3070
return ContentAppAgentService.sendCommand(
3171
context, discoveredApp.getAppName(), clusterId, commandId, commandPayload);

examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/model/ContentApp.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public ContentApp(
2525
this.vendorId = vendorId;
2626
this.productId = productId;
2727
this.version = version;
28+
this.supportedClusters = Collections.EMPTY_SET;
2829
}
2930

3031
public ContentApp(
@@ -67,9 +68,7 @@ public void setEndpointId(int endpoint) {
6768
}
6869

6970
public Set<SupportedCluster> getSupportedClusters() {
70-
return supportedClusters != null
71-
? Collections.unmodifiableSet(supportedClusters)
72-
: Collections.EMPTY_SET;
71+
return Collections.unmodifiableSet(supportedClusters);
7372
}
7473

7574
public String getVersion() {

examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java

+111-14
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@
55
import android.util.JsonReader;
66
import android.util.JsonWriter;
77
import android.util.Log;
8+
import com.matter.tv.app.api.SupportedCluster;
89
import com.matter.tv.server.model.ContentApp;
910
import java.io.IOException;
1011
import java.io.StringReader;
1112
import java.io.StringWriter;
13+
import java.util.ArrayList;
1214
import java.util.Collections;
1315
import java.util.HashMap;
16+
import java.util.HashSet;
17+
import java.util.List;
1418
import java.util.Map;
19+
import java.util.Set;
1520

1621
public class EndpointsDataStore {
1722

@@ -22,6 +27,11 @@ public class EndpointsDataStore {
2227
private static final String KEY_PRODUCTID = "PID";
2328
private static final String KEY_VERSION = "VER";
2429
private static final String KEY_ENDPOINTID = "EPID";
30+
private static final String KEY_SUPPORTED_CLUSTERS = "supportedClusters";
31+
private static final String KEY_CLUSTER_IDENTIFIER = "clusterIdentifier";
32+
private static final String KEY_FEATURES = "features";
33+
private static final String KEY_OPTIONAL_COMMAND_IDENTIFIERS = "optionalCommandIdentifiers";
34+
private static final String KEY_OPTIONAL_ATTRIBUTES_IDENTIFIERS = "optionalAttributesIdentifiers";
2535
private static EndpointsDataStore instance;
2636
private final SharedPreferences discoveredEndpoints;
2737
Map<String, ContentApp> persistedContentApps = new HashMap<>();
@@ -59,19 +69,20 @@ private String serializeContentApp(ContentApp app) {
5969
StringWriter stringWriter = new StringWriter();
6070
JsonWriter jsonWriter = new JsonWriter(stringWriter);
6171
try {
62-
jsonWriter
63-
.beginObject()
64-
.name(KEY_VENDORID)
65-
.value(app.getVendorId())
66-
.name(KEY_VENDORNAME)
67-
.value(app.getVendorName())
68-
.name(KEY_PRODUCTID)
69-
.value(app.getProductId())
70-
.name(KEY_VERSION)
71-
.value(app.getVersion())
72-
.name(KEY_ENDPOINTID)
73-
.value(app.getEndpointId())
74-
.endObject();
72+
jsonWriter.beginObject();
73+
jsonWriter.name(KEY_VENDORID);
74+
jsonWriter.value(app.getVendorId());
75+
jsonWriter.name(KEY_VENDORNAME);
76+
jsonWriter.value(app.getVendorName());
77+
jsonWriter.name(KEY_PRODUCTID);
78+
jsonWriter.value(app.getProductId());
79+
jsonWriter.name(KEY_VERSION);
80+
jsonWriter.value(app.getVersion());
81+
jsonWriter.name(KEY_ENDPOINTID);
82+
jsonWriter.value(app.getEndpointId());
83+
jsonWriter.name(KEY_SUPPORTED_CLUSTERS);
84+
serializeSupportedClusters(jsonWriter, app.getSupportedClusters());
85+
jsonWriter.endObject();
7586
jsonWriter.flush();
7687
jsonWriter.close();
7788
} catch (IOException e) {
@@ -90,6 +101,7 @@ private ContentApp deserializeContentApp(String appName, String appMetadata) {
90101
int vendorId = 0;
91102
int productId = 0;
92103
int endpoint = ContentApp.INVALID_ENDPOINTID;
104+
Set<SupportedCluster> supportedClusters = new HashSet<>();
93105
while (jsonReader.hasNext()) {
94106
String name = jsonReader.nextName();
95107
switch (name) {
@@ -108,14 +120,99 @@ private ContentApp deserializeContentApp(String appName, String appMetadata) {
108120
case KEY_ENDPOINTID:
109121
endpoint = jsonReader.nextInt();
110122
break;
123+
case KEY_SUPPORTED_CLUSTERS:
124+
supportedClusters = deserializeSupportedClusters(jsonReader);
125+
break;
111126
}
112127
}
113-
app = new ContentApp(appName, vendorName, vendorId, productId, version);
128+
app = new ContentApp(appName, vendorName, vendorId, productId, version, supportedClusters);
114129
jsonReader.endObject();
115130
jsonReader.close();
116131
} catch (IOException e) {
117132
// Cannot happen
118133
}
119134
return app;
120135
}
136+
137+
private void serializeSupportedClusters(
138+
JsonWriter jsonWriter, Set<SupportedCluster> supportedClusters) throws IOException {
139+
if (supportedClusters != null) {
140+
jsonWriter.beginArray();
141+
for (SupportedCluster supportedCluster : supportedClusters) {
142+
if (supportedCluster != null) {
143+
serializeSupportedCluster(jsonWriter, supportedCluster);
144+
}
145+
}
146+
jsonWriter.endArray();
147+
}
148+
}
149+
150+
private Set<SupportedCluster> deserializeSupportedClusters(JsonReader jsonReader)
151+
throws IOException {
152+
Set<SupportedCluster> supportedClusters = new HashSet<>();
153+
jsonReader.beginArray();
154+
while (jsonReader.hasNext()) {
155+
supportedClusters.add(deserializeSupportedCluster(jsonReader));
156+
}
157+
jsonReader.endArray();
158+
return supportedClusters;
159+
}
160+
161+
private void serializeSupportedCluster(JsonWriter jsonWriter, SupportedCluster supportedCluster)
162+
throws IOException {
163+
jsonWriter.beginObject();
164+
jsonWriter.name(KEY_CLUSTER_IDENTIFIER);
165+
jsonWriter.value(supportedCluster.clusterIdentifier);
166+
jsonWriter.name(KEY_FEATURES);
167+
jsonWriter.value(supportedCluster.features);
168+
jsonWriter.name(KEY_OPTIONAL_COMMAND_IDENTIFIERS);
169+
serializeIntArray(jsonWriter, supportedCluster.optionalCommandIdentifiers);
170+
jsonWriter.name(KEY_OPTIONAL_ATTRIBUTES_IDENTIFIERS);
171+
serializeIntArray(jsonWriter, supportedCluster.optionalAttributesIdentifiers);
172+
jsonWriter.endObject();
173+
}
174+
175+
private SupportedCluster deserializeSupportedCluster(JsonReader jsonReader) throws IOException {
176+
SupportedCluster supportedCluster = new SupportedCluster();
177+
jsonReader.beginObject();
178+
while (jsonReader.hasNext()) {
179+
String name = jsonReader.nextName();
180+
switch (name) {
181+
case KEY_CLUSTER_IDENTIFIER:
182+
supportedCluster.clusterIdentifier = jsonReader.nextInt();
183+
break;
184+
case KEY_FEATURES:
185+
supportedCluster.features = jsonReader.nextInt();
186+
break;
187+
case KEY_OPTIONAL_COMMAND_IDENTIFIERS:
188+
supportedCluster.optionalCommandIdentifiers = deserializeIntArray(jsonReader);
189+
break;
190+
case KEY_OPTIONAL_ATTRIBUTES_IDENTIFIERS:
191+
supportedCluster.optionalAttributesIdentifiers = deserializeIntArray(jsonReader);
192+
break;
193+
}
194+
}
195+
jsonReader.endObject();
196+
return supportedCluster;
197+
}
198+
199+
private void serializeIntArray(JsonWriter jsonWriter, int[] array) throws IOException {
200+
jsonWriter.beginArray();
201+
if (array != null) {
202+
for (int value : array) {
203+
jsonWriter.value(value);
204+
}
205+
}
206+
jsonWriter.endArray();
207+
}
208+
209+
private int[] deserializeIntArray(JsonReader jsonReader) throws IOException {
210+
List<Integer> dynamicArray = new ArrayList<>();
211+
jsonReader.beginArray();
212+
while (jsonReader.hasNext()) {
213+
dynamicArray.add(jsonReader.nextInt());
214+
}
215+
jsonReader.endArray();
216+
return dynamicArray.stream().mapToInt(Integer::intValue).toArray();
217+
}
121218
}

src/app/clusters/door-lock-server/door-lock-server.cpp

-22
Original file line numberDiff line numberDiff line change
@@ -2923,28 +2923,6 @@ Status DoorLockServer::clearCredential(chip::EndpointId endpointId, chip::Fabric
29232923
return Status::Failure;
29242924
}
29252925

2926-
uint8_t maxCredentialsPerUser;
2927-
if (!GetNumberOfCredentialsSupportedPerUser(endpointId, maxCredentialsPerUser))
2928-
{
2929-
ChipLogError(Zcl,
2930-
"[clearCredential] Unable to get the number of available credentials per user: internal error "
2931-
"[endpointId=%d,credentialType=%d,credentialIndex=%d]",
2932-
endpointId, to_underlying(credentialType), credentialIndex);
2933-
return Status::Failure;
2934-
}
2935-
2936-
// Should never happen, only possible if the implementation of application is incorrect
2937-
if (relatedUser.credentials.size() > maxCredentialsPerUser)
2938-
{
2939-
ChipLogError(Zcl,
2940-
"[clearCredential] Unable to clear credential for related user - user has too many credentials associated"
2941-
"[endpointId=%d,credentialType=%u,credentialIndex=%d,modifier=%d,userIndex=%d,credentialsCount=%u]",
2942-
endpointId, to_underlying(credentialType), credentialIndex, modifier, relatedUserIndex,
2943-
static_cast<unsigned int>(relatedUser.credentials.size()));
2944-
2945-
return Status::Failure;
2946-
}
2947-
29482926
chip::Platform::ScopedMemoryBuffer<CredentialStruct> newCredentials;
29492927
if (!newCredentials.Alloc(relatedUser.credentials.size()))
29502928
{

0 commit comments

Comments
 (0)