From 87cc90757b75456ef8453afddc19c530b791b331 Mon Sep 17 00:00:00 2001
From: Lazar Kovacic <lkovacic@amazon.com>
Date: Fri, 28 Jun 2024 23:37:38 +0200
Subject: [PATCH 01/22] Add install things

---
 .../all-clusters-minimal-app.matter           |   2 +
 .../placeholder/linux/apps/app1/config.matter |   4 +
 .../placeholder/linux/apps/app2/config.matter |   4 +
 .../android/App/.idea/codeStyles/Project.xml  | 117 ++++++
 .../App/.idea/codeStyles/codeStyleConfig.xml  |   5 +
 .../contentapp/CommandResponseHolder.java     |   5 +
 .../android/App/platform-app/build.gradle     |  16 +-
 .../com/matter/tv/server/MainActivity.java    |   2 +
 .../ApplicationLauncherManagerImpl.java       | 149 ++++++++
 .../tv/server/service/AppPlatformService.java |   2 +
 .../tv/server/service/MatterServant.java      |  11 +
 .../tv/server/utils/EndpointsDataStore.java   |   2 +
 .../tv/server/utils/InstallationObserver.java | 133 +++++++
 examples/tv-app/android/BUILD.gn              |   7 +-
 .../ApplicationLauncherManager.cpp            |  76 ----
 .../tv-app/android/include/cluster-init.cpp   |  17 -
 examples/tv-app/android/java/AppImpl.h        |   2 +-
 examples/tv-app/android/java/TVApp-JNI.cpp    |   6 +
 .../ApplicationLauncherManager.cpp            | 337 ++++++++++++++++++
 .../ApplicationLauncherManager.h              |  18 +-
 .../matter/tv/server/tvapp/Application.java   |  46 +++
 .../tvapp/ApplicationLauncherManager.java     |  36 ++
 .../tv/server/tvapp/LauncherResponse.java     |  21 ++
 .../src/com/matter/tv/server/tvapp/TvApp.java |   2 +
 examples/tv-app/tv-common/tv-app.matter       |   2 +
 .../tv-casting-common/tv-casting-app.matter   |   2 +
 .../application-launcher-server.cpp           |  32 +-
 .../chip/application-launcher-cluster.xml     |   2 +
 .../data_model/controller-clusters.matter     |   2 +
 .../python/chip/clusters/Objects.py           |   8 +-
 .../CHIP/zap-generated/MTRBaseClusters.h      |   2 +
 src/lib/support/JniTypeWrappers.h             |   3 +
 .../zap-generated/cluster-enums-check.h       |   2 +
 .../app-common/zap-generated/cluster-enums.h  |  10 +-
 34 files changed, 955 insertions(+), 130 deletions(-)
 create mode 100644 examples/tv-app/android/App/.idea/codeStyles/Project.xml
 create mode 100644 examples/tv-app/android/App/.idea/codeStyles/codeStyleConfig.xml
 create mode 100644 examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
 create mode 100644 examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/InstallationObserver.java
 delete mode 100644 examples/tv-app/android/include/application-launcher/ApplicationLauncherManager.cpp
 create mode 100644 examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
 rename examples/tv-app/android/{include => java}/application-launcher/ApplicationLauncherManager.h (72%)
 create mode 100644 examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Application.java
 create mode 100644 examples/tv-app/android/java/src/com/matter/tv/server/tvapp/ApplicationLauncherManager.java
 create mode 100644 examples/tv-app/android/java/src/com/matter/tv/server/tvapp/LauncherResponse.java

diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter
index fcb987edb574aa..73cdabada04c71 100644
--- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter
+++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter
@@ -5583,6 +5583,8 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
+    kStatusPending = 3;
+    kStatusInstalling = 4;
   }
 
   bitmap Feature : bitmap32 {
diff --git a/examples/placeholder/linux/apps/app1/config.matter b/examples/placeholder/linux/apps/app1/config.matter
index 87b61c8a45357c..f32ba1782f42ff 100644
--- a/examples/placeholder/linux/apps/app1/config.matter
+++ b/examples/placeholder/linux/apps/app1/config.matter
@@ -8236,6 +8236,8 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
+    kStatusPending = 3;
+    kStatusInstalling = 4;
   }
 
   bitmap Feature : bitmap32 {
@@ -8295,6 +8297,8 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
+    kStatusPending = 3;
+    kStatusInstalling = 4;
   }
 
   bitmap Feature : bitmap32 {
diff --git a/examples/placeholder/linux/apps/app2/config.matter b/examples/placeholder/linux/apps/app2/config.matter
index db46fa85d7e71d..1a8af42889604a 100644
--- a/examples/placeholder/linux/apps/app2/config.matter
+++ b/examples/placeholder/linux/apps/app2/config.matter
@@ -8193,6 +8193,8 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
+    kStatusPending = 3;
+    kStatusInstalling = 4;
   }
 
   bitmap Feature : bitmap32 {
@@ -8252,6 +8254,8 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
+    kStatusPending = 3;
+    kStatusInstalling = 4;
   }
 
   bitmap Feature : bitmap32 {
diff --git a/examples/tv-app/android/App/.idea/codeStyles/Project.xml b/examples/tv-app/android/App/.idea/codeStyles/Project.xml
new file mode 100644
index 00000000000000..4bec4ea8ae0d9c
--- /dev/null
+++ b/examples/tv-app/android/App/.idea/codeStyles/Project.xml
@@ -0,0 +1,117 @@
+<component name="ProjectCodeStyleConfiguration">
+  <code_scheme name="Project" version="173">
+    <codeStyleSettings language="XML">
+      <option name="FORCE_REARRANGE_MODE" value="1" />
+      <indentOptions>
+        <option name="CONTINUATION_INDENT_SIZE" value="4" />
+      </indentOptions>
+      <arrangement>
+        <rules>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>xmlns:android</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>xmlns:.*</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+              <order>BY_NAME</order>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*:id</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*:name</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>name</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>style</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>^$</XML_NAMESPACE>
+                </AND>
+              </match>
+              <order>BY_NAME</order>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+                </AND>
+              </match>
+              <order>ANDROID_ATTRIBUTE_ORDER</order>
+            </rule>
+          </section>
+          <section>
+            <rule>
+              <match>
+                <AND>
+                  <NAME>.*</NAME>
+                  <XML_ATTRIBUTE />
+                  <XML_NAMESPACE>.*</XML_NAMESPACE>
+                </AND>
+              </match>
+              <order>BY_NAME</order>
+            </rule>
+          </section>
+        </rules>
+      </arrangement>
+    </codeStyleSettings>
+  </code_scheme>
+</component>
\ No newline at end of file
diff --git a/examples/tv-app/android/App/.idea/codeStyles/codeStyleConfig.xml b/examples/tv-app/android/App/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 00000000000000..a55e7a179bde3e
--- /dev/null
+++ b/examples/tv-app/android/App/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+<component name="ProjectCodeStyleConfiguration">
+  <state>
+    <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
+  </state>
+</component>
\ No newline at end of file
diff --git a/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/CommandResponseHolder.java b/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/CommandResponseHolder.java
index 61ee303b408587..86e8d24829f1af 100644
--- a/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/CommandResponseHolder.java
+++ b/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/CommandResponseHolder.java
@@ -1,5 +1,8 @@
 package com.example.contentapp;
 
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
 import android.util.Log;
 import com.matter.tv.app.api.Clusters;
 import java.util.HashMap;
@@ -10,6 +13,7 @@ public class CommandResponseHolder {
   private Map<Long, Map<Long, String>> responseValues = new HashMap<>();
   private static final String TAG = "CommandResponseHolder";
   private static final Long DEFAULT_COMMAND = -1L;
+  private ContentResolver contentResolver;
 
   private static CommandResponseHolder instance = new CommandResponseHolder();
 
@@ -31,6 +35,7 @@ private CommandResponseHolder() {
         Clusters.AccountLogin.Id,
         Clusters.AccountLogin.Commands.GetSetupPIN.ID,
         "{\"0\":\"20202021\"}");
+//    "{\"0\":\""+ Settings.Secure.getInt(contentResolver, "matter_pin_code", 20202021) +"\"}");
   };
 
   public static CommandResponseHolder getInstance() {
diff --git a/examples/tv-app/android/App/platform-app/build.gradle b/examples/tv-app/android/App/platform-app/build.gradle
index 0845105bffccc5..165ec1fbad8fc5 100644
--- a/examples/tv-app/android/App/platform-app/build.gradle
+++ b/examples/tv-app/android/App/platform-app/build.gradle
@@ -47,14 +47,14 @@ android {
             aidl.srcDirs = ['../common-api/src/main/aidl']
 
             // uncomment this code to debug
-//            java.srcDirs = [
-//                    'src/main/java',
-//                    '../common-api/src/main/java',
-//                    '../../third_party/connectedhomeip/src/setup_payload/java/src',
-//                    '../../third_party/connectedhomeip/src/platform/android/java',
-//                    '../../third_party/connectedhomeip/src/app/server/java/src/',
-//                    '../../java/src',
-//            ]
+            java.srcDirs = [
+                    'src/main/java',
+                    '../common-api/src/main/java',
+                    '../../third_party/connectedhomeip/src/setup_payload/java/src',
+                    '../../third_party/connectedhomeip/src/platform/android/java',
+                    '../../third_party/connectedhomeip/src/app/server/java/src/',
+                    '../../java/src',
+            ]
         }
     }
     buildFeatures {
diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java
index df612cf78fea94..e78c9a2142802d 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java
@@ -11,6 +11,8 @@
 import com.matter.tv.server.fragments.ContentAppFragment;
 import com.matter.tv.server.fragments.QrCodeFragment;
 import com.matter.tv.server.fragments.TerminalFragment;
+import com.matter.tv.server.utils.InstallationObserver;
+
 import java.util.LinkedHashMap;
 
 public class MainActivity extends AppCompatActivity {
diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
new file mode 100644
index 00000000000000..255dd11be9ab56
--- /dev/null
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
@@ -0,0 +1,149 @@
+package com.matter.tv.server.handlers;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.util.Log;
+
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.Observer;
+
+import com.matter.tv.server.tvapp.Application;
+import com.matter.tv.server.tvapp.ApplicationLauncherManager;
+import com.matter.tv.server.tvapp.LauncherResponse;
+import com.matter.tv.server.utils.EndpointsDataStore;
+import com.matter.tv.server.utils.InstallationObserver;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+public class ApplicationLauncherManagerImpl implements ApplicationLauncherManager {
+
+  private static final String TAG = "ApplicationLauncherService";
+
+  private volatile boolean registered = false;
+  private PackageManager packageManager;
+  private EndpointsDataStore endpointsDataStore;
+
+  /**
+   * Hash Map of packageName & Install Status
+   */
+  private Map<String, InstallationObserver.InstallStatus> lastReceivedInstallationStatus = new HashMap<>();
+
+  private LiveData<InstallationObserver.InstallState> installStateLiveData;
+
+  public ApplicationLauncherManagerImpl(Context context) {
+    packageManager = context.getPackageManager();
+    endpointsDataStore = EndpointsDataStore.getInstance(context);
+    registerSelf(context);
+  }
+
+  // Add list of apps with latest install statuses - DONE
+  // Add list of installed apps - DONE
+  // Add list of installed apps that support Matter
+  // Store all of the list using Shared pref
+  // Load the stored lists, by asking shared pref
+
+  private final Observer<InstallationObserver.InstallState> installStateObserver = state -> {
+    lastReceivedInstallationStatus.put(state.getAppPackageName(), state.getStatus());
+    switch (state.getStatus()) {
+
+      case IN_PROGRESS:
+        // Installation is in progress
+        Log.d(TAG, "Installation of " + state.getAppPackageName() + " in progress");
+        break;
+      case SUCCEEDED:
+        // Installation succeeded
+        Log.d(TAG, "Installation of " + state.getAppPackageName() + " succeeded");
+        break;
+      case FAILED:
+        // Installation failed
+        Log.d(TAG, "Installation of " + state.getAppPackageName() + " failed");
+        break;
+    }
+  };
+
+  private void stopObservingInstallations() {
+    if (installStateLiveData != null) {
+      Log.d("InstallationObserver", "Stopped Observing");
+      installStateLiveData.removeObserver(installStateObserver);
+    }
+  }
+
+  public void unregister() {
+    stopObservingInstallations();
+  }
+
+  private void registerSelf(Context context) {
+    if (registered) {
+      Log.i(TAG, "Package update receiver for matter already registered");
+      return;
+    } else {
+      registered = true;
+    }
+    Log.i(TAG, "Registered the matter package updates receiver");
+
+    installStateLiveData = InstallationObserver.installationStates(context);
+    installStateLiveData.observeForever(installStateObserver);
+    Log.d(TAG, "Started Observing package installations");
+  }
+
+  @Override
+  public int[] getCatalogList() {
+    Log.i(TAG, "Get Catalog List");
+    return new int[0];
+  }
+
+  @Override
+  public LauncherResponse launchApp(Application app, String data) {
+    Log.i(TAG, "Launch app id:" + app.applicationId + " cid:" + app.catalogVendorId + " data:" + data);
+
+    int status = 0;
+    String responseData = "";
+
+    boolean matterAppEnabledIsInstalled = endpointsDataStore.getAllPersistedContentApps().containsKey(app.applicationId);
+    boolean appIsInstalled = InstallationObserver.getInstalledPackages(packageManager).contains(app.applicationId);
+    boolean isAppInstalling = Objects.equals(lastReceivedInstallationStatus.get(app.applicationId), InstallationObserver.InstallStatus.IN_PROGRESS);
+    boolean appInstallFailed = Objects.equals(lastReceivedInstallationStatus.get(app.applicationId), InstallationObserver.InstallStatus.FAILED);
+
+
+    if (!matterAppEnabledIsInstalled && appIsInstalled) {
+      Log.i(TAG, "Matter enabled app is not installed, but app is installed. Launching app's install page");
+      status = LauncherResponse.STATUS_PENDING;
+      responseData = "App is installed, try updating";
+      // TODO: Launch App Install Page
+
+    } else if (!matterAppEnabledIsInstalled && !appIsInstalled) {
+      Log.i(TAG, "Matter enabled app is not installed and app is not installed. Launching app's install page");
+      if (isAppInstalling) {
+        Log.i(TAG, "App is installing");
+        status = LauncherResponse.STATUS_INSTALLING;
+      } else {
+        status = LauncherResponse.STATUS_PENDING;
+        if (appInstallFailed) {
+          responseData = "App install failed. Try again";
+        }
+      }
+      // TODO: Launch App Install Page
+
+    } else if (matterAppEnabledIsInstalled && appIsInstalled) {
+      Log.i(TAG, "Launching the app");
+      status = LauncherResponse.STATUS_SUCCESS;
+      // TODO: Launch App
+    }
+
+    return new LauncherResponse(status, responseData);
+  }
+
+  @Override
+  public LauncherResponse stopApp(Application app) {
+    Log.i(TAG, "Stop app id:" + app.applicationId + " cid:" + app.catalogVendorId);
+    return new LauncherResponse(LauncherResponse.STATUS_SUCCESS, "");
+  }
+
+  @Override
+  public LauncherResponse hideApp(Application app) {
+    Log.i(TAG, "Hide app id:" + app.applicationId + " cid:" + app.catalogVendorId);
+    return new LauncherResponse(LauncherResponse.STATUS_SUCCESS, "");
+  }
+}
diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java
index df360375068e70..09944c648e187d 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java
@@ -25,6 +25,7 @@
 import android.util.Log;
 import androidx.annotation.NonNull;
 import com.matter.tv.app.api.SupportedCluster;
+import com.matter.tv.server.handlers.ApplicationLauncherManagerImpl;
 import com.matter.tv.server.handlers.ContentAppEndpointManagerImpl;
 import com.matter.tv.server.model.ContentApp;
 import com.matter.tv.server.receivers.ContentAppDiscoveryService;
@@ -195,6 +196,7 @@ public void addContentApp(ContentApp app) {
     }
   }
 
+
   private Collection<ContentAppSupportedCluster> mapSupportedClusters(
       Collection<SupportedCluster> supportedClusters) {
     return supportedClusters
diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java
index c1d479e6d147e1..9b42d8ac464223 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java
@@ -30,6 +30,8 @@
 import chip.platform.PreferencesConfigurationManager;
 import chip.platform.PreferencesKeyValueStoreManager;
 import com.matter.tv.server.MatterCommissioningPrompter;
+import com.matter.tv.server.handlers.ApplicationLauncherManagerImpl;
+import com.matter.tv.server.tvapp.ApplicationLauncherManager;
 import com.matter.tv.server.tvapp.ChannelManagerStub;
 import com.matter.tv.server.tvapp.Clusters;
 import com.matter.tv.server.tvapp.ContentLaunchManagerStub;
@@ -55,6 +57,8 @@ public class MatterServant {
   private boolean mIsOn = true;
   private int mOnOffEndpoint;
   private int mLevelEndpoint;
+  private MatterCommissioningPrompter matterCommissioningPrompter;
+  private ApplicationLauncherManager applicationLauncherManager;
 
   private MatterServant() {}
 
@@ -72,17 +76,24 @@ public void init(@NonNull Context context) {
 
     this.context = context;
 
+    this.applicationLauncherManager = new ApplicationLauncherManagerImpl(context);
+
     // The order is important, must
     // first new TvApp to load dynamic library
     // then chipPlatform to prepare platform
     // then TvApp.preServerInit to initialize any server configuration
     // then start ChipAppServer
     // then TvApp.postServerInit to init app platform
+    //
+    // TODO: Move all of this logic to PlatformAppCommandDelegate
+    // There is no need for this complicated logic
     mTvApp =
         new TvApp(
             (app, clusterId, endpoint) -> {
               if (clusterId == Clusters.ClusterId_KeypadInput) {
                 app.setKeypadInputManager(endpoint, new KeypadInputManagerStub(endpoint));
+              } else if (clusterId == Clusters.ClusterId_ApplicationLauncher) {
+                app.setApplicationLauncherManager(endpoint, applicationLauncherManager);
               } else if (clusterId == Clusters.ClusterId_WakeOnLan) {
                 app.setWakeOnLanManager(endpoint, new WakeOnLanManagerStub(endpoint));
               } else if (clusterId == Clusters.ClusterId_MediaInput) {
diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java
index 227ea9326be538..7c7b39034f55a6 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java
@@ -4,6 +4,7 @@
 import android.content.SharedPreferences;
 import android.util.JsonReader;
 import android.util.JsonWriter;
+import android.util.Log;
 import com.matter.tv.app.api.SupportedCluster;
 import com.matter.tv.server.model.ContentApp;
 import java.io.IOException;
@@ -59,6 +60,7 @@ public Map<String, ContentApp> getAllPersistedContentApps() {
   }
 
   public void persistContentAppEndpoint(ContentApp app) {
+    Log.i( EndpointsDataStore.class.toString(), "Persist Content App Endpoint " + app.getAppName());
     persistedContentApps.put(app.getAppName(), app);
     discoveredEndpoints.edit().putString(app.getAppName(), serializeContentApp(app)).apply();
   }
diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/InstallationObserver.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/InstallationObserver.java
new file mode 100644
index 00000000000000..4c355278b5614e
--- /dev/null
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/InstallationObserver.java
@@ -0,0 +1,133 @@
+package com.matter.tv.server.utils;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
+import android.util.Log;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+public class InstallationObserver {
+    public enum InstallStatus {
+        IN_PROGRESS, SUCCEEDED, FAILED
+    }
+
+    public static class InstallState {
+        private final String appPackageName;
+        private final InstallStatus status;
+
+        public InstallState(String appPackageName, InstallStatus status) {
+            this.appPackageName = appPackageName;
+            this.status = status;
+        }
+
+        public String getAppPackageName() {
+            return appPackageName;
+        }
+
+        public InstallStatus getStatus() {
+            return status;
+        }
+
+        public String getPackageShortName() {
+            return appPackageName.substring(appPackageName.lastIndexOf(".") + 1);
+        }
+
+        public String getPackageTitle() {
+            String shortName = getPackageShortName();
+            return shortName.substring(0, 1).toUpperCase(Locale.getDefault()) + shortName.substring(1);
+        }
+    }
+
+    private static InstallState stateFromId(PackageInstaller installer, int sessionId) {
+        PackageInstaller.SessionInfo info = installer.getSessionInfo(sessionId);
+        if (info == null || info.getAppPackageName() == null) {
+            return null;
+        }
+        return new InstallState(info.getAppPackageName(), InstallStatus.IN_PROGRESS);
+    }
+
+    public static Set<String> getInstalledPackages(PackageManager packageManager) {
+        List<PackageInfo> packageInfoList = packageManager.getInstalledPackages(0);
+        Set<String> setOfInstalledApps = new HashSet<>();
+        for (PackageInfo info: packageInfoList) {
+            setOfInstalledApps.add(info.packageName);
+        }
+        return setOfInstalledApps;
+    }
+
+    public static LiveData<InstallState> installationStates(Context context) {
+        MutableLiveData<InstallState> liveData = new MutableLiveData<>();
+        PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
+        Map<Integer, InstallState> inProgressSessions = new HashMap<>();
+
+        PackageInstaller.SessionCallback callback = new PackageInstaller.SessionCallback() {
+            @Override
+            public void onCreated(int sessionId) {
+                Log.d(TAG, "onCreated ");
+                InstallState state = stateFromId(packageInstaller, sessionId);
+                if (state != null) {
+                    inProgressSessions.put(sessionId, state);
+                    liveData.postValue(state);
+                }
+            }
+
+            @Override
+            public void onBadgingChanged(int sessionId) {
+            }
+
+            @Override
+            public void onActiveChanged(int sessionId, boolean active) {
+                Log.d(TAG, "onActiveChanged");
+                InstallState state = stateFromId(packageInstaller, sessionId);
+                if (state != null) {
+                    inProgressSessions.put(sessionId, state);
+                    liveData.postValue(state);
+                }
+            }
+
+            @Override
+            public void onProgressChanged(int sessionId, float progress) {
+                Log.d(TAG, "onProgressChanged:" + progress);
+                InstallState state = stateFromId(packageInstaller, sessionId);
+                if (state != null) {
+                    inProgressSessions.put(sessionId, state);
+                    liveData.postValue(state);
+                }
+            }
+
+            @Override
+            public void onFinished(int sessionId, boolean success) {
+                Log.d(TAG, "onFinished " + sessionId + " " + success);
+                InstallState current = inProgressSessions.get(sessionId);
+                if (current != null) {
+                    InstallState newState = new InstallState(current.getAppPackageName(), success ? InstallStatus.SUCCEEDED : InstallStatus.FAILED);
+                    liveData.postValue(newState);
+                    inProgressSessions.remove(sessionId);
+                }
+            }
+        };
+
+        packageInstaller.registerSessionCallback(callback);
+
+        for (PackageInstaller.SessionInfo info : packageInstaller.getMySessions()) {
+            if (info.isActive() && info.getAppPackageName() != null) {
+                InstallState state = new InstallState(info.getAppPackageName(), InstallStatus.IN_PROGRESS);
+                inProgressSessions.put(info.getSessionId(), state);
+                liveData.postValue(state);
+            }
+        }
+
+        return liveData;
+    }
+
+    private static final String TAG = "InstallationObserver";
+}
diff --git a/examples/tv-app/android/BUILD.gn b/examples/tv-app/android/BUILD.gn
index 38c75d9273c243..dea0e8dc89bae7 100644
--- a/examples/tv-app/android/BUILD.gn
+++ b/examples/tv-app/android/BUILD.gn
@@ -28,8 +28,6 @@ shared_library("jni") {
     "include/account-login/AccountLoginManager.h",
     "include/application-basic/ApplicationBasicManager.cpp",
     "include/application-basic/ApplicationBasicManager.h",
-    "include/application-launcher/ApplicationLauncherManager.cpp",
-    "include/application-launcher/ApplicationLauncherManager.h",
     "include/audio-output/AudioOutputManager.cpp",
     "include/audio-output/AudioOutputManager.h",
     "include/cluster-init.cpp",
@@ -41,6 +39,8 @@ shared_library("jni") {
     "include/media-playback/AppMediaPlaybackManager.h",
     "include/target-navigator/TargetNavigatorManager.cpp",
     "include/target-navigator/TargetNavigatorManager.h",
+    "java/application-launcher/ApplicationLauncherManager.cpp",
+    "java/application-launcher/ApplicationLauncherManager.h",
     "java/AppImpl.cpp",
     "java/AppImpl.h",
     "java/AppPlatform-JNI.cpp",
@@ -113,6 +113,8 @@ android_library("java") {
   ]
 
   sources = [
+    "java/src/com/matter/tv/server/tvapp/Application.java",
+    "java/src/com/matter/tv/server/tvapp/ApplicationLauncherManager.java",
     "java/src/com/matter/tv/server/tvapp/AppPlatform.java",
     "java/src/com/matter/tv/server/tvapp/AppPlatformShellCommands.java",
     "java/src/com/matter/tv/server/tvapp/ChannelInfo.java",
@@ -136,6 +138,7 @@ android_library("java") {
     "java/src/com/matter/tv/server/tvapp/DeviceEventProvider.java",
     "java/src/com/matter/tv/server/tvapp/KeypadInputManager.java",
     "java/src/com/matter/tv/server/tvapp/KeypadInputManagerStub.java",
+    "java/src/com/matter/tv/server/tvapp/LauncherResponse.java",
     "java/src/com/matter/tv/server/tvapp/LevelManager.java",
     "java/src/com/matter/tv/server/tvapp/LevelManagerStub.java",
     "java/src/com/matter/tv/server/tvapp/LowPowerManager.java",
diff --git a/examples/tv-app/android/include/application-launcher/ApplicationLauncherManager.cpp b/examples/tv-app/android/include/application-launcher/ApplicationLauncherManager.cpp
deleted file mode 100644
index c915856f48fd4d..00000000000000
--- a/examples/tv-app/android/include/application-launcher/ApplicationLauncherManager.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- *
- *    Copyright (c) 2021 Project CHIP Authors
- *    All rights reserved.
- *
- *    Licensed under the Apache License, Version 2.0 (the "License");
- *    you may not use this file except in compliance with the License.
- *    You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- */
-
-#include "ApplicationLauncherManager.h"
-
-using namespace std;
-using namespace chip::app;
-using namespace chip::app::Clusters;
-using namespace chip::app::Clusters::ApplicationLauncher;
-using namespace chip::Uint8;
-
-CHIP_ERROR ApplicationLauncherManager::HandleGetCatalogList(AttributeValueEncoder & aEncoder)
-{
-    std::list<uint16_t> catalogList = { 123, 456 };
-    return aEncoder.EncodeList([catalogList](const auto & encoder) -> CHIP_ERROR {
-        for (const auto & catalog : catalogList)
-        {
-            ReturnErrorOnFailure(encoder.Encode(catalog));
-        }
-        return CHIP_NO_ERROR;
-    });
-}
-
-void ApplicationLauncherManager::HandleLaunchApp(CommandResponseHelper<LauncherResponseType> & helper, const ByteSpan & data,
-                                                 const ApplicationType & application)
-{
-    ChipLogProgress(Zcl, "ApplicationLauncherManager::HandleLaunchApp");
-
-    // TODO: Insert code here
-    LauncherResponseType response;
-    const char * buf = "data";
-    response.data.SetValue(ByteSpan(from_const_char(buf), strlen(buf)));
-    response.status = StatusEnum::kSuccess;
-    helper.Success(response);
-}
-
-void ApplicationLauncherManager::HandleStopApp(CommandResponseHelper<LauncherResponseType> & helper,
-                                               const ApplicationType & application)
-{
-    ChipLogProgress(Zcl, "ApplicationLauncherManager::HandleStopApp");
-
-    // TODO: Insert code here
-    LauncherResponseType response;
-    const char * buf = "data";
-    response.data.SetValue(ByteSpan(from_const_char(buf), strlen(buf)));
-    response.status = StatusEnum::kSuccess;
-    helper.Success(response);
-}
-
-void ApplicationLauncherManager::HandleHideApp(CommandResponseHelper<LauncherResponseType> & helper,
-                                               const ApplicationType & application)
-{
-    ChipLogProgress(Zcl, "ApplicationLauncherManager::HandleHideApp");
-
-    // TODO: Insert code here
-    LauncherResponseType response;
-    const char * buf = "data";
-    response.data.SetValue(ByteSpan(from_const_char(buf), strlen(buf)));
-    response.status = StatusEnum::kSuccess;
-    helper.Success(response);
-}
diff --git a/examples/tv-app/android/include/cluster-init.cpp b/examples/tv-app/android/include/cluster-init.cpp
index e6f0cd8b481f57..7481625b664a21 100644
--- a/examples/tv-app/android/include/cluster-init.cpp
+++ b/examples/tv-app/android/include/cluster-init.cpp
@@ -17,7 +17,6 @@
  */
 
 #include "application-basic/ApplicationBasicManager.h"
-#include "application-launcher/ApplicationLauncherManager.h"
 #include "audio-output/AudioOutputManager.h"
 #include "target-navigator/TargetNavigatorManager.h"
 
@@ -30,7 +29,6 @@ using namespace chip;
 
 namespace {
 static ApplicationBasicManager applicationBasicManager;
-static ApplicationLauncherManager applicationLauncherManager;
 static AudioOutputManager audioOutputManager;
 static TargetNavigatorManager targetNavigatorManager;
 } // namespace
@@ -50,21 +48,6 @@ void emberAfApplicationBasicClusterInitCallback(chip::EndpointId endpoint)
     chip::app::Clusters::ApplicationBasic::SetDefaultDelegate(endpoint, &applicationBasicManager);
 }
 
-/** @brief Application Launcher  Cluster Init
- *
- * This function is called when a specific cluster is initialized. It gives the
- * application an opportunity to take care of cluster initialization procedures.
- * It is called exactly once for each endpoint where cluster is present.
- *
- * @param endpoint   Ver.: always
- *
- */
-void emberAfApplicationLauncherClusterInitCallback(EndpointId endpoint)
-{
-    ChipLogProgress(Zcl, "TV Android App: ApplicationLauncher::SetDefaultDelegate");
-    chip::app::Clusters::ApplicationLauncher::SetDefaultDelegate(endpoint, &applicationLauncherManager);
-}
-
 /** @brief Audio Output Cluster Init
  *
  * This function is called when a specific cluster is initialized. It gives the
diff --git a/examples/tv-app/android/java/AppImpl.h b/examples/tv-app/android/java/AppImpl.h
index b10c96608c8fc1..1593f263f30244 100644
--- a/examples/tv-app/android/java/AppImpl.h
+++ b/examples/tv-app/android/java/AppImpl.h
@@ -35,11 +35,11 @@
 
 #include "../include/account-login/AccountLoginManager.h"
 #include "../include/application-basic/ApplicationBasicManager.h"
-#include "../include/application-launcher/ApplicationLauncherManager.h"
 #include "../include/content-control/ContentController.h"
 #include "../include/content-launcher/AppContentLauncherManager.h"
 #include "../include/media-playback/AppMediaPlaybackManager.h"
 #include "../include/target-navigator/TargetNavigatorManager.h"
+#include "application-launcher/ApplicationLauncherManager.h"
 #include "ChannelManager.h"
 #include "CommissionerMain.h"
 #include "ContentAppAttributeDelegate.h"
diff --git a/examples/tv-app/android/java/TVApp-JNI.cpp b/examples/tv-app/android/java/TVApp-JNI.cpp
index 65a0a4409e9b8f..f2829dda6b1004 100644
--- a/examples/tv-app/android/java/TVApp-JNI.cpp
+++ b/examples/tv-app/android/java/TVApp-JNI.cpp
@@ -17,6 +17,7 @@
  */
 
 #include "TvApp-JNI.h"
+#include "application-launcher/ApplicationLauncherManager.h"
 #include "ChannelManager.h"
 #include "CommissionerMain.h"
 #include "ContentLauncherManager.h"
@@ -139,6 +140,11 @@ JNI_METHOD(void, setMediaPlaybackManager)(JNIEnv *, jobject, jint endpoint, jobj
     MediaPlaybackManager::NewManager(endpoint, manager);
 }
 
+JNI_METHOD(void, setApplicationLauncherManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
+{
+    ApplicationLauncherManager::NewManager(endpoint, manager);
+}
+
 JNI_METHOD(void, setMessagesManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
 {
     MessagesManager::NewManager(endpoint, manager);
diff --git a/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp b/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
new file mode 100644
index 00000000000000..97515f1efecd29
--- /dev/null
+++ b/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
@@ -0,0 +1,337 @@
+/*
+ *
+ *    Copyright (c) 2021 Project CHIP Authors
+ *    All rights reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "ApplicationLauncherManager.h"
+#include "../TvApp-JNI.h"
+#include <app-common/zap-generated/attributes/Accessors.h>
+#include <app-common/zap-generated/ids/Clusters.h>
+#include <app/util/config.h>
+#include <jni.h>
+#include <lib/core/CHIPSafeCasts.h>
+#include <lib/support/CHIPJNIError.h>
+#include <lib/support/JniReferences.h>
+#include <lib/support/JniTypeWrappers.h>
+
+using namespace std;
+using namespace chip::app;
+using namespace chip::app::Clusters;
+using namespace chip::app::Clusters::ApplicationLauncher;
+using namespace chip::Uint8;
+
+void emberAfApplicationLauncherClusterInitCallback(chip::EndpointId endpoint)
+{
+    ChipLogProgress(Zcl, "TV Android App: ApplicationLauncher::PostClusterInit");
+    if (endpoint > kLocalVideoPlayerEndpointId) {
+        ChipLogProgress(Zcl, "TV Android App: ignore setting the delegate for endpoints larger than 1");
+        return;
+    }
+    TvAppJNIMgr().PostClusterInit(chip::app::Clusters::ApplicationLauncher::Id, endpoint);
+}
+
+void ApplicationLauncherManager::NewManager(jint endpoint, jobject manager)
+{
+    if (endpoint > kLocalVideoPlayerEndpointId) {
+        ChipLogProgress(Zcl, "TV Android App: ignore setting the delegate for endpoints larger than 1");
+        return;
+    }
+    ChipLogProgress(Zcl, "TV Android App: ApplicationLauncher::SetDefaultDelegate for endpoint: %d", endpoint);
+    ApplicationLauncherManager * mgr = new ApplicationLauncherManager();
+    mgr->InitializeWithObjects(manager);
+    chip::app::Clusters::ApplicationLauncher::SetDefaultDelegate(static_cast<chip::EndpointId>(endpoint), mgr);
+}
+
+CHIP_ERROR ApplicationLauncherManager::HandleGetCatalogList(AttributeValueEncoder & aEncoder)
+{
+    chip::DeviceLayer::StackUnlock unlock;
+    CHIP_ERROR err = CHIP_NO_ERROR;
+    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
+    std::list<std::string> acceptedHeadersList;
+    VerifyOrReturnError(env != nullptr, CHIP_JNI_ERROR_NO_ENV, ChipLogError(Zcl, "Could not get JNIEnv for current thread"));
+    chip::JniLocalReferenceScope scope(env);
+
+    ChipLogProgress(Zcl, "Received ApplicationLauncherManager::GetCatalogList");
+    VerifyOrExit(mApplicationLauncherManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE);
+    VerifyOrExit(mGetCatalogListMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
+
+    env->ExceptionClear();
+
+    return aEncoder.EncodeList([this, env](const auto & encoder) -> CHIP_ERROR {
+        jobjectArray jCatalogList =
+            (jobjectArray) env->CallObjectMethod(mApplicationLauncherManagerObject.ObjectRef(), mGetCatalogListMethod);
+        if (env->ExceptionCheck())
+        {
+            ChipLogError(Zcl, "Java exception in ApplicationLauncherManager::GetCatalogList");
+            env->ExceptionDescribe();
+            env->ExceptionClear();
+            return CHIP_ERROR_INCORRECT_STATE;
+        }
+
+        jint size = env->GetArrayLength(jCatalogList);
+        for (int i = 0; i < size; i++)
+        {
+            jint jCatalogVendorId = (jint) env->GetObjectArrayElement(jCatalogList, i);
+            ReturnErrorOnFailure(encoder.Encode(static_cast<uint16_t>(jCatalogVendorId)));
+        }
+
+        return CHIP_NO_ERROR;
+    });
+
+exit:
+    if (err != CHIP_NO_ERROR)
+    {
+        ChipLogError(Zcl, "ApplicationLauncherManager::GetCatalogList status error: %s", err.AsString());
+    }
+
+    return err;
+}
+
+void ApplicationLauncherManager::HandleLaunchApp(CommandResponseHelper<LauncherResponseType> & helper, const ByteSpan & data,
+                                                 const ApplicationType & application)
+{
+    chip::DeviceLayer::StackUnlock unlock;
+    LauncherResponseType response;
+    CHIP_ERROR err = CHIP_NO_ERROR;
+    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
+    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNIEnv for current thread"));
+    chip::JniLocalReferenceScope scope(env);
+
+    ChipLogProgress(Zcl, "Received ApplicationLauncherManager::LaunchApp");
+    VerifyOrExit(mApplicationLauncherManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE);
+    VerifyOrExit(mLaunchAppMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
+
+    env->ExceptionClear();
+
+    {   
+        // UtfString accepts const char * data
+        chip::UtfString jByteData(env, reinterpret_cast<const char*>(data.data()));
+
+        chip::UtfString jappId(env, application.applicationID);
+
+        // Create an instance of Application
+        jobject appObject = env->NewObject(mApplicationClass, mCreateApplicationMethod, static_cast<jint>(application.catalogVendorID), jappId.jniValue());
+        VerifyOrReturn(appObject != nullptr, ChipLogError(Zcl, "Failed to create Application object"));
+
+        jobject resp = env->CallObjectMethod(mApplicationLauncherManagerObject.ObjectRef(), mLaunchAppMethod, appObject, 
+                                             jByteData.jniValue());
+        if (env->ExceptionCheck())
+        {
+            ChipLogError(Zcl, "Java exception in ApplicationLauncherManager::LaunchApp");
+            env->ExceptionDescribe();
+            env->ExceptionClear();
+            err = CHIP_ERROR_INCORRECT_STATE;
+            goto exit;
+        }
+
+        VerifyOrExit(resp != nullptr, err = CHIP_JNI_ERROR_NULL_OBJECT);
+        jclass respCls     = env->GetObjectClass(resp);
+        jfieldID statusFid = env->GetFieldID(respCls, "status", "I");
+        VerifyOrExit(statusFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND);
+        jint status = env->GetIntField(resp, statusFid);
+
+        jfieldID dataFid = env->GetFieldID(respCls, "data", "Ljava/lang/String;");
+        VerifyOrExit(dataFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND);
+        jstring jdataStr = (jstring) env->GetObjectField(resp, dataFid);
+        chip::JniUtfString dataStr(env, jdataStr);
+
+        response.status = static_cast<chip::app::Clusters::ApplicationLauncher::StatusEnum>(status);
+        response.data   = chip::Optional<chip::ByteSpan>(dataStr.byteSpan());
+
+        err = helper.Success(response);
+    }
+
+exit:
+    if (err != CHIP_NO_ERROR)
+    {
+        ChipLogError(Zcl, "ApplicationLauncherManager::LaunchApp status error: %s", err.AsString());
+    }
+}
+
+void ApplicationLauncherManager::HandleStopApp(CommandResponseHelper<LauncherResponseType> & helper,
+                                               const ApplicationType & application)
+{
+    chip::DeviceLayer::StackUnlock unlock;
+    LauncherResponseType response;
+    CHIP_ERROR err = CHIP_NO_ERROR;
+    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
+    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNIEnv for current thread"));
+    chip::JniLocalReferenceScope scope(env);
+
+    ChipLogProgress(Zcl, "Received ApplicationLauncherManager::StopApp");
+    VerifyOrExit(mApplicationLauncherManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE);
+    VerifyOrExit(mStopAppMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
+
+    env->ExceptionClear();
+
+    {   
+        chip::UtfString jappId(env, application.applicationID);
+
+        // Create an instance of Application
+        jobject appObject = env->NewObject(mApplicationClass, mCreateApplicationMethod, static_cast<jint>(application.catalogVendorID), jappId.jniValue());
+        VerifyOrReturn(appObject != nullptr, ChipLogError(Zcl, "Failed to create Application object"));
+
+        jobject resp = env->CallObjectMethod(mApplicationLauncherManagerObject.ObjectRef(), mStopAppMethod, appObject);
+        if (env->ExceptionCheck())
+        {
+            ChipLogError(Zcl, "Java exception in ApplicationLauncherManager::StopApp");
+            env->ExceptionDescribe();
+            env->ExceptionClear();
+            err = CHIP_ERROR_INCORRECT_STATE;
+            goto exit;
+        }
+
+        VerifyOrExit(resp != nullptr, err = CHIP_JNI_ERROR_NULL_OBJECT);
+        jclass respCls     = env->GetObjectClass(resp);
+        jfieldID statusFid = env->GetFieldID(respCls, "status", "I");
+        VerifyOrExit(statusFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND);
+        jint status = env->GetIntField(resp, statusFid);
+
+        jfieldID dataFid = env->GetFieldID(respCls, "data", "Ljava/lang/String;");
+        VerifyOrExit(dataFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND);
+        jstring jdataStr = (jstring) env->GetObjectField(resp, dataFid);
+        chip::JniUtfString dataStr(env, jdataStr);
+
+        response.status = static_cast<chip::app::Clusters::ApplicationLauncher::StatusEnum>(status);
+        response.data   = chip::Optional<chip::ByteSpan>(dataStr.byteSpan());
+
+        err = helper.Success(response);
+    }
+
+exit:
+    if (err != CHIP_NO_ERROR)
+    {
+        ChipLogError(Zcl, "ApplicationLauncherManager::StopApp status error: %s", err.AsString());
+    }
+}
+
+void ApplicationLauncherManager::HandleHideApp(CommandResponseHelper<LauncherResponseType> & helper,
+                                               const ApplicationType & application)
+{
+    chip::DeviceLayer::StackUnlock unlock;
+    LauncherResponseType response;
+    CHIP_ERROR err = CHIP_NO_ERROR;
+    JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
+    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNIEnv for current thread"));
+    chip::JniLocalReferenceScope scope(env);
+
+    ChipLogProgress(Zcl, "Received ApplicationLauncherManager::HideApp");
+    VerifyOrExit(mApplicationLauncherManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE);
+    VerifyOrExit(mHideAppMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
+
+    env->ExceptionClear();
+
+    {   
+        chip::UtfString jappId(env, application.applicationID);
+
+        // Create an instance of Application
+        jobject appObject = env->NewObject(mApplicationClass, mCreateApplicationMethod, static_cast<jint>(application.catalogVendorID), jappId.jniValue());
+        VerifyOrReturn(appObject != nullptr, ChipLogError(Zcl, "Failed to create Application object"));
+
+        jobject resp = env->CallObjectMethod(mApplicationLauncherManagerObject.ObjectRef(), mHideAppMethod, appObject);
+        if (env->ExceptionCheck())
+        {
+            ChipLogError(Zcl, "Java exception in ApplicationLauncherManager::HideApp");
+            env->ExceptionDescribe();
+            env->ExceptionClear();
+            err = CHIP_ERROR_INCORRECT_STATE;
+            goto exit;
+        }
+
+        VerifyOrExit(resp != nullptr, err = CHIP_JNI_ERROR_NULL_OBJECT);
+        jclass respCls     = env->GetObjectClass(resp);
+        jfieldID statusFid = env->GetFieldID(respCls, "status", "I");
+        VerifyOrExit(statusFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND);
+        jint status = env->GetIntField(resp, statusFid);
+
+        jfieldID dataFid = env->GetFieldID(respCls, "data", "Ljava/lang/String;");
+        VerifyOrExit(dataFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND);
+        jstring jdataStr = (jstring) env->GetObjectField(resp, dataFid);
+        chip::JniUtfString dataStr(env, jdataStr);
+
+        response.status = static_cast<chip::app::Clusters::ApplicationLauncher::StatusEnum>(status);
+        response.data   = chip::Optional<chip::ByteSpan>(dataStr.byteSpan());
+
+        err = helper.Success(response);
+    }
+
+exit:
+    if (err != CHIP_NO_ERROR)
+    {
+        ChipLogError(Zcl, "ApplicationLauncherManager::HideApp status error: %s", err.AsString());
+    }
+}
+
+void ApplicationLauncherManager::InitializeWithObjects(jobject managerObject)
+{
+    JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
+    VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Failed to GetEnvForCurrentThread for ApplicationLauncherManager"));
+
+    VerifyOrReturn(mApplicationLauncherManagerObject.Init(managerObject) == CHIP_NO_ERROR,
+                   ChipLogError(Zcl, "Failed to init mApplicationLauncherManagerObject"));
+
+    jclass applicationLauncherClass = env->GetObjectClass(managerObject);
+    VerifyOrReturn(applicationLauncherClass != nullptr, ChipLogError(Zcl, "Failed to get ApplicationLauncherManager Java class"));
+
+    mGetCatalogListMethod = env->GetMethodID(applicationLauncherClass, "getCatalogList", "()[I");
+    if (mGetCatalogListMethod == nullptr)
+    {
+        ChipLogError(Zcl, "Failed to access ApplicationLauncherManager 'getCatalogList' method");
+        env->ExceptionClear();
+    }
+
+    mLaunchAppMethod = env->GetMethodID(applicationLauncherClass, "launchApp", "(Lcom/matter/tv/server/tvapp/"
+                                        "Application;Ljava/lang/String;)Lcom/matter/tv/server/tvapp/LauncherResponse;");
+    if (mLaunchAppMethod == nullptr)
+    {
+        ChipLogError(Zcl, "Failed to access ApplicationLauncherManager 'launchApp' method");
+        env->ExceptionClear();
+    }
+
+    mStopAppMethod = env->GetMethodID(applicationLauncherClass, "stopApp", "(Lcom/matter/tv/server/tvapp/"
+                                        "Application;)Lcom/matter/tv/server/tvapp/LauncherResponse;");
+    if (mStopAppMethod == nullptr)
+    {
+        ChipLogError(Zcl, "Failed to access ApplicationLauncherManager 'stopApp' method");
+        env->ExceptionClear();
+    }
+
+    mHideAppMethod = env->GetMethodID(applicationLauncherClass, "hideApp", "(Lcom/matter/tv/server/tvapp/"
+                                        "Application;)Lcom/matter/tv/server/tvapp/LauncherResponse;");
+    if (mHideAppMethod == nullptr)
+    {
+        ChipLogError(Zcl, "Failed to access ApplicationLauncherManager 'hideApp' method");
+        env->ExceptionClear();
+    }
+
+    // Find the Application class
+    jclass jc = env->FindClass("com/matter/tv/server/tvapp/Application");
+    // convert it to a global reference, otherwise code will crash
+    mApplicationClass = static_cast<jclass>(env->NewGlobalRef(jc));
+    if (mApplicationClass == nullptr)
+    {
+        ChipLogError(Zcl, "Failed to find Application Java class");
+        env->ExceptionClear();
+    }
+
+    // Get the constructor method ID
+    mCreateApplicationMethod = env->GetMethodID(mApplicationClass, "<init>", "(ILjava/lang/String;)V");
+    if (mCreateApplicationMethod == nullptr)
+    {
+        ChipLogError(Zcl, "Failed to find constructor of Application Java class");
+        env->ExceptionClear();
+    }
+}
\ No newline at end of file
diff --git a/examples/tv-app/android/include/application-launcher/ApplicationLauncherManager.h b/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.h
similarity index 72%
rename from examples/tv-app/android/include/application-launcher/ApplicationLauncherManager.h
rename to examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.h
index ffdd89ca8731e9..2b3ed006f72800 100644
--- a/examples/tv-app/android/include/application-launcher/ApplicationLauncherManager.h
+++ b/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.h
@@ -19,7 +19,9 @@
 #pragma once
 
 #include <app/clusters/application-launcher-server/application-launcher-server.h>
-#include <list>
+
+#include <jni.h>
+#include <lib/support/JniReferences.h>
 
 using chip::ByteSpan;
 using chip::app::AttributeValueEncoder;
@@ -28,11 +30,13 @@ using ApplicationLauncherDelegate = chip::app::Clusters::ApplicationLauncher::De
 using ApplicationType             = chip::app::Clusters::ApplicationLauncher::Structs::ApplicationStruct::Type;
 using LauncherResponseType        = chip::app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Type;
 
+inline constexpr chip::EndpointId kLocalVideoPlayerEndpointId = 1;
+
 class ApplicationLauncherManager : public ApplicationLauncherDelegate
 {
 public:
-    ApplicationLauncherManager() : ApplicationLauncherDelegate(){};
-    ApplicationLauncherManager(bool featureMapContentPlatform) : ApplicationLauncherDelegate(featureMapContentPlatform){};
+    static void NewManager(jint endpoint, jobject manager);
+    void InitializeWithObjects(jobject managerObject);
 
     CHIP_ERROR HandleGetCatalogList(AttributeValueEncoder & aEncoder) override;
 
@@ -40,4 +44,12 @@ class ApplicationLauncherManager : public ApplicationLauncherDelegate
                          const ApplicationType & application) override;
     void HandleStopApp(CommandResponseHelper<LauncherResponseType> & helper, const ApplicationType & application) override;
     void HandleHideApp(CommandResponseHelper<LauncherResponseType> & helper, const ApplicationType & application) override;
+
+    chip::JniGlobalReference mApplicationLauncherManagerObject;
+    jmethodID mGetCatalogListMethod               = nullptr;
+    jmethodID mLaunchAppMethod                    = nullptr;
+    jmethodID mStopAppMethod                      = nullptr;
+    jmethodID mHideAppMethod                      = nullptr;
+    jmethodID mCreateApplicationMethod            = nullptr;
+    jclass mApplicationClass                      = nullptr;
 };
diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Application.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Application.java
new file mode 100644
index 00000000000000..86da098c292235
--- /dev/null
+++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Application.java
@@ -0,0 +1,46 @@
+/*
+ *   Copyright (c) 2021 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package com.matter.tv.server.tvapp;
+
+public class Application {
+
+  public int catalogVendorId;
+  public String applicationId;
+
+  public Application(
+      int catalogVendorId,
+      String applicationId) {
+    this.catalogVendorId = catalogVendorId;
+    this.applicationId = applicationId;
+  }
+
+  public Application createApplication(int catalogVendorId,
+                                       String applicationId) {
+    return new Application(catalogVendorId, applicationId);
+  }
+
+  @Override
+  public String toString() {
+    return "Application{"
+        + "catalogVendorId="
+        + catalogVendorId
+        + ", applicationId='"
+        + '\''
+        + '}';
+  }
+}
diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/ApplicationLauncherManager.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/ApplicationLauncherManager.java
new file mode 100644
index 00000000000000..1cc51e9b09e17d
--- /dev/null
+++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/ApplicationLauncherManager.java
@@ -0,0 +1,36 @@
+package com.matter.tv.server.tvapp;
+
+public interface ApplicationLauncherManager {
+
+  /**
+   * Return a list of available catalogs
+   * 
+   * @return list of int
+   */
+  int[] getCatalogList();
+
+  /**
+   * Launch an app
+   * 
+   * @param app that you want to launch 
+   * @param data to send addditional data if needed
+   * @return launcher response with status 
+   */
+  LauncherResponse launchApp(Application app, String data);
+
+  /**
+   * Stop an app
+   * 
+   * @param app that you want to stop
+   * @return launcher response with status
+   */
+  LauncherResponse stopApp(Application app);
+
+  /**
+   * hide an app
+   * 
+   * @param app that you want to hide
+   * @return launcher response with status
+   */
+  LauncherResponse hideApp(Application app);
+}
diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/LauncherResponse.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/LauncherResponse.java
new file mode 100644
index 00000000000000..391f92b82f319e
--- /dev/null
+++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/LauncherResponse.java
@@ -0,0 +1,21 @@
+package com.matter.tv.server.tvapp;
+
+public class LauncherResponse {
+
+  public static final int STATUS_SUCCESS = 0;
+  public static final int STATUS_APP_NOT_AVAILABLE = 1;
+  public static final int STATUS_SYSTEM_BUSY = 2;
+  public static final int STATUS_PENDING = 3;
+  public static final int STATUS_INSTALLING = 4;
+
+  public LauncherResponse(int status, String data) {
+    this.status = status;
+    this.data = data;
+  }
+
+  /** The status in STATUS_XXX */
+  public int status;
+
+  /** Optional app-specific data. */
+  public String data;
+}
diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/TvApp.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/TvApp.java
index eaf207e45f3618..abc0b55007c7e1 100644
--- a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/TvApp.java
+++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/TvApp.java
@@ -47,6 +47,8 @@ private void postClusterInit(long clusterId, int endpoint) {
 
   public native void setKeypadInputManager(int endpoint, KeypadInputManager manager);
 
+  public native void setApplicationLauncherManager(int endpoint, ApplicationLauncherManager manager);
+
   public native void setWakeOnLanManager(int endpoint, WakeOnLanManager manager);
 
   public native void setMediaInputManager(int endpoint, MediaInputManager manager);
diff --git a/examples/tv-app/tv-common/tv-app.matter b/examples/tv-app/tv-common/tv-app.matter
index 34aa4475c79677..727f999ae69f70 100644
--- a/examples/tv-app/tv-common/tv-app.matter
+++ b/examples/tv-app/tv-common/tv-app.matter
@@ -3259,6 +3259,8 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
+    kStatusPending = 3;
+    kStatusInstalling = 4;
   }
 
   bitmap Feature : bitmap32 {
diff --git a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter
index 02aadc0439b50a..e0d4d1ea069aa7 100644
--- a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter
+++ b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter
@@ -2699,6 +2699,8 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
+    kStatusPending = 3;
+    kStatusInstalling = 4;
   }
 
   bitmap Feature : bitmap32 {
diff --git a/src/app/clusters/application-launcher-server/application-launcher-server.cpp b/src/app/clusters/application-launcher-server/application-launcher-server.cpp
index ed6265e47c485b..c3e490d2c9119c 100644
--- a/src/app/clusters/application-launcher-server/application-launcher-server.cpp
+++ b/src/app/clusters/application-launcher-server/application-launcher-server.cpp
@@ -255,7 +255,7 @@ bool emberAfApplicationLauncherClusterLaunchAppCallback(app::CommandHandler * co
         //  4. Call launch app command on Content App
         if (delegate->HasFeature(Feature::kApplicationPlatform))
         {
-            ChipLogError(Zcl, "ApplicationLauncher has content platform feature");
+            ChipLogProgress(Zcl, "ApplicationLauncher has content platform feature");
             ContentApp * app = ContentAppPlatform::GetInstance().LoadContentApp(&vendorApp);
             if (app == nullptr)
             {
@@ -268,7 +268,7 @@ bool emberAfApplicationLauncherClusterLaunchAppCallback(app::CommandHandler * co
 
             ContentAppPlatform::GetInstance().SetCurrentApp(app);
 
-            ChipLogError(Zcl, "ApplicationLauncher handling launch on ContentApp");
+            ChipLogProgress(Zcl, "ApplicationLauncher handling launch on ContentApp");
             app->GetApplicationLauncherDelegate()->HandleLaunchApp(responder, data.HasValue() ? data.Value() : ByteSpan(),
                                                                    application.Value());
             return true;
@@ -278,11 +278,11 @@ bool emberAfApplicationLauncherClusterLaunchAppCallback(app::CommandHandler * co
        //  1. Set Content App status (basic cluster) to ACTIVE_VISIBLE_FOCUS
        //  2. Call launch app command on the given endpoint
 
-        ChipLogError(Zcl, "ApplicationLauncher no content platform feature");
+        ChipLogProgress(Zcl, "ApplicationLauncher no content platform feature");
         ApplicationBasic::Delegate * appBasic = ApplicationBasic::GetDefaultDelegate(endpoint);
         if (appBasic != nullptr)
         {
-            ChipLogError(Zcl, "ApplicationLauncher setting basic cluster status to visible");
+            ChipLogProgress(Zcl, "ApplicationLauncher setting basic cluster status to visible");
             appBasic->SetApplicationStatus(ApplicationStatusEnum::kActiveVisibleFocus);
         }
 
@@ -292,9 +292,9 @@ bool emberAfApplicationLauncherClusterLaunchAppCallback(app::CommandHandler * co
         {
             ContentAppPlatform::GetInstance().SetCurrentApp(app);
         }
-        else
+        else if (delegate->HasFeature(Feature::kApplicationPlatform))
         {
-            ChipLogError(Zcl, "ApplicationLauncher target app not found");
+            ChipLogProgress(Zcl, "ApplicationLauncher target app not found");
             LauncherResponseType response;
             response.status = StatusEnum::kAppNotAvailable;
             responder.Success(response);
@@ -302,7 +302,7 @@ bool emberAfApplicationLauncherClusterLaunchAppCallback(app::CommandHandler * co
         }
 #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
 
-        ChipLogError(Zcl, "ApplicationLauncher handling launch");
+        ChipLogProgress(Zcl, "ApplicationLauncher handling launch");
         delegate->HandleLaunchApp(responder, data.HasValue() ? data.Value() : ByteSpan(), application.Value());
     }
 
@@ -349,7 +349,7 @@ bool emberAfApplicationLauncherClusterStopAppCallback(app::CommandHandler * comm
         //  4. Call stop app command on Content App
         if (delegate->HasFeature(Feature::kApplicationPlatform))
         {
-            ChipLogError(Zcl, "ApplicationLauncher has content platform feature");
+            ChipLogProgress(Zcl, "ApplicationLauncher has content platform feature");
             ContentApp * app = ContentAppPlatform::GetInstance().LoadContentApp(&vendorApp);
             if (app == nullptr)
             {
@@ -362,10 +362,10 @@ bool emberAfApplicationLauncherClusterStopAppCallback(app::CommandHandler * comm
 
             ContentAppPlatform::GetInstance().UnsetIfCurrentApp(app);
 
-            ChipLogError(Zcl, "ApplicationLauncher setting app status");
+            ChipLogProgress(Zcl, "ApplicationLauncher setting app status");
             app->GetApplicationBasicDelegate()->SetApplicationStatus(ApplicationStatusEnum::kStopped);
 
-            ChipLogError(Zcl, "ApplicationLauncher handling stop on ContentApp");
+            ChipLogProgress(Zcl, "ApplicationLauncher handling stop on ContentApp");
             app->GetApplicationLauncherDelegate()->HandleStopApp(responder, application.Value());
             return true;
         }
@@ -374,7 +374,7 @@ bool emberAfApplicationLauncherClusterStopAppCallback(app::CommandHandler * comm
        //  1. Set Content App status (basic cluster) to ACTIVE_STOPPED
        //  2. Call launch app command on the given endpoint
 
-        ChipLogError(Zcl, "ApplicationLauncher no content platform feature");
+        ChipLogProgress(Zcl, "ApplicationLauncher no content platform feature");
 
 #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
         ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(&vendorApp);
@@ -388,7 +388,7 @@ bool emberAfApplicationLauncherClusterStopAppCallback(app::CommandHandler * comm
         ApplicationBasic::Delegate * appBasic = ApplicationBasic::GetDefaultDelegate(endpoint);
         if (appBasic != nullptr)
         {
-            ChipLogError(Zcl, "ApplicationLauncher setting basic cluster status to stopped");
+            ChipLogProgress(Zcl, "ApplicationLauncher setting basic cluster status to stopped");
             appBasic->SetApplicationStatus(ApplicationStatusEnum::kStopped);
         }
 
@@ -438,7 +438,7 @@ bool emberAfApplicationLauncherClusterHideAppCallback(app::CommandHandler * comm
         //  4. Call stop app command on Content App
         if (delegate->HasFeature(Feature::kApplicationPlatform))
         {
-            ChipLogError(Zcl, "ApplicationLauncher has content platform feature");
+            ChipLogProgress(Zcl, "ApplicationLauncher has content platform feature");
             ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(&vendorApp);
             if (app == nullptr)
             {
@@ -451,7 +451,7 @@ bool emberAfApplicationLauncherClusterHideAppCallback(app::CommandHandler * comm
 
             ContentAppPlatform::GetInstance().UnsetIfCurrentApp(app);
 
-            ChipLogError(Zcl, "ApplicationLauncher handling stop on ContentApp");
+            ChipLogProgress(Zcl, "ApplicationLauncher handling stop on ContentApp");
             app->GetApplicationLauncherDelegate()->HandleHideApp(responder, application.Value());
             return true;
         }
@@ -460,7 +460,7 @@ bool emberAfApplicationLauncherClusterHideAppCallback(app::CommandHandler * comm
        //  1. Set Content App status (basic cluster) to ACTIVE_VISIBLE_NOT_FOCUS
        //  2. Call launch app command on the given endpoint
 
-        ChipLogError(Zcl, "ApplicationLauncher no content platform feature");
+        ChipLogProgress(Zcl, "ApplicationLauncher no content platform feature");
 
 #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
         ContentApp * app = ContentAppPlatform::GetInstance().GetContentApp(&vendorApp);
@@ -473,7 +473,7 @@ bool emberAfApplicationLauncherClusterHideAppCallback(app::CommandHandler * comm
         ApplicationBasic::Delegate * appBasic = ApplicationBasic::GetDefaultDelegate(endpoint);
         if (appBasic != nullptr)
         {
-            ChipLogError(Zcl, "ApplicationLauncher setting basic cluster status to stopped");
+            ChipLogProgress(Zcl, "ApplicationLauncher setting basic cluster status to stopped");
             appBasic->SetApplicationStatus(ApplicationStatusEnum::kActiveHidden);
         }
 
diff --git a/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml
index 8aaca6201074dd..b9ec3964ab069e 100644
--- a/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml
+++ b/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml
@@ -80,5 +80,7 @@ limitations under the License.
     <item name="Success" value="0x00"/>
     <item name="AppNotAvailable" value="0x01"/>
     <item name="SystemBusy" value="0x02"/>
+    <item name="StatusPending" value="0x03"/>
+    <item name="StatusInstalling" value="0x04"/>
   </enum>
 </configurator>
diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter
index 810f82819c1a19..1a276502f37093 100644
--- a/src/controller/data_model/controller-clusters.matter
+++ b/src/controller/data_model/controller-clusters.matter
@@ -9114,6 +9114,8 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
+    kStatusPending = 3;
+    kStatusInstalling = 4;
   }
 
   bitmap Feature : bitmap32 {
diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py
index 670c7109a5ccb8..e6f060d36251fc 100644
--- a/src/controller/python/chip/clusters/Objects.py
+++ b/src/controller/python/chip/clusters/Objects.py
@@ -45574,11 +45574,13 @@ class StatusEnum(MatterIntEnum):
             kSuccess = 0x00
             kAppNotAvailable = 0x01
             kSystemBusy = 0x02
+            kStatusPending = 0x03
+            kStatusInstalling = 0x04
             # All received enum values that are not listed above will be mapped
             # to kUnknownEnumValue. This is a helper enum value that should only
-            # be used by code to process how it handles receiving an unknown
-            # enum value. This specific value should never be transmitted.
-            kUnknownEnumValue = 3,
+            # be used by code to process how it handles receiving and unknown
+            # enum value. This specific should never be transmitted.
+            kUnknownEnumValue = 5,
 
     class Bitmaps:
         class Feature(IntFlag):
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
index b8dfaa140e03e3..70bdf7b478d62b 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
@@ -21061,6 +21061,8 @@ typedef NS_ENUM(uint8_t, MTRApplicationLauncherStatus) {
     MTRApplicationLauncherStatusSuccess MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x00,
     MTRApplicationLauncherStatusAppNotAvailable MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x01,
     MTRApplicationLauncherStatusSystemBusy MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x02,
+    MTRApplicationLauncherStatusStatusPending MTR_PROVISIONALLY_AVAILABLE = 0x03,
+    MTRApplicationLauncherStatusStatusInstalling MTR_PROVISIONALLY_AVAILABLE = 0x04,
 } MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1));
 
 typedef NS_OPTIONS(uint32_t, MTRApplicationLauncherFeature) {
diff --git a/src/lib/support/JniTypeWrappers.h b/src/lib/support/JniTypeWrappers.h
index 0e64666b3e328e..883b9228482b39 100644
--- a/src/lib/support/JniTypeWrappers.h
+++ b/src/lib/support/JniTypeWrappers.h
@@ -19,6 +19,7 @@
 
 #include <cstdint>
 #include <jni.h>
+#include <lib/core/CHIPSafeCasts.h>
 #include <lib/support/CHIPJNIError.h>
 #include <lib/support/JniReferences.h>
 #include <lib/support/Span.h>
@@ -50,6 +51,8 @@ class JniUtfString
 
     chip::CharSpan charSpan() const { return chip::CharSpan(c_str(), static_cast<size_t>(size())); }
 
+    chip::ByteSpan byteSpan() const { return chip::ByteSpan(chip::Uint8::from_const_char(c_str()), static_cast<size_t>(size())); }
+
     jsize size() const { return mDataLength; }
 
 private:
diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h
index 8a951e2a54a575..ea03297cb40517 100644
--- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h
+++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h
@@ -3425,6 +3425,8 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(ApplicationLauncher::St
     case EnumType::kSuccess:
     case EnumType::kAppNotAvailable:
     case EnumType::kSystemBusy:
+    case EnumType::kStatusPending:
+    case EnumType::kStatusInstalling:
         return val;
     default:
         return EnumType::kUnknownEnumValue;
diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
index a0407517696744..5c06cf190dbd08 100644
--- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
+++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
@@ -5218,14 +5218,16 @@ namespace ApplicationLauncher {
 // Enum for StatusEnum
 enum class StatusEnum : uint8_t
 {
-    kSuccess         = 0x00,
-    kAppNotAvailable = 0x01,
-    kSystemBusy      = 0x02,
+    kSuccess          = 0x00,
+    kAppNotAvailable  = 0x01,
+    kSystemBusy       = 0x02,
+    kStatusPending    = 0x03,
+    kStatusInstalling = 0x04,
     // All received enum values that are not listed above will be mapped
     // to kUnknownEnumValue. This is a helper enum value that should only
     // be used by code to process how it handles receiving and unknown
     // enum value. This specific should never be transmitted.
-    kUnknownEnumValue = 3,
+    kUnknownEnumValue = 5,
 };
 
 // Bitmap for Feature

From 8057d2d98efea27dabffb07f6f3ac848a4488aac Mon Sep 17 00:00:00 2001
From: Lazar Kovacic <lkovacic@amazon.com>
Date: Sat, 29 Jun 2024 02:18:23 +0200
Subject: [PATCH 02/22] Update the code

---
 .../App/.idea/deploymentTargetDropDown.xml    | 10 +++++++++
 examples/tv-app/android/App/.idea/gradle.xml  |  3 +--
 .../contentapp/CommandResponseHolder.java     |  2 --
 .../android/App/platform-app/build.gradle     | 16 +++++++-------
 .../com/matter/tv/server/MainActivity.java    |  1 -
 .../ApplicationLauncherManagerImpl.java       | 21 +++++++++++--------
 .../tv/server/service/AppPlatformService.java |  1 -
 .../ApplicationLauncherManager.cpp            |  2 +-
 .../matter/tv/server/tvapp/Application.java   |  2 +-
 9 files changed, 33 insertions(+), 25 deletions(-)
 create mode 100644 examples/tv-app/android/App/.idea/deploymentTargetDropDown.xml

diff --git a/examples/tv-app/android/App/.idea/deploymentTargetDropDown.xml b/examples/tv-app/android/App/.idea/deploymentTargetDropDown.xml
new file mode 100644
index 00000000000000..5ca3f336b64004
--- /dev/null
+++ b/examples/tv-app/android/App/.idea/deploymentTargetDropDown.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="deploymentTargetDropDown">
+    <value>
+      <entry key="platform-app">
+        <State />
+      </entry>
+    </value>
+  </component>
+</project>
\ No newline at end of file
diff --git a/examples/tv-app/android/App/.idea/gradle.xml b/examples/tv-app/android/App/.idea/gradle.xml
index c55cb656581f0b..6d1563baf79f38 100644
--- a/examples/tv-app/android/App/.idea/gradle.xml
+++ b/examples/tv-app/android/App/.idea/gradle.xml
@@ -4,8 +4,6 @@
   <component name="GradleSettings">
     <option name="linkedExternalProjectsSettings">
       <GradleProjectSettings>
-        <option name="testRunner" value="GRADLE" />
-        <option name="distributionType" value="DEFAULT_WRAPPED" />
         <option name="externalProjectPath" value="$PROJECT_DIR$" />
         <option name="modules">
           <set>
@@ -14,6 +12,7 @@
             <option value="$PROJECT_DIR$/platform-app" />
           </set>
         </option>
+        <option name="resolveExternalAnnotations" value="false" />
       </GradleProjectSettings>
     </option>
   </component>
diff --git a/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/CommandResponseHolder.java b/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/CommandResponseHolder.java
index 86e8d24829f1af..68c7fe04c2d352 100644
--- a/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/CommandResponseHolder.java
+++ b/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/CommandResponseHolder.java
@@ -13,7 +13,6 @@ public class CommandResponseHolder {
   private Map<Long, Map<Long, String>> responseValues = new HashMap<>();
   private static final String TAG = "CommandResponseHolder";
   private static final Long DEFAULT_COMMAND = -1L;
-  private ContentResolver contentResolver;
 
   private static CommandResponseHolder instance = new CommandResponseHolder();
 
@@ -35,7 +34,6 @@ private CommandResponseHolder() {
         Clusters.AccountLogin.Id,
         Clusters.AccountLogin.Commands.GetSetupPIN.ID,
         "{\"0\":\"20202021\"}");
-//    "{\"0\":\""+ Settings.Secure.getInt(contentResolver, "matter_pin_code", 20202021) +"\"}");
   };
 
   public static CommandResponseHolder getInstance() {
diff --git a/examples/tv-app/android/App/platform-app/build.gradle b/examples/tv-app/android/App/platform-app/build.gradle
index 165ec1fbad8fc5..92b31f1f54be6a 100644
--- a/examples/tv-app/android/App/platform-app/build.gradle
+++ b/examples/tv-app/android/App/platform-app/build.gradle
@@ -47,14 +47,14 @@ android {
             aidl.srcDirs = ['../common-api/src/main/aidl']
 
             // uncomment this code to debug
-            java.srcDirs = [
-                    'src/main/java',
-                    '../common-api/src/main/java',
-                    '../../third_party/connectedhomeip/src/setup_payload/java/src',
-                    '../../third_party/connectedhomeip/src/platform/android/java',
-                    '../../third_party/connectedhomeip/src/app/server/java/src/',
-                    '../../java/src',
-            ]
+            // java.srcDirs = [
+            //         'src/main/java',
+            //         '../common-api/src/main/java',
+            //         '../../third_party/connectedhomeip/src/setup_payload/java/src',
+            //         '../../third_party/connectedhomeip/src/platform/android/java',
+            //         '../../third_party/connectedhomeip/src/app/server/java/src/',
+            //         '../../java/src',
+            // ]
         }
     }
     buildFeatures {
diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java
index e78c9a2142802d..64937200733511 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java
@@ -11,7 +11,6 @@
 import com.matter.tv.server.fragments.ContentAppFragment;
 import com.matter.tv.server.fragments.QrCodeFragment;
 import com.matter.tv.server.fragments.TerminalFragment;
-import com.matter.tv.server.utils.InstallationObserver;
 
 import java.util.LinkedHashMap;
 
diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
index 255dd11be9ab56..ebfbd0e5eb0121 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
@@ -38,12 +38,6 @@ public ApplicationLauncherManagerImpl(Context context) {
     registerSelf(context);
   }
 
-  // Add list of apps with latest install statuses - DONE
-  // Add list of installed apps - DONE
-  // Add list of installed apps that support Matter
-  // Store all of the list using Shared pref
-  // Load the stored lists, by asking shared pref
-
   private final Observer<InstallationObserver.InstallState> installStateObserver = state -> {
     lastReceivedInstallationStatus.put(state.getAppPackageName(), state.getStatus());
     switch (state.getStatus()) {
@@ -111,7 +105,10 @@ public LauncherResponse launchApp(Application app, String data) {
       Log.i(TAG, "Matter enabled app is not installed, but app is installed. Launching app's install page");
       status = LauncherResponse.STATUS_PENDING;
       responseData = "App is installed, try updating";
-      // TODO: Launch App Install Page
+
+      //
+      // Add code to launch App Install Page
+      //
 
     } else if (!matterAppEnabledIsInstalled && !appIsInstalled) {
       Log.i(TAG, "Matter enabled app is not installed and app is not installed. Launching app's install page");
@@ -124,12 +121,18 @@ public LauncherResponse launchApp(Application app, String data) {
           responseData = "App install failed. Try again";
         }
       }
-      // TODO: Launch App Install Page
+
+      //
+      // Add code to launch App Install Page
+      //
 
     } else if (matterAppEnabledIsInstalled && appIsInstalled) {
       Log.i(TAG, "Launching the app");
       status = LauncherResponse.STATUS_SUCCESS;
-      // TODO: Launch App
+
+      //
+      // Add code to launch an app
+      //
     }
 
     return new LauncherResponse(status, responseData);
diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java
index 09944c648e187d..0a8dd07ffae2d5 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java
@@ -25,7 +25,6 @@
 import android.util.Log;
 import androidx.annotation.NonNull;
 import com.matter.tv.app.api.SupportedCluster;
-import com.matter.tv.server.handlers.ApplicationLauncherManagerImpl;
 import com.matter.tv.server.handlers.ContentAppEndpointManagerImpl;
 import com.matter.tv.server.model.ContentApp;
 import com.matter.tv.server.receivers.ContentAppDiscoveryService;
diff --git a/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp b/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
index 97515f1efecd29..d4ce4d8b32b324 100644
--- a/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
+++ b/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
@@ -1,6 +1,6 @@
 /*
  *
- *    Copyright (c) 2021 Project CHIP Authors
+ *    Copyright (c) 2024 Project CHIP Authors
  *    All rights reserved.
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Application.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Application.java
index 86da098c292235..64d9996eda0b1b 100644
--- a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Application.java
+++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Application.java
@@ -1,5 +1,5 @@
 /*
- *   Copyright (c) 2021 Project CHIP Authors
+ *   Copyright (c) 2024 Project CHIP Authors
  *   All rights reserved.
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");

From cb06c684fe9e6ebb0b414de75a4a8de7cf0a7e1a Mon Sep 17 00:00:00 2001
From: "Restyled.io" <commits@restyled.io>
Date: Sat, 29 Jun 2024 00:14:50 +0000
Subject: [PATCH 03/22] Restyled by whitespace

---
 .../ApplicationLauncherManager.cpp                   | 10 +++++-----
 .../tv/server/tvapp/ApplicationLauncherManager.java  | 12 ++++++------
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp b/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
index d4ce4d8b32b324..1e231ecafa81fe 100644
--- a/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
+++ b/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
@@ -116,7 +116,7 @@ void ApplicationLauncherManager::HandleLaunchApp(CommandResponseHelper<LauncherR
 
     env->ExceptionClear();
 
-    {   
+    {
         // UtfString accepts const char * data
         chip::UtfString jByteData(env, reinterpret_cast<const char*>(data.data()));
 
@@ -126,7 +126,7 @@ void ApplicationLauncherManager::HandleLaunchApp(CommandResponseHelper<LauncherR
         jobject appObject = env->NewObject(mApplicationClass, mCreateApplicationMethod, static_cast<jint>(application.catalogVendorID), jappId.jniValue());
         VerifyOrReturn(appObject != nullptr, ChipLogError(Zcl, "Failed to create Application object"));
 
-        jobject resp = env->CallObjectMethod(mApplicationLauncherManagerObject.ObjectRef(), mLaunchAppMethod, appObject, 
+        jobject resp = env->CallObjectMethod(mApplicationLauncherManagerObject.ObjectRef(), mLaunchAppMethod, appObject,
                                              jByteData.jniValue());
         if (env->ExceptionCheck())
         {
@@ -177,7 +177,7 @@ void ApplicationLauncherManager::HandleStopApp(CommandResponseHelper<LauncherRes
 
     env->ExceptionClear();
 
-    {   
+    {
         chip::UtfString jappId(env, application.applicationID);
 
         // Create an instance of Application
@@ -234,7 +234,7 @@ void ApplicationLauncherManager::HandleHideApp(CommandResponseHelper<LauncherRes
 
     env->ExceptionClear();
 
-    {   
+    {
         chip::UtfString jappId(env, application.applicationID);
 
         // Create an instance of Application
@@ -334,4 +334,4 @@ void ApplicationLauncherManager::InitializeWithObjects(jobject managerObject)
         ChipLogError(Zcl, "Failed to find constructor of Application Java class");
         env->ExceptionClear();
     }
-}
\ No newline at end of file
+}
diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/ApplicationLauncherManager.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/ApplicationLauncherManager.java
index 1cc51e9b09e17d..7f80eb7a6c3421 100644
--- a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/ApplicationLauncherManager.java
+++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/ApplicationLauncherManager.java
@@ -4,23 +4,23 @@ public interface ApplicationLauncherManager {
 
   /**
    * Return a list of available catalogs
-   * 
+   *
    * @return list of int
    */
   int[] getCatalogList();
 
   /**
    * Launch an app
-   * 
-   * @param app that you want to launch 
+   *
+   * @param app that you want to launch
    * @param data to send addditional data if needed
-   * @return launcher response with status 
+   * @return launcher response with status
    */
   LauncherResponse launchApp(Application app, String data);
 
   /**
    * Stop an app
-   * 
+   *
    * @param app that you want to stop
    * @return launcher response with status
    */
@@ -28,7 +28,7 @@ public interface ApplicationLauncherManager {
 
   /**
    * hide an app
-   * 
+   *
    * @param app that you want to hide
    * @return launcher response with status
    */

From 826379c813cf73e832f5acb43151f2e03c781809 Mon Sep 17 00:00:00 2001
From: "Restyled.io" <commits@restyled.io>
Date: Sat, 29 Jun 2024 00:19:44 +0000
Subject: [PATCH 04/22] Restyled by google-java-format

---
 .../contentapp/CommandResponseHolder.java     |   3 -
 .../com/matter/tv/server/MainActivity.java    |   1 -
 .../ApplicationLauncherManagerImpl.java       |  75 ++++---
 .../tv/server/service/AppPlatformService.java |   1 -
 .../tv/server/utils/EndpointsDataStore.java   |   2 +-
 .../tv/server/utils/InstallationObserver.java | 198 +++++++++---------
 .../matter/tv/server/tvapp/Application.java   |  14 +-
 .../src/com/matter/tv/server/tvapp/TvApp.java |   3 +-
 8 files changed, 149 insertions(+), 148 deletions(-)

diff --git a/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/CommandResponseHolder.java b/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/CommandResponseHolder.java
index 68c7fe04c2d352..61ee303b408587 100644
--- a/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/CommandResponseHolder.java
+++ b/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/CommandResponseHolder.java
@@ -1,8 +1,5 @@
 package com.example.contentapp;
 
-import android.content.ContentResolver;
-import android.content.Context;
-import android.provider.Settings;
 import android.util.Log;
 import com.matter.tv.app.api.Clusters;
 import java.util.HashMap;
diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java
index 64937200733511..df612cf78fea94 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java
@@ -11,7 +11,6 @@
 import com.matter.tv.server.fragments.ContentAppFragment;
 import com.matter.tv.server.fragments.QrCodeFragment;
 import com.matter.tv.server.fragments.TerminalFragment;
-
 import java.util.LinkedHashMap;
 
 public class MainActivity extends AppCompatActivity {
diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
index ebfbd0e5eb0121..3e4366ee6d8428 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
@@ -3,16 +3,13 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.util.Log;
-
 import androidx.lifecycle.LiveData;
 import androidx.lifecycle.Observer;
-
 import com.matter.tv.server.tvapp.Application;
 import com.matter.tv.server.tvapp.ApplicationLauncherManager;
 import com.matter.tv.server.tvapp.LauncherResponse;
 import com.matter.tv.server.utils.EndpointsDataStore;
 import com.matter.tv.server.utils.InstallationObserver;
-
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
@@ -25,10 +22,9 @@ public class ApplicationLauncherManagerImpl implements ApplicationLauncherManage
   private PackageManager packageManager;
   private EndpointsDataStore endpointsDataStore;
 
-  /**
-   * Hash Map of packageName & Install Status
-   */
-  private Map<String, InstallationObserver.InstallStatus> lastReceivedInstallationStatus = new HashMap<>();
+  /** Hash Map of packageName & Install Status */
+  private Map<String, InstallationObserver.InstallStatus> lastReceivedInstallationStatus =
+      new HashMap<>();
 
   private LiveData<InstallationObserver.InstallState> installStateLiveData;
 
@@ -38,24 +34,24 @@ public ApplicationLauncherManagerImpl(Context context) {
     registerSelf(context);
   }
 
-  private final Observer<InstallationObserver.InstallState> installStateObserver = state -> {
-    lastReceivedInstallationStatus.put(state.getAppPackageName(), state.getStatus());
-    switch (state.getStatus()) {
-
-      case IN_PROGRESS:
-        // Installation is in progress
-        Log.d(TAG, "Installation of " + state.getAppPackageName() + " in progress");
-        break;
-      case SUCCEEDED:
-        // Installation succeeded
-        Log.d(TAG, "Installation of " + state.getAppPackageName() + " succeeded");
-        break;
-      case FAILED:
-        // Installation failed
-        Log.d(TAG, "Installation of " + state.getAppPackageName() + " failed");
-        break;
-    }
-  };
+  private final Observer<InstallationObserver.InstallState> installStateObserver =
+      state -> {
+        lastReceivedInstallationStatus.put(state.getAppPackageName(), state.getStatus());
+        switch (state.getStatus()) {
+          case IN_PROGRESS:
+            // Installation is in progress
+            Log.d(TAG, "Installation of " + state.getAppPackageName() + " in progress");
+            break;
+          case SUCCEEDED:
+            // Installation succeeded
+            Log.d(TAG, "Installation of " + state.getAppPackageName() + " succeeded");
+            break;
+          case FAILED:
+            // Installation failed
+            Log.d(TAG, "Installation of " + state.getAppPackageName() + " failed");
+            break;
+        }
+      };
 
   private void stopObservingInstallations() {
     if (installStateLiveData != null) {
@@ -90,19 +86,30 @@ public int[] getCatalogList() {
 
   @Override
   public LauncherResponse launchApp(Application app, String data) {
-    Log.i(TAG, "Launch app id:" + app.applicationId + " cid:" + app.catalogVendorId + " data:" + data);
+    Log.i(
+        TAG,
+        "Launch app id:" + app.applicationId + " cid:" + app.catalogVendorId + " data:" + data);
 
     int status = 0;
     String responseData = "";
 
-    boolean matterAppEnabledIsInstalled = endpointsDataStore.getAllPersistedContentApps().containsKey(app.applicationId);
-    boolean appIsInstalled = InstallationObserver.getInstalledPackages(packageManager).contains(app.applicationId);
-    boolean isAppInstalling = Objects.equals(lastReceivedInstallationStatus.get(app.applicationId), InstallationObserver.InstallStatus.IN_PROGRESS);
-    boolean appInstallFailed = Objects.equals(lastReceivedInstallationStatus.get(app.applicationId), InstallationObserver.InstallStatus.FAILED);
-
+    boolean matterAppEnabledIsInstalled =
+        endpointsDataStore.getAllPersistedContentApps().containsKey(app.applicationId);
+    boolean appIsInstalled =
+        InstallationObserver.getInstalledPackages(packageManager).contains(app.applicationId);
+    boolean isAppInstalling =
+        Objects.equals(
+            lastReceivedInstallationStatus.get(app.applicationId),
+            InstallationObserver.InstallStatus.IN_PROGRESS);
+    boolean appInstallFailed =
+        Objects.equals(
+            lastReceivedInstallationStatus.get(app.applicationId),
+            InstallationObserver.InstallStatus.FAILED);
 
     if (!matterAppEnabledIsInstalled && appIsInstalled) {
-      Log.i(TAG, "Matter enabled app is not installed, but app is installed. Launching app's install page");
+      Log.i(
+          TAG,
+          "Matter enabled app is not installed, but app is installed. Launching app's install page");
       status = LauncherResponse.STATUS_PENDING;
       responseData = "App is installed, try updating";
 
@@ -111,7 +118,9 @@ public LauncherResponse launchApp(Application app, String data) {
       //
 
     } else if (!matterAppEnabledIsInstalled && !appIsInstalled) {
-      Log.i(TAG, "Matter enabled app is not installed and app is not installed. Launching app's install page");
+      Log.i(
+          TAG,
+          "Matter enabled app is not installed and app is not installed. Launching app's install page");
       if (isAppInstalling) {
         Log.i(TAG, "App is installing");
         status = LauncherResponse.STATUS_INSTALLING;
diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java
index 0a8dd07ffae2d5..df360375068e70 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java
@@ -195,7 +195,6 @@ public void addContentApp(ContentApp app) {
     }
   }
 
-
   private Collection<ContentAppSupportedCluster> mapSupportedClusters(
       Collection<SupportedCluster> supportedClusters) {
     return supportedClusters
diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java
index 7c7b39034f55a6..7b3822bb1b59a4 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/EndpointsDataStore.java
@@ -60,7 +60,7 @@ public Map<String, ContentApp> getAllPersistedContentApps() {
   }
 
   public void persistContentAppEndpoint(ContentApp app) {
-    Log.i( EndpointsDataStore.class.toString(), "Persist Content App Endpoint " + app.getAppName());
+    Log.i(EndpointsDataStore.class.toString(), "Persist Content App Endpoint " + app.getAppName());
     persistedContentApps.put(app.getAppName(), app);
     discoveredEndpoints.edit().putString(app.getAppName(), serializeContentApp(app)).apply();
   }
diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/InstallationObserver.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/InstallationObserver.java
index 4c355278b5614e..c47359272a1359 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/InstallationObserver.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/InstallationObserver.java
@@ -7,7 +7,6 @@
 import android.util.Log;
 import androidx.lifecycle.LiveData;
 import androidx.lifecycle.MutableLiveData;
-
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -16,118 +15,123 @@
 import java.util.Set;
 
 public class InstallationObserver {
-    public enum InstallStatus {
-        IN_PROGRESS, SUCCEEDED, FAILED
+  public enum InstallStatus {
+    IN_PROGRESS,
+    SUCCEEDED,
+    FAILED
+  }
+
+  public static class InstallState {
+    private final String appPackageName;
+    private final InstallStatus status;
+
+    public InstallState(String appPackageName, InstallStatus status) {
+      this.appPackageName = appPackageName;
+      this.status = status;
     }
 
-    public static class InstallState {
-        private final String appPackageName;
-        private final InstallStatus status;
-
-        public InstallState(String appPackageName, InstallStatus status) {
-            this.appPackageName = appPackageName;
-            this.status = status;
-        }
-
-        public String getAppPackageName() {
-            return appPackageName;
-        }
-
-        public InstallStatus getStatus() {
-            return status;
-        }
-
-        public String getPackageShortName() {
-            return appPackageName.substring(appPackageName.lastIndexOf(".") + 1);
-        }
-
-        public String getPackageTitle() {
-            String shortName = getPackageShortName();
-            return shortName.substring(0, 1).toUpperCase(Locale.getDefault()) + shortName.substring(1);
-        }
+    public String getAppPackageName() {
+      return appPackageName;
     }
 
-    private static InstallState stateFromId(PackageInstaller installer, int sessionId) {
-        PackageInstaller.SessionInfo info = installer.getSessionInfo(sessionId);
-        if (info == null || info.getAppPackageName() == null) {
-            return null;
-        }
-        return new InstallState(info.getAppPackageName(), InstallStatus.IN_PROGRESS);
+    public InstallStatus getStatus() {
+      return status;
     }
 
-    public static Set<String> getInstalledPackages(PackageManager packageManager) {
-        List<PackageInfo> packageInfoList = packageManager.getInstalledPackages(0);
-        Set<String> setOfInstalledApps = new HashSet<>();
-        for (PackageInfo info: packageInfoList) {
-            setOfInstalledApps.add(info.packageName);
-        }
-        return setOfInstalledApps;
+    public String getPackageShortName() {
+      return appPackageName.substring(appPackageName.lastIndexOf(".") + 1);
     }
 
-    public static LiveData<InstallState> installationStates(Context context) {
-        MutableLiveData<InstallState> liveData = new MutableLiveData<>();
-        PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
-        Map<Integer, InstallState> inProgressSessions = new HashMap<>();
-
-        PackageInstaller.SessionCallback callback = new PackageInstaller.SessionCallback() {
-            @Override
-            public void onCreated(int sessionId) {
-                Log.d(TAG, "onCreated ");
-                InstallState state = stateFromId(packageInstaller, sessionId);
-                if (state != null) {
-                    inProgressSessions.put(sessionId, state);
-                    liveData.postValue(state);
-                }
-            }
+    public String getPackageTitle() {
+      String shortName = getPackageShortName();
+      return shortName.substring(0, 1).toUpperCase(Locale.getDefault()) + shortName.substring(1);
+    }
+  }
 
-            @Override
-            public void onBadgingChanged(int sessionId) {
+  private static InstallState stateFromId(PackageInstaller installer, int sessionId) {
+    PackageInstaller.SessionInfo info = installer.getSessionInfo(sessionId);
+    if (info == null || info.getAppPackageName() == null) {
+      return null;
+    }
+    return new InstallState(info.getAppPackageName(), InstallStatus.IN_PROGRESS);
+  }
+
+  public static Set<String> getInstalledPackages(PackageManager packageManager) {
+    List<PackageInfo> packageInfoList = packageManager.getInstalledPackages(0);
+    Set<String> setOfInstalledApps = new HashSet<>();
+    for (PackageInfo info : packageInfoList) {
+      setOfInstalledApps.add(info.packageName);
+    }
+    return setOfInstalledApps;
+  }
+
+  public static LiveData<InstallState> installationStates(Context context) {
+    MutableLiveData<InstallState> liveData = new MutableLiveData<>();
+    PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
+    Map<Integer, InstallState> inProgressSessions = new HashMap<>();
+
+    PackageInstaller.SessionCallback callback =
+        new PackageInstaller.SessionCallback() {
+          @Override
+          public void onCreated(int sessionId) {
+            Log.d(TAG, "onCreated ");
+            InstallState state = stateFromId(packageInstaller, sessionId);
+            if (state != null) {
+              inProgressSessions.put(sessionId, state);
+              liveData.postValue(state);
             }
-
-            @Override
-            public void onActiveChanged(int sessionId, boolean active) {
-                Log.d(TAG, "onActiveChanged");
-                InstallState state = stateFromId(packageInstaller, sessionId);
-                if (state != null) {
-                    inProgressSessions.put(sessionId, state);
-                    liveData.postValue(state);
-                }
+          }
+
+          @Override
+          public void onBadgingChanged(int sessionId) {}
+
+          @Override
+          public void onActiveChanged(int sessionId, boolean active) {
+            Log.d(TAG, "onActiveChanged");
+            InstallState state = stateFromId(packageInstaller, sessionId);
+            if (state != null) {
+              inProgressSessions.put(sessionId, state);
+              liveData.postValue(state);
             }
-
-            @Override
-            public void onProgressChanged(int sessionId, float progress) {
-                Log.d(TAG, "onProgressChanged:" + progress);
-                InstallState state = stateFromId(packageInstaller, sessionId);
-                if (state != null) {
-                    inProgressSessions.put(sessionId, state);
-                    liveData.postValue(state);
-                }
+          }
+
+          @Override
+          public void onProgressChanged(int sessionId, float progress) {
+            Log.d(TAG, "onProgressChanged:" + progress);
+            InstallState state = stateFromId(packageInstaller, sessionId);
+            if (state != null) {
+              inProgressSessions.put(sessionId, state);
+              liveData.postValue(state);
             }
-
-            @Override
-            public void onFinished(int sessionId, boolean success) {
-                Log.d(TAG, "onFinished " + sessionId + " " + success);
-                InstallState current = inProgressSessions.get(sessionId);
-                if (current != null) {
-                    InstallState newState = new InstallState(current.getAppPackageName(), success ? InstallStatus.SUCCEEDED : InstallStatus.FAILED);
-                    liveData.postValue(newState);
-                    inProgressSessions.remove(sessionId);
-                }
+          }
+
+          @Override
+          public void onFinished(int sessionId, boolean success) {
+            Log.d(TAG, "onFinished " + sessionId + " " + success);
+            InstallState current = inProgressSessions.get(sessionId);
+            if (current != null) {
+              InstallState newState =
+                  new InstallState(
+                      current.getAppPackageName(),
+                      success ? InstallStatus.SUCCEEDED : InstallStatus.FAILED);
+              liveData.postValue(newState);
+              inProgressSessions.remove(sessionId);
             }
+          }
         };
 
-        packageInstaller.registerSessionCallback(callback);
-
-        for (PackageInstaller.SessionInfo info : packageInstaller.getMySessions()) {
-            if (info.isActive() && info.getAppPackageName() != null) {
-                InstallState state = new InstallState(info.getAppPackageName(), InstallStatus.IN_PROGRESS);
-                inProgressSessions.put(info.getSessionId(), state);
-                liveData.postValue(state);
-            }
-        }
+    packageInstaller.registerSessionCallback(callback);
 
-        return liveData;
+    for (PackageInstaller.SessionInfo info : packageInstaller.getMySessions()) {
+      if (info.isActive() && info.getAppPackageName() != null) {
+        InstallState state = new InstallState(info.getAppPackageName(), InstallStatus.IN_PROGRESS);
+        inProgressSessions.put(info.getSessionId(), state);
+        liveData.postValue(state);
+      }
     }
 
-    private static final String TAG = "InstallationObserver";
+    return liveData;
+  }
+
+  private static final String TAG = "InstallationObserver";
 }
diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Application.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Application.java
index 64d9996eda0b1b..bac89b09420213 100644
--- a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Application.java
+++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/Application.java
@@ -22,25 +22,17 @@ public class Application {
   public int catalogVendorId;
   public String applicationId;
 
-  public Application(
-      int catalogVendorId,
-      String applicationId) {
+  public Application(int catalogVendorId, String applicationId) {
     this.catalogVendorId = catalogVendorId;
     this.applicationId = applicationId;
   }
 
-  public Application createApplication(int catalogVendorId,
-                                       String applicationId) {
+  public Application createApplication(int catalogVendorId, String applicationId) {
     return new Application(catalogVendorId, applicationId);
   }
 
   @Override
   public String toString() {
-    return "Application{"
-        + "catalogVendorId="
-        + catalogVendorId
-        + ", applicationId='"
-        + '\''
-        + '}';
+    return "Application{" + "catalogVendorId=" + catalogVendorId + ", applicationId='" + '\'' + '}';
   }
 }
diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/TvApp.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/TvApp.java
index abc0b55007c7e1..8cac42ff582e3e 100644
--- a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/TvApp.java
+++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/TvApp.java
@@ -47,7 +47,8 @@ private void postClusterInit(long clusterId, int endpoint) {
 
   public native void setKeypadInputManager(int endpoint, KeypadInputManager manager);
 
-  public native void setApplicationLauncherManager(int endpoint, ApplicationLauncherManager manager);
+  public native void setApplicationLauncherManager(
+      int endpoint, ApplicationLauncherManager manager);
 
   public native void setWakeOnLanManager(int endpoint, WakeOnLanManager manager);
 

From 77618b421049ff05374d955f4316c247f2004c63 Mon Sep 17 00:00:00 2001
From: "Restyled.io" <commits@restyled.io>
Date: Sat, 29 Jun 2024 00:19:45 +0000
Subject: [PATCH 05/22] Restyled by clang-format

---
 examples/tv-app/android/java/AppImpl.h        |  2 +-
 examples/tv-app/android/java/TVApp-JNI.cpp    |  2 +-
 .../ApplicationLauncherManager.cpp            | 34 ++++++++++++-------
 .../ApplicationLauncherManager.h              | 12 +++----
 4 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/examples/tv-app/android/java/AppImpl.h b/examples/tv-app/android/java/AppImpl.h
index 1593f263f30244..5fac7b96b2abfe 100644
--- a/examples/tv-app/android/java/AppImpl.h
+++ b/examples/tv-app/android/java/AppImpl.h
@@ -39,12 +39,12 @@
 #include "../include/content-launcher/AppContentLauncherManager.h"
 #include "../include/media-playback/AppMediaPlaybackManager.h"
 #include "../include/target-navigator/TargetNavigatorManager.h"
-#include "application-launcher/ApplicationLauncherManager.h"
 #include "ChannelManager.h"
 #include "CommissionerMain.h"
 #include "ContentAppAttributeDelegate.h"
 #include "ContentAppCommandDelegate.h"
 #include "KeypadInputManager.h"
+#include "application-launcher/ApplicationLauncherManager.h"
 #include <app/clusters/account-login-server/account-login-delegate.h>
 #include <app/clusters/application-basic-server/application-basic-delegate.h>
 #include <app/clusters/application-launcher-server/application-launcher-delegate.h>
diff --git a/examples/tv-app/android/java/TVApp-JNI.cpp b/examples/tv-app/android/java/TVApp-JNI.cpp
index f2829dda6b1004..0fe1bdef939ca8 100644
--- a/examples/tv-app/android/java/TVApp-JNI.cpp
+++ b/examples/tv-app/android/java/TVApp-JNI.cpp
@@ -17,7 +17,6 @@
  */
 
 #include "TvApp-JNI.h"
-#include "application-launcher/ApplicationLauncherManager.h"
 #include "ChannelManager.h"
 #include "CommissionerMain.h"
 #include "ContentLauncherManager.h"
@@ -32,6 +31,7 @@
 #include "MyUserPrompter-JNI.h"
 #include "OnOffManager.h"
 #include "WakeOnLanManager.h"
+#include "application-launcher/ApplicationLauncherManager.h"
 #include "credentials/DeviceAttestationCredsProvider.h"
 #include <app/app-platform/ContentAppPlatform.h>
 #include <app/server/Dnssd.h>
diff --git a/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp b/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
index 1e231ecafa81fe..5ffd2ec17791af 100644
--- a/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
+++ b/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
@@ -36,7 +36,8 @@ using namespace chip::Uint8;
 void emberAfApplicationLauncherClusterInitCallback(chip::EndpointId endpoint)
 {
     ChipLogProgress(Zcl, "TV Android App: ApplicationLauncher::PostClusterInit");
-    if (endpoint > kLocalVideoPlayerEndpointId) {
+    if (endpoint > kLocalVideoPlayerEndpointId)
+    {
         ChipLogProgress(Zcl, "TV Android App: ignore setting the delegate for endpoints larger than 1");
         return;
     }
@@ -45,7 +46,8 @@ void emberAfApplicationLauncherClusterInitCallback(chip::EndpointId endpoint)
 
 void ApplicationLauncherManager::NewManager(jint endpoint, jobject manager)
 {
-    if (endpoint > kLocalVideoPlayerEndpointId) {
+    if (endpoint > kLocalVideoPlayerEndpointId)
+    {
         ChipLogProgress(Zcl, "TV Android App: ignore setting the delegate for endpoints larger than 1");
         return;
     }
@@ -118,16 +120,17 @@ void ApplicationLauncherManager::HandleLaunchApp(CommandResponseHelper<LauncherR
 
     {
         // UtfString accepts const char * data
-        chip::UtfString jByteData(env, reinterpret_cast<const char*>(data.data()));
+        chip::UtfString jByteData(env, reinterpret_cast<const char *>(data.data()));
 
         chip::UtfString jappId(env, application.applicationID);
 
         // Create an instance of Application
-        jobject appObject = env->NewObject(mApplicationClass, mCreateApplicationMethod, static_cast<jint>(application.catalogVendorID), jappId.jniValue());
+        jobject appObject = env->NewObject(mApplicationClass, mCreateApplicationMethod,
+                                           static_cast<jint>(application.catalogVendorID), jappId.jniValue());
         VerifyOrReturn(appObject != nullptr, ChipLogError(Zcl, "Failed to create Application object"));
 
-        jobject resp = env->CallObjectMethod(mApplicationLauncherManagerObject.ObjectRef(), mLaunchAppMethod, appObject,
-                                             jByteData.jniValue());
+        jobject resp =
+            env->CallObjectMethod(mApplicationLauncherManagerObject.ObjectRef(), mLaunchAppMethod, appObject, jByteData.jniValue());
         if (env->ExceptionCheck())
         {
             ChipLogError(Zcl, "Java exception in ApplicationLauncherManager::LaunchApp");
@@ -181,7 +184,8 @@ void ApplicationLauncherManager::HandleStopApp(CommandResponseHelper<LauncherRes
         chip::UtfString jappId(env, application.applicationID);
 
         // Create an instance of Application
-        jobject appObject = env->NewObject(mApplicationClass, mCreateApplicationMethod, static_cast<jint>(application.catalogVendorID), jappId.jniValue());
+        jobject appObject = env->NewObject(mApplicationClass, mCreateApplicationMethod,
+                                           static_cast<jint>(application.catalogVendorID), jappId.jniValue());
         VerifyOrReturn(appObject != nullptr, ChipLogError(Zcl, "Failed to create Application object"));
 
         jobject resp = env->CallObjectMethod(mApplicationLauncherManagerObject.ObjectRef(), mStopAppMethod, appObject);
@@ -238,7 +242,8 @@ void ApplicationLauncherManager::HandleHideApp(CommandResponseHelper<LauncherRes
         chip::UtfString jappId(env, application.applicationID);
 
         // Create an instance of Application
-        jobject appObject = env->NewObject(mApplicationClass, mCreateApplicationMethod, static_cast<jint>(application.catalogVendorID), jappId.jniValue());
+        jobject appObject = env->NewObject(mApplicationClass, mCreateApplicationMethod,
+                                           static_cast<jint>(application.catalogVendorID), jappId.jniValue());
         VerifyOrReturn(appObject != nullptr, ChipLogError(Zcl, "Failed to create Application object"));
 
         jobject resp = env->CallObjectMethod(mApplicationLauncherManagerObject.ObjectRef(), mHideAppMethod, appObject);
@@ -293,7 +298,8 @@ void ApplicationLauncherManager::InitializeWithObjects(jobject managerObject)
         env->ExceptionClear();
     }
 
-    mLaunchAppMethod = env->GetMethodID(applicationLauncherClass, "launchApp", "(Lcom/matter/tv/server/tvapp/"
+    mLaunchAppMethod = env->GetMethodID(applicationLauncherClass, "launchApp",
+                                        "(Lcom/matter/tv/server/tvapp/"
                                         "Application;Ljava/lang/String;)Lcom/matter/tv/server/tvapp/LauncherResponse;");
     if (mLaunchAppMethod == nullptr)
     {
@@ -301,16 +307,18 @@ void ApplicationLauncherManager::InitializeWithObjects(jobject managerObject)
         env->ExceptionClear();
     }
 
-    mStopAppMethod = env->GetMethodID(applicationLauncherClass, "stopApp", "(Lcom/matter/tv/server/tvapp/"
-                                        "Application;)Lcom/matter/tv/server/tvapp/LauncherResponse;");
+    mStopAppMethod = env->GetMethodID(applicationLauncherClass, "stopApp",
+                                      "(Lcom/matter/tv/server/tvapp/"
+                                      "Application;)Lcom/matter/tv/server/tvapp/LauncherResponse;");
     if (mStopAppMethod == nullptr)
     {
         ChipLogError(Zcl, "Failed to access ApplicationLauncherManager 'stopApp' method");
         env->ExceptionClear();
     }
 
-    mHideAppMethod = env->GetMethodID(applicationLauncherClass, "hideApp", "(Lcom/matter/tv/server/tvapp/"
-                                        "Application;)Lcom/matter/tv/server/tvapp/LauncherResponse;");
+    mHideAppMethod = env->GetMethodID(applicationLauncherClass, "hideApp",
+                                      "(Lcom/matter/tv/server/tvapp/"
+                                      "Application;)Lcom/matter/tv/server/tvapp/LauncherResponse;");
     if (mHideAppMethod == nullptr)
     {
         ChipLogError(Zcl, "Failed to access ApplicationLauncherManager 'hideApp' method");
diff --git a/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.h b/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.h
index 2b3ed006f72800..fd0f40d84b5b60 100644
--- a/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.h
+++ b/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.h
@@ -46,10 +46,10 @@ class ApplicationLauncherManager : public ApplicationLauncherDelegate
     void HandleHideApp(CommandResponseHelper<LauncherResponseType> & helper, const ApplicationType & application) override;
 
     chip::JniGlobalReference mApplicationLauncherManagerObject;
-    jmethodID mGetCatalogListMethod               = nullptr;
-    jmethodID mLaunchAppMethod                    = nullptr;
-    jmethodID mStopAppMethod                      = nullptr;
-    jmethodID mHideAppMethod                      = nullptr;
-    jmethodID mCreateApplicationMethod            = nullptr;
-    jclass mApplicationClass                      = nullptr;
+    jmethodID mGetCatalogListMethod    = nullptr;
+    jmethodID mLaunchAppMethod         = nullptr;
+    jmethodID mStopAppMethod           = nullptr;
+    jmethodID mHideAppMethod           = nullptr;
+    jmethodID mCreateApplicationMethod = nullptr;
+    jclass mApplicationClass           = nullptr;
 };

From 1223002a91e5045b478106bc4a1cd69bfabc852c Mon Sep 17 00:00:00 2001
From: "Restyled.io" <commits@restyled.io>
Date: Sat, 29 Jun 2024 00:19:45 +0000
Subject: [PATCH 06/22] Restyled by gn

---
 examples/tv-app/android/BUILD.gn | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/examples/tv-app/android/BUILD.gn b/examples/tv-app/android/BUILD.gn
index dea0e8dc89bae7..f08f16f363e516 100644
--- a/examples/tv-app/android/BUILD.gn
+++ b/examples/tv-app/android/BUILD.gn
@@ -39,8 +39,6 @@ shared_library("jni") {
     "include/media-playback/AppMediaPlaybackManager.h",
     "include/target-navigator/TargetNavigatorManager.cpp",
     "include/target-navigator/TargetNavigatorManager.h",
-    "java/application-launcher/ApplicationLauncherManager.cpp",
-    "java/application-launcher/ApplicationLauncherManager.h",
     "java/AppImpl.cpp",
     "java/AppImpl.h",
     "java/AppPlatform-JNI.cpp",
@@ -80,6 +78,8 @@ shared_library("jni") {
     "java/TVApp-JNI.cpp",
     "java/WakeOnLanManager.cpp",
     "java/WakeOnLanManager.h",
+    "java/application-launcher/ApplicationLauncherManager.cpp",
+    "java/application-launcher/ApplicationLauncherManager.h",
   ]
 
   deps = [
@@ -113,10 +113,10 @@ android_library("java") {
   ]
 
   sources = [
-    "java/src/com/matter/tv/server/tvapp/Application.java",
-    "java/src/com/matter/tv/server/tvapp/ApplicationLauncherManager.java",
     "java/src/com/matter/tv/server/tvapp/AppPlatform.java",
     "java/src/com/matter/tv/server/tvapp/AppPlatformShellCommands.java",
+    "java/src/com/matter/tv/server/tvapp/Application.java",
+    "java/src/com/matter/tv/server/tvapp/ApplicationLauncherManager.java",
     "java/src/com/matter/tv/server/tvapp/ChannelInfo.java",
     "java/src/com/matter/tv/server/tvapp/ChannelLineupInfo.java",
     "java/src/com/matter/tv/server/tvapp/ChannelManager.java",

From 340455e13ec05583ee10ae41ace2de1b55a3da72 Mon Sep 17 00:00:00 2001
From: Lazar Kovacic <lkovacic@amazon.com>
Date: Sat, 29 Jun 2024 02:28:05 +0200
Subject: [PATCH 07/22] Revert the unecessary changes

---
 .../App/.idea/deploymentTargetDropDown.xml     | 10 ----------
 examples/tv-app/android/App/.idea/gradle.xml   |  3 ++-
 .../android/App/platform-app/build.gradle      | 18 +++++++++---------
 3 files changed, 11 insertions(+), 20 deletions(-)
 delete mode 100644 examples/tv-app/android/App/.idea/deploymentTargetDropDown.xml

diff --git a/examples/tv-app/android/App/.idea/deploymentTargetDropDown.xml b/examples/tv-app/android/App/.idea/deploymentTargetDropDown.xml
deleted file mode 100644
index 5ca3f336b64004..00000000000000
--- a/examples/tv-app/android/App/.idea/deploymentTargetDropDown.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="deploymentTargetDropDown">
-    <value>
-      <entry key="platform-app">
-        <State />
-      </entry>
-    </value>
-  </component>
-</project>
\ No newline at end of file
diff --git a/examples/tv-app/android/App/.idea/gradle.xml b/examples/tv-app/android/App/.idea/gradle.xml
index 6d1563baf79f38..c55cb656581f0b 100644
--- a/examples/tv-app/android/App/.idea/gradle.xml
+++ b/examples/tv-app/android/App/.idea/gradle.xml
@@ -4,6 +4,8 @@
   <component name="GradleSettings">
     <option name="linkedExternalProjectsSettings">
       <GradleProjectSettings>
+        <option name="testRunner" value="GRADLE" />
+        <option name="distributionType" value="DEFAULT_WRAPPED" />
         <option name="externalProjectPath" value="$PROJECT_DIR$" />
         <option name="modules">
           <set>
@@ -12,7 +14,6 @@
             <option value="$PROJECT_DIR$/platform-app" />
           </set>
         </option>
-        <option name="resolveExternalAnnotations" value="false" />
       </GradleProjectSettings>
     </option>
   </component>
diff --git a/examples/tv-app/android/App/platform-app/build.gradle b/examples/tv-app/android/App/platform-app/build.gradle
index 92b31f1f54be6a..5b4203e9c1509c 100644
--- a/examples/tv-app/android/App/platform-app/build.gradle
+++ b/examples/tv-app/android/App/platform-app/build.gradle
@@ -47,14 +47,14 @@ android {
             aidl.srcDirs = ['../common-api/src/main/aidl']
 
             // uncomment this code to debug
-            // java.srcDirs = [
-            //         'src/main/java',
-            //         '../common-api/src/main/java',
-            //         '../../third_party/connectedhomeip/src/setup_payload/java/src',
-            //         '../../third_party/connectedhomeip/src/platform/android/java',
-            //         '../../third_party/connectedhomeip/src/app/server/java/src/',
-            //         '../../java/src',
-            // ]
+//            java.srcDirs = [
+//                    'src/main/java',
+//                    '../common-api/src/main/java',
+//                    '../../third_party/connectedhomeip/src/setup_payload/java/src',
+//                    '../../third_party/connectedhomeip/src/platform/android/java',
+//                    '../../third_party/connectedhomeip/src/app/server/java/src/',
+//                    '../../java/src',
+//            ]
         }
     }
     buildFeatures {
@@ -72,4 +72,4 @@ dependencies {
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
     implementation 'com.google.zxing:core:3.3.0'
     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
-}
+}
\ No newline at end of file

From 8176e036961e92399ee7920306d5cc1d523f13c1 Mon Sep 17 00:00:00 2001
From: Lazar Kovacic <lkovacic@amazon.com>
Date: Sat, 29 Jun 2024 02:29:14 +0200
Subject: [PATCH 08/22] Remove uncessary files

---
 .../android/App/.idea/codeStyles/Project.xml  | 117 ------------------
 .../App/.idea/codeStyles/codeStyleConfig.xml  |   5 -
 2 files changed, 122 deletions(-)
 delete mode 100644 examples/tv-app/android/App/.idea/codeStyles/Project.xml
 delete mode 100644 examples/tv-app/android/App/.idea/codeStyles/codeStyleConfig.xml

diff --git a/examples/tv-app/android/App/.idea/codeStyles/Project.xml b/examples/tv-app/android/App/.idea/codeStyles/Project.xml
deleted file mode 100644
index 4bec4ea8ae0d9c..00000000000000
--- a/examples/tv-app/android/App/.idea/codeStyles/Project.xml
+++ /dev/null
@@ -1,117 +0,0 @@
-<component name="ProjectCodeStyleConfiguration">
-  <code_scheme name="Project" version="173">
-    <codeStyleSettings language="XML">
-      <option name="FORCE_REARRANGE_MODE" value="1" />
-      <indentOptions>
-        <option name="CONTINUATION_INDENT_SIZE" value="4" />
-      </indentOptions>
-      <arrangement>
-        <rules>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>xmlns:android</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>^$</XML_NAMESPACE>
-                </AND>
-              </match>
-            </rule>
-          </section>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>xmlns:.*</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>^$</XML_NAMESPACE>
-                </AND>
-              </match>
-              <order>BY_NAME</order>
-            </rule>
-          </section>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>.*:id</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
-                </AND>
-              </match>
-            </rule>
-          </section>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>.*:name</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
-                </AND>
-              </match>
-            </rule>
-          </section>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>name</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>^$</XML_NAMESPACE>
-                </AND>
-              </match>
-            </rule>
-          </section>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>style</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>^$</XML_NAMESPACE>
-                </AND>
-              </match>
-            </rule>
-          </section>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>.*</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>^$</XML_NAMESPACE>
-                </AND>
-              </match>
-              <order>BY_NAME</order>
-            </rule>
-          </section>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>.*</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
-                </AND>
-              </match>
-              <order>ANDROID_ATTRIBUTE_ORDER</order>
-            </rule>
-          </section>
-          <section>
-            <rule>
-              <match>
-                <AND>
-                  <NAME>.*</NAME>
-                  <XML_ATTRIBUTE />
-                  <XML_NAMESPACE>.*</XML_NAMESPACE>
-                </AND>
-              </match>
-              <order>BY_NAME</order>
-            </rule>
-          </section>
-        </rules>
-      </arrangement>
-    </codeStyleSettings>
-  </code_scheme>
-</component>
\ No newline at end of file
diff --git a/examples/tv-app/android/App/.idea/codeStyles/codeStyleConfig.xml b/examples/tv-app/android/App/.idea/codeStyles/codeStyleConfig.xml
deleted file mode 100644
index a55e7a179bde3e..00000000000000
--- a/examples/tv-app/android/App/.idea/codeStyles/codeStyleConfig.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<component name="ProjectCodeStyleConfiguration">
-  <state>
-    <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
-  </state>
-</component>
\ No newline at end of file

From c321111c79dedf43bde5855cad45d05cde6c00d1 Mon Sep 17 00:00:00 2001
From: Lazar Kovacic <lkovacic@amazon.com>
Date: Sat, 29 Jun 2024 02:30:24 +0200
Subject: [PATCH 09/22] Update comment

---
 .../main/java/com/matter/tv/server/service/MatterServant.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/service/MatterServant.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java
index 9b42d8ac464223..13ed2a372b82e4 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java
@@ -85,7 +85,7 @@ public void init(@NonNull Context context) {
     // then start ChipAppServer
     // then TvApp.postServerInit to init app platform
     //
-    // TODO: Move all of this logic to PlatformAppCommandDelegate
+    // TODO: Move all of the bellow KeypadInputManager...LevelManagerStub to PlatformAppCommandDelegate
     // There is no need for this complicated logic
     mTvApp =
         new TvApp(

From 1851ee2bf0352deda2c8c03aa5950eb17aeafc55 Mon Sep 17 00:00:00 2001
From: "Restyled.io" <commits@restyled.io>
Date: Sat, 29 Jun 2024 00:30:47 +0000
Subject: [PATCH 10/22] Restyled by google-java-format

---
 .../main/java/com/matter/tv/server/service/MatterServant.java  | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java
index 13ed2a372b82e4..683fb226c9e441 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java
@@ -85,7 +85,8 @@ public void init(@NonNull Context context) {
     // then start ChipAppServer
     // then TvApp.postServerInit to init app platform
     //
-    // TODO: Move all of the bellow KeypadInputManager...LevelManagerStub to PlatformAppCommandDelegate
+    // TODO: Move all of the bellow KeypadInputManager...LevelManagerStub to
+    // PlatformAppCommandDelegate
     // There is no need for this complicated logic
     mTvApp =
         new TvApp(

From 98424b74d2fbc6575249a997152ef96d110453e5 Mon Sep 17 00:00:00 2001
From: Lazar Kovacic <lkovacic@amazon.com>
Date: Mon, 1 Jul 2024 10:35:52 +0200
Subject: [PATCH 11/22] Fix get catalog list

---
 .../server/handlers/ApplicationLauncherManagerImpl.java   | 2 +-
 .../application-launcher/ApplicationLauncherManager.cpp   | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
index 3e4366ee6d8428..308cdebe66530e 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
@@ -81,7 +81,7 @@ private void registerSelf(Context context) {
   @Override
   public int[] getCatalogList() {
     Log.i(TAG, "Get Catalog List");
-    return new int[0];
+    return new int[]{65521, 8891, 3191};
   }
 
   @Override
diff --git a/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp b/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
index 5ffd2ec17791af..91ab271c5fe5d7 100644
--- a/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
+++ b/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
@@ -62,7 +62,6 @@ CHIP_ERROR ApplicationLauncherManager::HandleGetCatalogList(AttributeValueEncode
     chip::DeviceLayer::StackUnlock unlock;
     CHIP_ERROR err = CHIP_NO_ERROR;
     JNIEnv * env   = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
-    std::list<std::string> acceptedHeadersList;
     VerifyOrReturnError(env != nullptr, CHIP_JNI_ERROR_NO_ENV, ChipLogError(Zcl, "Could not get JNIEnv for current thread"));
     chip::JniLocalReferenceScope scope(env);
 
@@ -73,8 +72,8 @@ CHIP_ERROR ApplicationLauncherManager::HandleGetCatalogList(AttributeValueEncode
     env->ExceptionClear();
 
     return aEncoder.EncodeList([this, env](const auto & encoder) -> CHIP_ERROR {
-        jobjectArray jCatalogList =
-            (jobjectArray) env->CallObjectMethod(mApplicationLauncherManagerObject.ObjectRef(), mGetCatalogListMethod);
+        jintArray jCatalogList =
+            (jintArray) env->CallObjectMethod(mApplicationLauncherManagerObject.ObjectRef(), mGetCatalogListMethod);
         if (env->ExceptionCheck())
         {
             ChipLogError(Zcl, "Java exception in ApplicationLauncherManager::GetCatalogList");
@@ -84,9 +83,10 @@ CHIP_ERROR ApplicationLauncherManager::HandleGetCatalogList(AttributeValueEncode
         }
 
         jint size = env->GetArrayLength(jCatalogList);
+        jint *elements = env->GetIntArrayElements(jCatalogList, 0);
         for (int i = 0; i < size; i++)
         {
-            jint jCatalogVendorId = (jint) env->GetObjectArrayElement(jCatalogList, i);
+            jint jCatalogVendorId = elements[i];
             ReturnErrorOnFailure(encoder.Encode(static_cast<uint16_t>(jCatalogVendorId)));
         }
 

From 5dbd67ce63f5c83292124f04fff9e980ab978c0e Mon Sep 17 00:00:00 2001
From: Lazar Kovacic <lkovacic@amazon.com>
Date: Mon, 1 Jul 2024 11:50:47 +0200
Subject: [PATCH 12/22] Added option to log the content apps

---
 examples/tv-app/android/java/AppImpl.cpp              | 10 ++++++++++
 examples/tv-app/android/java/AppImpl.h                |  2 ++
 .../android/java/AppPlatformShellCommands-JNI.cpp     | 11 +++++++++++
 3 files changed, 23 insertions(+)

diff --git a/examples/tv-app/android/java/AppImpl.cpp b/examples/tv-app/android/java/AppImpl.cpp
index d04964ee5eb747..2e5a79d585cd5a 100644
--- a/examples/tv-app/android/java/AppImpl.cpp
+++ b/examples/tv-app/android/java/AppImpl.cpp
@@ -503,6 +503,16 @@ EndpointId ContentAppFactoryImpl::RemoveContentApp(EndpointId epId)
     return kInvalidEndpointId;
 }
 
+void ContentAppFactoryImpl::LogInstalledApps()
+{
+    for (auto & contentApp : mContentApps)
+    {
+        ChipLogProgress(DeviceLayer, "Content app vid=%d pid=%d is on ep=%d",
+                        contentApp->GetApplicationBasicDelegate()->HandleGetVendorId(),
+                        contentApp->GetApplicationBasicDelegate()->HandleGetProductId(), contentApp->GetEndpointId());
+    }
+}
+
 void ContentAppFactoryImpl::AddAdminVendorId(uint16_t vendorId)
 {
     mAdminVendorIds.push_back(vendorId);
diff --git a/examples/tv-app/android/java/AppImpl.h b/examples/tv-app/android/java/AppImpl.h
index 5fac7b96b2abfe..a86a11c4386626 100644
--- a/examples/tv-app/android/java/AppImpl.h
+++ b/examples/tv-app/android/java/AppImpl.h
@@ -198,6 +198,8 @@ class DLL_EXPORT ContentAppFactoryImpl : public ContentAppFactory
 
     void setContentAppCommandDelegate(ContentAppCommandDelegate * commandDelegate);
 
+    void LogInstalledApps();
+
 protected:
     // TODO: Update to use unique_ptr instead of raw pointers
     std::vector<ContentAppImpl *> mContentApps;
diff --git a/examples/tv-app/android/java/AppPlatformShellCommands-JNI.cpp b/examples/tv-app/android/java/AppPlatformShellCommands-JNI.cpp
index f15ef7bebae54c..cb491fcae91163 100644
--- a/examples/tv-app/android/java/AppPlatformShellCommands-JNI.cpp
+++ b/examples/tv-app/android/java/AppPlatformShellCommands-JNI.cpp
@@ -269,6 +269,17 @@ char * AppPlatformHandler(int argc, char ** argv)
         }
         return response;
     }
+    else if (strcmp(argv[0], "print-apps") == 0)
+    {
+        ContentAppFactoryImpl * factory = GetContentAppFactoryImpl();
+        factory->LogInstalledApps();
+
+        ChipLogProgress(DeviceLayer, "logged installed apps");
+
+        strcpy(response, "logged installed apps");
+
+        return response;
+    }
     else if (strcmp(argv[0], "remove-app-access") == 0)
     {
         Access::GetAccessControl().DeleteAllEntriesForFabric(GetDeviceCommissioner()->GetFabricIndex());

From 4320a5f85efdbcc5a464cc8c732bec8bbc3c687b Mon Sep 17 00:00:00 2001
From: "Restyled.io" <commits@restyled.io>
Date: Mon, 1 Jul 2024 09:52:35 +0000
Subject: [PATCH 13/22] Restyled by google-java-format

---
 .../tv/server/handlers/ApplicationLauncherManagerImpl.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/ApplicationLauncherManagerImpl.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
index 308cdebe66530e..ea0b8e1a50eb33 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
@@ -81,7 +81,7 @@ private void registerSelf(Context context) {
   @Override
   public int[] getCatalogList() {
     Log.i(TAG, "Get Catalog List");
-    return new int[]{65521, 8891, 3191};
+    return new int[] {65521, 8891, 3191};
   }
 
   @Override

From 8a187983e6885904f7df60891e69db1a0f97b65b Mon Sep 17 00:00:00 2001
From: "Restyled.io" <commits@restyled.io>
Date: Mon, 1 Jul 2024 09:52:36 +0000
Subject: [PATCH 14/22] Restyled by clang-format

---
 .../java/application-launcher/ApplicationLauncherManager.cpp  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp b/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
index 91ab271c5fe5d7..8ee91292a5e76a 100644
--- a/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
+++ b/examples/tv-app/android/java/application-launcher/ApplicationLauncherManager.cpp
@@ -82,8 +82,8 @@ CHIP_ERROR ApplicationLauncherManager::HandleGetCatalogList(AttributeValueEncode
             return CHIP_ERROR_INCORRECT_STATE;
         }
 
-        jint size = env->GetArrayLength(jCatalogList);
-        jint *elements = env->GetIntArrayElements(jCatalogList, 0);
+        jint size       = env->GetArrayLength(jCatalogList);
+        jint * elements = env->GetIntArrayElements(jCatalogList, 0);
         for (int i = 0; i < size; i++)
         {
             jint jCatalogVendorId = elements[i];

From c6c588af26a1f3355f96fbc736f5f70039e8b9bb Mon Sep 17 00:00:00 2001
From: Lazar Kovacic <lkovacic@amazon.com>
Date: Tue, 2 Jul 2024 16:42:15 +0200
Subject: [PATCH 15/22] Updated code per comments

---
 .../handlers/ApplicationLauncherManagerImpl.java   | 14 +++++++++-----
 examples/tv-app/android/java/AppImpl.cpp           |  5 +++--
 .../application-basic-delegate.h                   |  5 +++++
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
index ea0b8e1a50eb33..0e7ea115d7972f 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
@@ -81,7 +81,7 @@ private void registerSelf(Context context) {
   @Override
   public int[] getCatalogList() {
     Log.i(TAG, "Get Catalog List");
-    return new int[] {65521, 8891, 3191};
+    return new int[] {123, 456, 89010};
   }
 
   @Override
@@ -93,8 +93,10 @@ public LauncherResponse launchApp(Application app, String data) {
     int status = 0;
     String responseData = "";
 
-    boolean matterAppEnabledIsInstalled =
+    // Installed Apps that have declared CSA product id & vendor id in their manifes
+    boolean matterEnabledAppdIsInstalled =
         endpointsDataStore.getAllPersistedContentApps().containsKey(app.applicationId);
+    // Installed App
     boolean appIsInstalled =
         InstallationObserver.getInstalledPackages(packageManager).contains(app.applicationId);
     boolean isAppInstalling =
@@ -106,7 +108,9 @@ public LauncherResponse launchApp(Application app, String data) {
             lastReceivedInstallationStatus.get(app.applicationId),
             InstallationObserver.InstallStatus.FAILED);
 
-    if (!matterAppEnabledIsInstalled && appIsInstalled) {
+    // This use-case can happen if app is installed
+    // but it does not support Matter
+    if (!matterEnabledAppdIsInstalled && appIsInstalled) {
       Log.i(
           TAG,
           "Matter enabled app is not installed, but app is installed. Launching app's install page");
@@ -117,7 +121,7 @@ public LauncherResponse launchApp(Application app, String data) {
       // Add code to launch App Install Page
       //
 
-    } else if (!matterAppEnabledIsInstalled && !appIsInstalled) {
+    } else if (!matterEnabledAppdIsInstalled && !appIsInstalled) {
       Log.i(
           TAG,
           "Matter enabled app is not installed and app is not installed. Launching app's install page");
@@ -135,7 +139,7 @@ public LauncherResponse launchApp(Application app, String data) {
       // Add code to launch App Install Page
       //
 
-    } else if (matterAppEnabledIsInstalled && appIsInstalled) {
+    } else if (matterEnabledAppdIsInstalled && appIsInstalled) {
       Log.i(TAG, "Launching the app");
       status = LauncherResponse.STATUS_SUCCESS;
 
diff --git a/examples/tv-app/android/java/AppImpl.cpp b/examples/tv-app/android/java/AppImpl.cpp
index 2e5a79d585cd5a..c9dcf187f35e6a 100644
--- a/examples/tv-app/android/java/AppImpl.cpp
+++ b/examples/tv-app/android/java/AppImpl.cpp
@@ -507,9 +507,10 @@ void ContentAppFactoryImpl::LogInstalledApps()
 {
     for (auto & contentApp : mContentApps)
     {
-        ChipLogProgress(DeviceLayer, "Content app vid=%d pid=%d is on ep=%d",
+        ChipLogProgress(DeviceLayer, "Content app vid=%d pid=%d id=%s is on ep=%d",
                         contentApp->GetApplicationBasicDelegate()->HandleGetVendorId(),
-                        contentApp->GetApplicationBasicDelegate()->HandleGetProductId(), contentApp->GetEndpointId());
+                        contentApp->GetApplicationBasicDelegate()->HandleGetProductId(), 
+                        contentApp->GetApplicationBasicDelegate()->GetCatalogVendorApp()->GetApplicationId(), contentApp->GetEndpointId());
     }
 }
 
diff --git a/src/app/clusters/application-basic-server/application-basic-delegate.h b/src/app/clusters/application-basic-server/application-basic-delegate.h
index 6d9b796ca29c39..7c10ee99a6c55e 100644
--- a/src/app/clusters/application-basic-server/application-basic-delegate.h
+++ b/src/app/clusters/application-basic-server/application-basic-delegate.h
@@ -58,6 +58,11 @@ class DLL_EXPORT CatalogVendorApp
         Platform::CopyString(applicationId, sizeof(applicationId), appId);
     }
 
+    const char * GetApplicationId()
+    {
+        return applicationId;
+    }
+
     static const int kApplicationIdSize = 32;
     char applicationId[kApplicationIdSize];
     uint16_t catalogVendorId;

From 56a9b1493d7a7477ce26af859900b93ced1bf7a0 Mon Sep 17 00:00:00 2001
From: "Restyled.io" <commits@restyled.io>
Date: Tue, 2 Jul 2024 14:42:39 +0000
Subject: [PATCH 16/22] Restyled by whitespace

---
 examples/tv-app/android/java/AppImpl.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/examples/tv-app/android/java/AppImpl.cpp b/examples/tv-app/android/java/AppImpl.cpp
index c9dcf187f35e6a..149c2913c3b716 100644
--- a/examples/tv-app/android/java/AppImpl.cpp
+++ b/examples/tv-app/android/java/AppImpl.cpp
@@ -509,7 +509,7 @@ void ContentAppFactoryImpl::LogInstalledApps()
     {
         ChipLogProgress(DeviceLayer, "Content app vid=%d pid=%d id=%s is on ep=%d",
                         contentApp->GetApplicationBasicDelegate()->HandleGetVendorId(),
-                        contentApp->GetApplicationBasicDelegate()->HandleGetProductId(), 
+                        contentApp->GetApplicationBasicDelegate()->HandleGetProductId(),
                         contentApp->GetApplicationBasicDelegate()->GetCatalogVendorApp()->GetApplicationId(), contentApp->GetEndpointId());
     }
 }

From acc5b4bbe196b8af9784de27d0ef2b7636ab9d71 Mon Sep 17 00:00:00 2001
From: "Restyled.io" <commits@restyled.io>
Date: Tue, 2 Jul 2024 14:42:48 +0000
Subject: [PATCH 17/22] Restyled by clang-format

---
 examples/tv-app/android/java/AppImpl.cpp                     | 3 ++-
 .../application-basic-server/application-basic-delegate.h    | 5 +----
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/examples/tv-app/android/java/AppImpl.cpp b/examples/tv-app/android/java/AppImpl.cpp
index 149c2913c3b716..7ac1499ab64f55 100644
--- a/examples/tv-app/android/java/AppImpl.cpp
+++ b/examples/tv-app/android/java/AppImpl.cpp
@@ -510,7 +510,8 @@ void ContentAppFactoryImpl::LogInstalledApps()
         ChipLogProgress(DeviceLayer, "Content app vid=%d pid=%d id=%s is on ep=%d",
                         contentApp->GetApplicationBasicDelegate()->HandleGetVendorId(),
                         contentApp->GetApplicationBasicDelegate()->HandleGetProductId(),
-                        contentApp->GetApplicationBasicDelegate()->GetCatalogVendorApp()->GetApplicationId(), contentApp->GetEndpointId());
+                        contentApp->GetApplicationBasicDelegate()->GetCatalogVendorApp()->GetApplicationId(),
+                        contentApp->GetEndpointId());
     }
 }
 
diff --git a/src/app/clusters/application-basic-server/application-basic-delegate.h b/src/app/clusters/application-basic-server/application-basic-delegate.h
index 7c10ee99a6c55e..deb148233a64ff 100644
--- a/src/app/clusters/application-basic-server/application-basic-delegate.h
+++ b/src/app/clusters/application-basic-server/application-basic-delegate.h
@@ -58,10 +58,7 @@ class DLL_EXPORT CatalogVendorApp
         Platform::CopyString(applicationId, sizeof(applicationId), appId);
     }
 
-    const char * GetApplicationId()
-    {
-        return applicationId;
-    }
+    const char * GetApplicationId() { return applicationId; }
 
     static const int kApplicationIdSize = 32;
     char applicationId[kApplicationIdSize];

From d44ce2ed36831e6935638b6d661ee1e60b16796d Mon Sep 17 00:00:00 2001
From: Lazar Kovacic <lkovacic@amazon.com>
Date: Tue, 2 Jul 2024 18:33:27 +0200
Subject: [PATCH 18/22] Add downloading state

---
 .../all-clusters-minimal-app.matter                 |  5 +++--
 examples/placeholder/linux/apps/app1/config.matter  | 10 ++++++----
 examples/placeholder/linux/apps/app2/config.matter  | 10 ++++++----
 .../matter/tv/server/tvapp/LauncherResponse.java    |  3 ++-
 examples/tv-app/tv-common/tv-app.matter             |  5 +++--
 .../tv-casting-common/tv-casting-app.matter         |  5 +++--
 .../chip/application-launcher-cluster.xml           |  5 +++--
 .../data_model/controller-clusters.matter           |  5 +++--
 src/controller/python/chip/clusters/Objects.py      |  7 ++++---
 .../Framework/CHIP/zap-generated/MTRBaseClusters.h  |  5 +++--
 .../app-common/zap-generated/cluster-enums-check.h  |  5 +++--
 .../app-common/zap-generated/cluster-enums.h        | 13 +++++++------
 12 files changed, 46 insertions(+), 32 deletions(-)

diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter
index 73cdabada04c71..75590949d9fded 100644
--- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter
+++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter
@@ -5583,8 +5583,9 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
-    kStatusPending = 3;
-    kStatusInstalling = 4;
+    kPending = 3;
+    kDownloading = 4;
+    kInstalling = 5;
   }
 
   bitmap Feature : bitmap32 {
diff --git a/examples/placeholder/linux/apps/app1/config.matter b/examples/placeholder/linux/apps/app1/config.matter
index f32ba1782f42ff..9526cadc44c76e 100644
--- a/examples/placeholder/linux/apps/app1/config.matter
+++ b/examples/placeholder/linux/apps/app1/config.matter
@@ -8236,8 +8236,9 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
-    kStatusPending = 3;
-    kStatusInstalling = 4;
+    kPending = 3;
+    kDownloading = 4;
+    kInstalling = 5;
   }
 
   bitmap Feature : bitmap32 {
@@ -8297,8 +8298,9 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
-    kStatusPending = 3;
-    kStatusInstalling = 4;
+    kPending = 3;
+    kDownloading = 4;
+    kInstalling = 5;
   }
 
   bitmap Feature : bitmap32 {
diff --git a/examples/placeholder/linux/apps/app2/config.matter b/examples/placeholder/linux/apps/app2/config.matter
index 1a8af42889604a..c573466d114f2e 100644
--- a/examples/placeholder/linux/apps/app2/config.matter
+++ b/examples/placeholder/linux/apps/app2/config.matter
@@ -8193,8 +8193,9 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
-    kStatusPending = 3;
-    kStatusInstalling = 4;
+    kPending = 3;
+    kDownloading = 4;
+    kInstalling = 5;
   }
 
   bitmap Feature : bitmap32 {
@@ -8254,8 +8255,9 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
-    kStatusPending = 3;
-    kStatusInstalling = 4;
+    kPending = 3;
+    kDownloading = 4;
+    kInstalling = 5;
   }
 
   bitmap Feature : bitmap32 {
diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/LauncherResponse.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/LauncherResponse.java
index 391f92b82f319e..27da03b81954dd 100644
--- a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/LauncherResponse.java
+++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/LauncherResponse.java
@@ -6,7 +6,8 @@ public class LauncherResponse {
   public static final int STATUS_APP_NOT_AVAILABLE = 1;
   public static final int STATUS_SYSTEM_BUSY = 2;
   public static final int STATUS_PENDING = 3;
-  public static final int STATUS_INSTALLING = 4;
+  public static final int STATUS_DOWNLOADING = 4;
+  public static final int STATUS_INSTALLING = 5;
 
   public LauncherResponse(int status, String data) {
     this.status = status;
diff --git a/examples/tv-app/tv-common/tv-app.matter b/examples/tv-app/tv-common/tv-app.matter
index 727f999ae69f70..1a72fb7c9e23cd 100644
--- a/examples/tv-app/tv-common/tv-app.matter
+++ b/examples/tv-app/tv-common/tv-app.matter
@@ -3259,8 +3259,9 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
-    kStatusPending = 3;
-    kStatusInstalling = 4;
+    kPending = 3;
+    kDownloading = 4;
+    kInstalling = 5;
   }
 
   bitmap Feature : bitmap32 {
diff --git a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter
index e0d4d1ea069aa7..a4625d08c46cdb 100644
--- a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter
+++ b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter
@@ -2699,8 +2699,9 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
-    kStatusPending = 3;
-    kStatusInstalling = 4;
+    kPending = 3;
+    kDownloading = 4;
+    kInstalling = 5;
   }
 
   bitmap Feature : bitmap32 {
diff --git a/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml
index b9ec3964ab069e..1f7aad0a3080dc 100644
--- a/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml
+++ b/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml
@@ -80,7 +80,8 @@ limitations under the License.
     <item name="Success" value="0x00"/>
     <item name="AppNotAvailable" value="0x01"/>
     <item name="SystemBusy" value="0x02"/>
-    <item name="StatusPending" value="0x03"/>
-    <item name="StatusInstalling" value="0x04"/>
+    <item name="Pending" value="0x03"/>
+    <item name="Downloading" value="0x04"/>
+    <item name="Installing" value="0x05"/>
   </enum>
 </configurator>
diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter
index 1a276502f37093..159cf8bef2eda0 100644
--- a/src/controller/data_model/controller-clusters.matter
+++ b/src/controller/data_model/controller-clusters.matter
@@ -9114,8 +9114,9 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
-    kStatusPending = 3;
-    kStatusInstalling = 4;
+    kPending = 3;
+    kDownloading = 4;
+    kInstalling = 5;
   }
 
   bitmap Feature : bitmap32 {
diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py
index e6f060d36251fc..16bbbd4b240ed6 100644
--- a/src/controller/python/chip/clusters/Objects.py
+++ b/src/controller/python/chip/clusters/Objects.py
@@ -45574,13 +45574,14 @@ class StatusEnum(MatterIntEnum):
             kSuccess = 0x00
             kAppNotAvailable = 0x01
             kSystemBusy = 0x02
-            kStatusPending = 0x03
-            kStatusInstalling = 0x04
+            kPending = 0x03
+            kDownloading = 0x04
+            kInstalling = 0x05
             # All received enum values that are not listed above will be mapped
             # to kUnknownEnumValue. This is a helper enum value that should only
             # be used by code to process how it handles receiving and unknown
             # enum value. This specific should never be transmitted.
-            kUnknownEnumValue = 5,
+            kUnknownEnumValue = 6,
 
     class Bitmaps:
         class Feature(IntFlag):
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
index 70bdf7b478d62b..dfc76a379de094 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
@@ -21061,8 +21061,9 @@ typedef NS_ENUM(uint8_t, MTRApplicationLauncherStatus) {
     MTRApplicationLauncherStatusSuccess MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x00,
     MTRApplicationLauncherStatusAppNotAvailable MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x01,
     MTRApplicationLauncherStatusSystemBusy MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x02,
-    MTRApplicationLauncherStatusStatusPending MTR_PROVISIONALLY_AVAILABLE = 0x03,
-    MTRApplicationLauncherStatusStatusInstalling MTR_PROVISIONALLY_AVAILABLE = 0x04,
+    MTRApplicationLauncherStatusPending MTR_PROVISIONALLY_AVAILABLE = 0x03,
+    MTRApplicationLauncherStatusDownloading MTR_PROVISIONALLY_AVAILABLE = 0x04,
+    MTRApplicationLauncherStatusInstalling MTR_PROVISIONALLY_AVAILABLE = 0x05,
 } MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1));
 
 typedef NS_OPTIONS(uint32_t, MTRApplicationLauncherFeature) {
diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h
index ea03297cb40517..044743c6aa63c4 100644
--- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h
+++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h
@@ -3425,8 +3425,9 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(ApplicationLauncher::St
     case EnumType::kSuccess:
     case EnumType::kAppNotAvailable:
     case EnumType::kSystemBusy:
-    case EnumType::kStatusPending:
-    case EnumType::kStatusInstalling:
+    case EnumType::kPending:
+    case EnumType::kDownloading:
+    case EnumType::kInstalling:
         return val;
     default:
         return EnumType::kUnknownEnumValue;
diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
index 5c06cf190dbd08..90cbbce7b0972d 100644
--- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
+++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
@@ -5218,16 +5218,17 @@ namespace ApplicationLauncher {
 // Enum for StatusEnum
 enum class StatusEnum : uint8_t
 {
-    kSuccess          = 0x00,
-    kAppNotAvailable  = 0x01,
-    kSystemBusy       = 0x02,
-    kStatusPending    = 0x03,
-    kStatusInstalling = 0x04,
+    kSuccess         = 0x00,
+    kAppNotAvailable = 0x01,
+    kSystemBusy      = 0x02,
+    kPending         = 0x03,
+    kDownloading     = 0x04,
+    kInstalling      = 0x05,
     // All received enum values that are not listed above will be mapped
     // to kUnknownEnumValue. This is a helper enum value that should only
     // be used by code to process how it handles receiving and unknown
     // enum value. This specific should never be transmitted.
-    kUnknownEnumValue = 5,
+    kUnknownEnumValue = 6,
 };
 
 // Bitmap for Feature

From 112ab521d49e7ebba6ce7f51989fd8b563e58667 Mon Sep 17 00:00:00 2001
From: Lazar Kovacic <lkovacic@amazon.com>
Date: Tue, 2 Jul 2024 18:48:43 +0200
Subject: [PATCH 19/22] Update pending status

---
 .../all-clusters-minimal-app.matter              |  2 +-
 .../placeholder/linux/apps/app1/config.matter    |  4 ++--
 .../placeholder/linux/apps/app2/config.matter    |  4 ++--
 .../tv-app/android/App/platform-app/build.gradle | 16 ++++++++--------
 .../handlers/ApplicationLauncherManagerImpl.java |  4 ++--
 .../matter/tv/server/tvapp/LauncherResponse.java |  2 +-
 examples/tv-app/tv-common/tv-app.matter          |  2 +-
 .../tv-casting-common/tv-casting-app.matter      |  2 +-
 .../chip/application-launcher-cluster.xml        |  2 +-
 .../data_model/controller-clusters.matter        |  2 +-
 src/controller/python/chip/clusters/Objects.py   |  2 +-
 .../CHIP/zap-generated/MTRBaseClusters.h         |  2 +-
 .../zap-generated/cluster-enums-check.h          |  2 +-
 .../app-common/zap-generated/cluster-enums.h     | 12 ++++++------
 14 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter
index 75590949d9fded..9d0bf693ac59f3 100644
--- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter
+++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter
@@ -5583,7 +5583,7 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
-    kPending = 3;
+    kPendingUserApproval = 3;
     kDownloading = 4;
     kInstalling = 5;
   }
diff --git a/examples/placeholder/linux/apps/app1/config.matter b/examples/placeholder/linux/apps/app1/config.matter
index 9526cadc44c76e..027ced1a0a93c1 100644
--- a/examples/placeholder/linux/apps/app1/config.matter
+++ b/examples/placeholder/linux/apps/app1/config.matter
@@ -8236,7 +8236,7 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
-    kPending = 3;
+    kPendingUserApproval = 3;
     kDownloading = 4;
     kInstalling = 5;
   }
@@ -8298,7 +8298,7 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
-    kPending = 3;
+    kPendingUserApproval = 3;
     kDownloading = 4;
     kInstalling = 5;
   }
diff --git a/examples/placeholder/linux/apps/app2/config.matter b/examples/placeholder/linux/apps/app2/config.matter
index c573466d114f2e..2ba0b14e680f08 100644
--- a/examples/placeholder/linux/apps/app2/config.matter
+++ b/examples/placeholder/linux/apps/app2/config.matter
@@ -8193,7 +8193,7 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
-    kPending = 3;
+    kPendingUserApproval = 3;
     kDownloading = 4;
     kInstalling = 5;
   }
@@ -8255,7 +8255,7 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
-    kPending = 3;
+    kPendingUserApproval = 3;
     kDownloading = 4;
     kInstalling = 5;
   }
diff --git a/examples/tv-app/android/App/platform-app/build.gradle b/examples/tv-app/android/App/platform-app/build.gradle
index 5b4203e9c1509c..b5e99dbf8798d0 100644
--- a/examples/tv-app/android/App/platform-app/build.gradle
+++ b/examples/tv-app/android/App/platform-app/build.gradle
@@ -47,14 +47,14 @@ android {
             aidl.srcDirs = ['../common-api/src/main/aidl']
 
             // uncomment this code to debug
-//            java.srcDirs = [
-//                    'src/main/java',
-//                    '../common-api/src/main/java',
-//                    '../../third_party/connectedhomeip/src/setup_payload/java/src',
-//                    '../../third_party/connectedhomeip/src/platform/android/java',
-//                    '../../third_party/connectedhomeip/src/app/server/java/src/',
-//                    '../../java/src',
-//            ]
+            java.srcDirs = [
+                    'src/main/java',
+                    '../common-api/src/main/java',
+                    '../../third_party/connectedhomeip/src/setup_payload/java/src',
+                    '../../third_party/connectedhomeip/src/platform/android/java',
+                    '../../third_party/connectedhomeip/src/app/server/java/src/',
+                    '../../java/src',
+            ]
         }
     }
     buildFeatures {
diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
index 0e7ea115d7972f..bb1856ec6e14d1 100644
--- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
+++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ApplicationLauncherManagerImpl.java
@@ -114,7 +114,7 @@ public LauncherResponse launchApp(Application app, String data) {
       Log.i(
           TAG,
           "Matter enabled app is not installed, but app is installed. Launching app's install page");
-      status = LauncherResponse.STATUS_PENDING;
+      status = LauncherResponse.STATUS_PENDING_USER_APPROVAL;
       responseData = "App is installed, try updating";
 
       //
@@ -129,7 +129,7 @@ public LauncherResponse launchApp(Application app, String data) {
         Log.i(TAG, "App is installing");
         status = LauncherResponse.STATUS_INSTALLING;
       } else {
-        status = LauncherResponse.STATUS_PENDING;
+        status = LauncherResponse.STATUS_PENDING_USER_APPROVAL;
         if (appInstallFailed) {
           responseData = "App install failed. Try again";
         }
diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/LauncherResponse.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/LauncherResponse.java
index 27da03b81954dd..c0a41d2b153969 100644
--- a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/LauncherResponse.java
+++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/LauncherResponse.java
@@ -5,7 +5,7 @@ public class LauncherResponse {
   public static final int STATUS_SUCCESS = 0;
   public static final int STATUS_APP_NOT_AVAILABLE = 1;
   public static final int STATUS_SYSTEM_BUSY = 2;
-  public static final int STATUS_PENDING = 3;
+  public static final int STATUS_PENDING_USER_APPROVAL = 3;
   public static final int STATUS_DOWNLOADING = 4;
   public static final int STATUS_INSTALLING = 5;
 
diff --git a/examples/tv-app/tv-common/tv-app.matter b/examples/tv-app/tv-common/tv-app.matter
index 1a72fb7c9e23cd..f2a2a6f0affb0f 100644
--- a/examples/tv-app/tv-common/tv-app.matter
+++ b/examples/tv-app/tv-common/tv-app.matter
@@ -3259,7 +3259,7 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
-    kPending = 3;
+    kPendingUserApproval = 3;
     kDownloading = 4;
     kInstalling = 5;
   }
diff --git a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter
index a4625d08c46cdb..196e59a9edc720 100644
--- a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter
+++ b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter
@@ -2699,7 +2699,7 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
-    kPending = 3;
+    kPendingUserApproval = 3;
     kDownloading = 4;
     kInstalling = 5;
   }
diff --git a/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml
index 1f7aad0a3080dc..50b715e138a744 100644
--- a/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml
+++ b/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml
@@ -80,7 +80,7 @@ limitations under the License.
     <item name="Success" value="0x00"/>
     <item name="AppNotAvailable" value="0x01"/>
     <item name="SystemBusy" value="0x02"/>
-    <item name="Pending" value="0x03"/>
+    <item name="PendingUserApproval" value="0x03"/>
     <item name="Downloading" value="0x04"/>
     <item name="Installing" value="0x05"/>
   </enum>
diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter
index 159cf8bef2eda0..770d6524ef021d 100644
--- a/src/controller/data_model/controller-clusters.matter
+++ b/src/controller/data_model/controller-clusters.matter
@@ -9114,7 +9114,7 @@ cluster ApplicationLauncher = 1292 {
     kSuccess = 0;
     kAppNotAvailable = 1;
     kSystemBusy = 2;
-    kPending = 3;
+    kPendingUserApproval = 3;
     kDownloading = 4;
     kInstalling = 5;
   }
diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py
index 16bbbd4b240ed6..f3fc2a5a3341bb 100644
--- a/src/controller/python/chip/clusters/Objects.py
+++ b/src/controller/python/chip/clusters/Objects.py
@@ -45574,7 +45574,7 @@ class StatusEnum(MatterIntEnum):
             kSuccess = 0x00
             kAppNotAvailable = 0x01
             kSystemBusy = 0x02
-            kPending = 0x03
+            kPendingUserApproval = 0x03
             kDownloading = 0x04
             kInstalling = 0x05
             # All received enum values that are not listed above will be mapped
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
index dfc76a379de094..59c08128f910d0 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
@@ -21061,7 +21061,7 @@ typedef NS_ENUM(uint8_t, MTRApplicationLauncherStatus) {
     MTRApplicationLauncherStatusSuccess MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x00,
     MTRApplicationLauncherStatusAppNotAvailable MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x01,
     MTRApplicationLauncherStatusSystemBusy MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x02,
-    MTRApplicationLauncherStatusPending MTR_PROVISIONALLY_AVAILABLE = 0x03,
+    MTRApplicationLauncherStatusPendingUserApproval MTR_PROVISIONALLY_AVAILABLE = 0x03,
     MTRApplicationLauncherStatusDownloading MTR_PROVISIONALLY_AVAILABLE = 0x04,
     MTRApplicationLauncherStatusInstalling MTR_PROVISIONALLY_AVAILABLE = 0x05,
 } MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1));
diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h
index 044743c6aa63c4..be23e2d1925c0c 100644
--- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h
+++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h
@@ -3425,7 +3425,7 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(ApplicationLauncher::St
     case EnumType::kSuccess:
     case EnumType::kAppNotAvailable:
     case EnumType::kSystemBusy:
-    case EnumType::kPending:
+    case EnumType::kPendingUserApproval:
     case EnumType::kDownloading:
     case EnumType::kInstalling:
         return val;
diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
index 90cbbce7b0972d..43bb08d1673567 100644
--- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
+++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h
@@ -5218,12 +5218,12 @@ namespace ApplicationLauncher {
 // Enum for StatusEnum
 enum class StatusEnum : uint8_t
 {
-    kSuccess         = 0x00,
-    kAppNotAvailable = 0x01,
-    kSystemBusy      = 0x02,
-    kPending         = 0x03,
-    kDownloading     = 0x04,
-    kInstalling      = 0x05,
+    kSuccess             = 0x00,
+    kAppNotAvailable     = 0x01,
+    kSystemBusy          = 0x02,
+    kPendingUserApproval = 0x03,
+    kDownloading         = 0x04,
+    kInstalling          = 0x05,
     // All received enum values that are not listed above will be mapped
     // to kUnknownEnumValue. This is a helper enum value that should only
     // be used by code to process how it handles receiving and unknown

From 84b75dd9e1ab0d8c9177e4573d2271dea75f9112 Mon Sep 17 00:00:00 2001
From: Lazar Kovacic <lkovacic@amazon.com>
Date: Tue, 2 Jul 2024 18:50:02 +0200
Subject: [PATCH 20/22] Undo gradle change

---
 .../tv-app/android/App/platform-app/build.gradle | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/examples/tv-app/android/App/platform-app/build.gradle b/examples/tv-app/android/App/platform-app/build.gradle
index b5e99dbf8798d0..5b4203e9c1509c 100644
--- a/examples/tv-app/android/App/platform-app/build.gradle
+++ b/examples/tv-app/android/App/platform-app/build.gradle
@@ -47,14 +47,14 @@ android {
             aidl.srcDirs = ['../common-api/src/main/aidl']
 
             // uncomment this code to debug
-            java.srcDirs = [
-                    'src/main/java',
-                    '../common-api/src/main/java',
-                    '../../third_party/connectedhomeip/src/setup_payload/java/src',
-                    '../../third_party/connectedhomeip/src/platform/android/java',
-                    '../../third_party/connectedhomeip/src/app/server/java/src/',
-                    '../../java/src',
-            ]
+//            java.srcDirs = [
+//                    'src/main/java',
+//                    '../common-api/src/main/java',
+//                    '../../third_party/connectedhomeip/src/setup_payload/java/src',
+//                    '../../third_party/connectedhomeip/src/platform/android/java',
+//                    '../../third_party/connectedhomeip/src/app/server/java/src/',
+//                    '../../java/src',
+//            ]
         }
     }
     buildFeatures {

From 77f30ee9fd7bca06653a5625f5f62e2c6eb996a7 Mon Sep 17 00:00:00 2001
From: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com>
Date: Wed, 7 Aug 2024 17:20:24 +1200
Subject: [PATCH 21/22] Fix network-manager app device type id (#34831)

---
 .../network-manager-app/linux/include/CHIPProjectAppConfig.h    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/examples/network-manager-app/linux/include/CHIPProjectAppConfig.h b/examples/network-manager-app/linux/include/CHIPProjectAppConfig.h
index 6fa4c82568eb70..1ef9862a272938 100644
--- a/examples/network-manager-app/linux/include/CHIPProjectAppConfig.h
+++ b/examples/network-manager-app/linux/include/CHIPProjectAppConfig.h
@@ -18,7 +18,7 @@
 
 #pragma once
 
-#define CHIP_DEVICE_CONFIG_DEVICE_TYPE 0xFFF10010 // TODO: ID-TBD
+#define CHIP_DEVICE_CONFIG_DEVICE_TYPE 144 // 0x0090 Network Infrastructure Manager
 #define CHIP_DEVICE_CONFIG_DEVICE_NAME "Network Infrastructure Manager"
 
 // Inherit defaults from config/standalone/CHIPProjectConfig.h

From 4017d578b861a484335418a1c30944e3809ad963 Mon Sep 17 00:00:00 2001
From: Lazar Kovacic <lkovacic@amazon.com>
Date: Wed, 7 Aug 2024 12:07:31 +0200
Subject: [PATCH 22/22] Update object

---
 src/controller/python/chip/clusters/Objects.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py
index f3fc2a5a3341bb..b81eca3ed8aa50 100644
--- a/src/controller/python/chip/clusters/Objects.py
+++ b/src/controller/python/chip/clusters/Objects.py
@@ -45579,8 +45579,8 @@ class StatusEnum(MatterIntEnum):
             kInstalling = 0x05
             # All received enum values that are not listed above will be mapped
             # to kUnknownEnumValue. This is a helper enum value that should only
-            # be used by code to process how it handles receiving and unknown
-            # enum value. This specific should never be transmitted.
+            # be used by code to process how it handles receiving an unknown
+            # enum value. This specific value should never be transmitted.
             kUnknownEnumValue = 6,
 
     class Bitmaps: