From 6edaee284f91fd474d36d85373c9254fe1131288 Mon Sep 17 00:00:00 2001 From: mthiesc Date: Mon, 8 Jul 2024 00:05:39 +0200 Subject: [PATCH 1/6] Launch content app on command [Problem] 3P content app does not have permissions to launch itself and put main activity in foreground. This is necessary in response to ContentLauncher and TargetNavigator cluster commands. [Solution] Intercept the LaunchContent and NavigateTarget commands in ContentAppEndpointManagerImpl. Then start content app main/launch activity if it's not already in the foreground before sending command intent. [Testing] WIP --- .../ContentAppEndpointManagerImpl.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java index f93897f2d2a582..4ad57ca653b7fb 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java @@ -2,6 +2,7 @@ import android.content.Context; 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; @@ -18,6 +19,17 @@ public ContentAppEndpointManagerImpl(Context context) { this.context = context; } + private boolean isForegroundCommand(long clusterId, long commandId) { + switch (clusterId) { + case Clusters.ContentLauncher.Id: + return commandId == Clusters.ContentLauncher.Commands.LaunchContent.Id; + case Clusters.TargetNavigator.Id: + return commandId == Clusters.TargetNavigator.Commands.NavigateTarget.Id; + default: + return false; + } + } + public String sendCommand(int endpointId, long clusterId, long commandId, String commandPayload) { Log.d(TAG, "Received a command for endpointId " + endpointId + ". Message " + commandPayload); @@ -26,6 +38,14 @@ 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)) { + // TODO: Check if contentapp main/launch activity is already in foreground before launching. + Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(discoveredApp.getAppName()); + if (launchIntent != null) { + startActivity(launchIntent); + } + } Log.d(TAG, "Sending a command for endpointId " + endpointId + ". Message " + commandPayload); return ContentAppAgentService.sendCommand( context, discoveredApp.getAppName(), clusterId, commandId, commandPayload); From 090cb66d5353f2fefa1e399e82c75fd159df7027 Mon Sep 17 00:00:00 2001 From: Lazar Kovacic Date: Mon, 8 Jul 2024 23:52:27 +0200 Subject: [PATCH 2/6] Add logic to detect foreground apps --- .../ContentAppEndpointManagerImpl.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java index 4ad57ca653b7fb..92266b3ae0d75d 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java @@ -30,6 +30,17 @@ private boolean isForegroundCommand(long clusterId, long commandId) { } } + private boolean isAppInForeground(String contentAppPackageName) { + ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + List tasks = activityManager.getRunningTasks(1); + if (tasks != null && !tasks.isEmpty()) { + ActivityManager.RunningTaskInfo taskInfo = tasks.get(0); + String packageName = 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); @@ -40,10 +51,12 @@ public String sendCommand(int endpointId, long clusterId, long commandId, String if (discoveredApp != null) { // Intercept NavigateTarget and LaunchContent commands and launch content app if necessary if (isForegroundCommand(clusterId, commandId)) { - // TODO: Check if contentapp main/launch activity is already in foreground before launching. - Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(discoveredApp.getAppName()); - if (launchIntent != null) { - startActivity(launchIntent); + // 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) { + startActivity(launchIntent); + } } } Log.d(TAG, "Sending a command for endpointId " + endpointId + ". Message " + commandPayload); From 393029e724b518755d54d6189105496fa1a214d1 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Mon, 8 Jul 2024 21:53:46 +0000 Subject: [PATCH 3/6] Restyled by whitespace --- .../tv/server/handlers/ContentAppEndpointManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java index 92266b3ae0d75d..7ce655938200df 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java @@ -56,7 +56,7 @@ public String sendCommand(int endpointId, long clusterId, long commandId, String Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(discoveredApp.getAppName()); if (launchIntent != null) { startActivity(launchIntent); - } + } } } Log.d(TAG, "Sending a command for endpointId " + endpointId + ". Message " + commandPayload); From 40074d26451b0903843a330418cf46a321fd6548 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Mon, 8 Jul 2024 21:54:09 +0000 Subject: [PATCH 4/6] Restyled by google-java-format --- .../tv/server/handlers/ContentAppEndpointManagerImpl.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java index 7ce655938200df..0ecda625b5b4b5 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java @@ -31,7 +31,8 @@ private boolean isForegroundCommand(long clusterId, long commandId) { } private boolean isAppInForeground(String contentAppPackageName) { - ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + ActivityManager activityManager = + (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List tasks = activityManager.getRunningTasks(1); if (tasks != null && !tasks.isEmpty()) { ActivityManager.RunningTaskInfo taskInfo = tasks.get(0); @@ -53,9 +54,10 @@ public String sendCommand(int endpointId, long clusterId, long commandId, String 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()); + Intent launchIntent = + context.getPackageManager().getLaunchIntentForPackage(discoveredApp.getAppName()); if (launchIntent != null) { - startActivity(launchIntent); + startActivity(launchIntent); } } } From 96a846ba7f3346668d7111355a9b1b86b3b20e7b Mon Sep 17 00:00:00 2001 From: Lazar Kovacic Date: Tue, 9 Jul 2024 09:05:48 +0200 Subject: [PATCH 5/6] Update code --- .../platform-app/src/main/AndroidManifest.xml | 3 ++ .../ContentAppEndpointManagerImpl.java | 28 +++++++++++-------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/examples/tv-app/android/App/platform-app/src/main/AndroidManifest.xml b/examples/tv-app/android/App/platform-app/src/main/AndroidManifest.xml index b6e00cd75d0365..476faa2030c7a2 100644 --- a/examples/tv-app/android/App/platform-app/src/main/AndroidManifest.xml +++ b/examples/tv-app/android/App/platform-app/src/main/AndroidManifest.xml @@ -26,6 +26,9 @@ tools:ignore="QueryAllPackagesPermission" /> + + + tasks = activityManager.getRunningTasks(1); - if (tasks != null && !tasks.isEmpty()) { - ActivityManager.RunningTaskInfo taskInfo = tasks.get(0); - String packageName = taskInfo.topActivity.getPackageName(); - return packageName.equals(contentAppPackageName); - } + ActivityManager activityManager = + (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + List 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; } @@ -57,7 +61,7 @@ public String sendCommand(int endpointId, long clusterId, long commandId, String Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(discoveredApp.getAppName()); if (launchIntent != null) { - startActivity(launchIntent); + context.startActivity(launchIntent); } } } From 1365db5de2fbb88ea572cb28745a71ed81a4fd66 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Tue, 9 Jul 2024 07:07:39 +0000 Subject: [PATCH 6/6] Restyled by google-java-format --- .../ContentAppEndpointManagerImpl.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java index 86576921c3d529..85fe7367944c74 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java @@ -23,10 +23,10 @@ public ContentAppEndpointManagerImpl(Context context) { } private boolean isForegroundCommand(long clusterId, long commandId) { - switch ((int)clusterId) { + switch ((int) clusterId) { case Clusters.ContentLauncher.Id: - return commandId == Clusters.ContentLauncher.Commands.LaunchContent.ID || - commandId == Clusters.ContentLauncher.Commands.LaunchURL.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: @@ -35,14 +35,15 @@ private boolean isForegroundCommand(long clusterId, long commandId) { } private boolean isAppInForeground(String contentAppPackageName) { - ActivityManager activityManager = - (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); - List 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); - } + ActivityManager activityManager = + (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + List 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; }