Skip to content

Commit

Permalink
Merge branch 'master' into accountlogin-login-logout-support
Browse files Browse the repository at this point in the history
  • Loading branch information
lazarkov authored Jul 11, 2024
2 parents 8957b1f + 905dc36 commit 7289e08
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
tools:ignore="QueryAllPackagesPermission" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

<uses-permission android:name="android.permission.GET_TASKS" />


<application
android:allowBackup="true"
android:extractNativeLibs="true"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package com.matter.tv.server.handlers;

import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.matter.tv.app.api.Clusters;
import com.matter.tv.server.model.ContentApp;
import com.matter.tv.server.receivers.ContentAppDiscoveryService;
import com.matter.tv.server.service.ContentAppAgentService;
import com.matter.tv.server.tvapp.ContentAppEndpointManager;
import com.matter.tv.server.utils.EndpointsDataStore;
import java.util.Collection;
import java.util.List;

public class ContentAppEndpointManagerImpl implements ContentAppEndpointManager {

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

private boolean isForegroundCommand(long clusterId, long commandId) {
switch ((int) clusterId) {
case Clusters.ContentLauncher.Id:
return commandId == Clusters.ContentLauncher.Commands.LaunchContent.ID
|| commandId == Clusters.ContentLauncher.Commands.LaunchURL.ID;
case Clusters.TargetNavigator.Id:
return commandId == Clusters.TargetNavigator.Commands.NavigateTarget.ID;
default:
return false;
}
}

private boolean isAppInForeground(String contentAppPackageName) {
ActivityManager activityManager =
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(1);
if (tasks != null && !tasks.isEmpty()) {
ActivityManager.RunningTaskInfo taskInfo = tasks.get(0);
String packageName =
taskInfo.topActivity != null ? taskInfo.topActivity.getPackageName() : "";
return packageName.equals(contentAppPackageName);
}
return false;
}

public String sendCommand(int endpointId, long clusterId, long commandId, String commandPayload) {
Log.d(TAG, "Received a command for endpointId " + endpointId + ". Message " + commandPayload);

Expand All @@ -26,6 +55,17 @@ public String sendCommand(int endpointId, long clusterId, long commandId, String
ContentAppDiscoveryService.getReceiverInstance().getDiscoveredContentApps().values(),
endpointId);
if (discoveredApp != null) {
// Intercept NavigateTarget and LaunchContent commands and launch content app if necessary
if (isForegroundCommand(clusterId, commandId)) {
// Check if contentapp main/launch activity is already in foreground before launching.
if (!isAppInForeground(discoveredApp.getAppName())) {
Intent launchIntent =
context.getPackageManager().getLaunchIntentForPackage(discoveredApp.getAppName());
if (launchIntent != null) {
context.startActivity(launchIntent);
}
}
}
Log.d(TAG, "Sending a command for endpointId " + endpointId + ". Message " + commandPayload);
return ContentAppAgentService.sendCommand(
context, discoveredApp.getAppName(), clusterId, commandId, commandPayload);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public ContentApp(
this.vendorId = vendorId;
this.productId = productId;
this.version = version;
this.supportedClusters = Collections.EMPTY_SET;
}

public ContentApp(
Expand Down Expand Up @@ -67,9 +68,7 @@ public void setEndpointId(int endpoint) {
}

public Set<SupportedCluster> getSupportedClusters() {
return supportedClusters != null
? Collections.unmodifiableSet(supportedClusters)
: Collections.EMPTY_SET;
return Collections.unmodifiableSet(supportedClusters);
}

public String getVersion() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@
import android.content.SharedPreferences;
import android.util.JsonReader;
import android.util.JsonWriter;
import com.matter.tv.app.api.SupportedCluster;
import com.matter.tv.server.model.ContentApp;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class EndpointsDataStore {

Expand All @@ -21,6 +26,11 @@ public class EndpointsDataStore {
private static final String KEY_PRODUCTID = "PID";
private static final String KEY_VERSION = "VER";
private static final String KEY_ENDPOINTID = "EPID";
private static final String KEY_SUPPORTED_CLUSTERS = "supportedClusters";
private static final String KEY_CLUSTER_IDENTIFIER = "clusterIdentifier";
private static final String KEY_FEATURES = "features";
private static final String KEY_OPTIONAL_COMMAND_IDENTIFIERS = "optionalCommandIdentifiers";
private static final String KEY_OPTIONAL_ATTRIBUTES_IDENTIFIERS = "optionalAttributesIdentifiers";
private static EndpointsDataStore instance;
private final SharedPreferences discoveredEndpoints;
Map<String, ContentApp> persistedContentApps = new HashMap<>();
Expand Down Expand Up @@ -57,19 +67,20 @@ private String serializeContentApp(ContentApp app) {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
try {
jsonWriter
.beginObject()
.name(KEY_VENDORID)
.value(app.getVendorId())
.name(KEY_VENDORNAME)
.value(app.getVendorName())
.name(KEY_PRODUCTID)
.value(app.getProductId())
.name(KEY_VERSION)
.value(app.getVersion())
.name(KEY_ENDPOINTID)
.value(app.getEndpointId())
.endObject();
jsonWriter.beginObject();
jsonWriter.name(KEY_VENDORID);
jsonWriter.value(app.getVendorId());
jsonWriter.name(KEY_VENDORNAME);
jsonWriter.value(app.getVendorName());
jsonWriter.name(KEY_PRODUCTID);
jsonWriter.value(app.getProductId());
jsonWriter.name(KEY_VERSION);
jsonWriter.value(app.getVersion());
jsonWriter.name(KEY_ENDPOINTID);
jsonWriter.value(app.getEndpointId());
jsonWriter.name(KEY_SUPPORTED_CLUSTERS);
serializeSupportedClusters(jsonWriter, app.getSupportedClusters());
jsonWriter.endObject();
jsonWriter.flush();
jsonWriter.close();
} catch (IOException e) {
Expand All @@ -88,6 +99,7 @@ private ContentApp deserializeContentApp(String appName, String appMetadata) {
int vendorId = 0;
int productId = 0;
int endpoint = ContentApp.INVALID_ENDPOINTID;
Set<SupportedCluster> supportedClusters = new HashSet<>();
while (jsonReader.hasNext()) {
String name = jsonReader.nextName();
switch (name) {
Expand All @@ -106,14 +118,99 @@ private ContentApp deserializeContentApp(String appName, String appMetadata) {
case KEY_ENDPOINTID:
endpoint = jsonReader.nextInt();
break;
case KEY_SUPPORTED_CLUSTERS:
supportedClusters = deserializeSupportedClusters(jsonReader);
break;
}
}
app = new ContentApp(appName, vendorName, vendorId, productId, version);
app = new ContentApp(appName, vendorName, vendorId, productId, version, supportedClusters);
jsonReader.endObject();
jsonReader.close();
} catch (IOException e) {
// Cannot happen
}
return app;
}

private void serializeSupportedClusters(
JsonWriter jsonWriter, Set<SupportedCluster> supportedClusters) throws IOException {
if (supportedClusters != null) {
jsonWriter.beginArray();
for (SupportedCluster supportedCluster : supportedClusters) {
if (supportedCluster != null) {
serializeSupportedCluster(jsonWriter, supportedCluster);
}
}
jsonWriter.endArray();
}
}

private Set<SupportedCluster> deserializeSupportedClusters(JsonReader jsonReader)
throws IOException {
Set<SupportedCluster> supportedClusters = new HashSet<>();
jsonReader.beginArray();
while (jsonReader.hasNext()) {
supportedClusters.add(deserializeSupportedCluster(jsonReader));
}
jsonReader.endArray();
return supportedClusters;
}

private void serializeSupportedCluster(JsonWriter jsonWriter, SupportedCluster supportedCluster)
throws IOException {
jsonWriter.beginObject();
jsonWriter.name(KEY_CLUSTER_IDENTIFIER);
jsonWriter.value(supportedCluster.clusterIdentifier);
jsonWriter.name(KEY_FEATURES);
jsonWriter.value(supportedCluster.features);
jsonWriter.name(KEY_OPTIONAL_COMMAND_IDENTIFIERS);
serializeIntArray(jsonWriter, supportedCluster.optionalCommandIdentifiers);
jsonWriter.name(KEY_OPTIONAL_ATTRIBUTES_IDENTIFIERS);
serializeIntArray(jsonWriter, supportedCluster.optionalAttributesIdentifiers);
jsonWriter.endObject();
}

private SupportedCluster deserializeSupportedCluster(JsonReader jsonReader) throws IOException {
SupportedCluster supportedCluster = new SupportedCluster();
jsonReader.beginObject();
while (jsonReader.hasNext()) {
String name = jsonReader.nextName();
switch (name) {
case KEY_CLUSTER_IDENTIFIER:
supportedCluster.clusterIdentifier = jsonReader.nextInt();
break;
case KEY_FEATURES:
supportedCluster.features = jsonReader.nextInt();
break;
case KEY_OPTIONAL_COMMAND_IDENTIFIERS:
supportedCluster.optionalCommandIdentifiers = deserializeIntArray(jsonReader);
break;
case KEY_OPTIONAL_ATTRIBUTES_IDENTIFIERS:
supportedCluster.optionalAttributesIdentifiers = deserializeIntArray(jsonReader);
break;
}
}
jsonReader.endObject();
return supportedCluster;
}

private void serializeIntArray(JsonWriter jsonWriter, int[] array) throws IOException {
jsonWriter.beginArray();
if (array != null) {
for (int value : array) {
jsonWriter.value(value);
}
}
jsonWriter.endArray();
}

private int[] deserializeIntArray(JsonReader jsonReader) throws IOException {
List<Integer> dynamicArray = new ArrayList<>();
jsonReader.beginArray();
while (jsonReader.hasNext()) {
dynamicArray.add(jsonReader.nextInt());
}
jsonReader.endArray();
return dynamicArray.stream().mapToInt(Integer::intValue).toArray();
}
}

0 comments on commit 7289e08

Please sign in to comment.