tv-casting-app: Fixes for #24399 and #24400 (#24401)

* iOS tv-casting-app: Re-init binding handlers in startMatterServer API

* tv-casting-app: Disconnecting from previous video player before connecting to the new one

* Moving SetRotatingDeviceIdUniqueId to preInitApp so it always happens before- Matter server is initialized
iOS tv-casting-app: Changed initApp to initializeApp and added return value

* Addressing andy31415@'s feedback
diff --git a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/MainActivity.java b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/MainActivity.java
index 03d1873..4aa983c 100644
--- a/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/MainActivity.java
+++ b/examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/MainActivity.java
@@ -27,7 +27,11 @@
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
 
-    initJni();
+    boolean ret = initJni();
+    if (!ret) {
+      Log.e(TAG, "Failed to initialize Matter TV casting library");
+      return;
+    }
 
     Fragment fragment = CommissionerDiscoveryFragment.newInstance(tvCastingApp);
     getSupportFragmentManager()
@@ -71,7 +75,7 @@
    * AndroidChipPlatform to prepare platform, then start ChipAppServer, then call init on
    * TvCastingApp
    */
-  private void initJni() {
+  private boolean initJni() {
     tvCastingApp = new TvCastingApp();
 
     Context applicationContext = this.getApplicationContext();
@@ -84,7 +88,7 @@
     appParameters.setDacProvider(new DACProviderStub());
     appParameters.setSetupPasscode(GlobalCastingConstants.SetupPasscode);
     appParameters.setDiscriminator(GlobalCastingConstants.Discriminator);
-    tvCastingApp.initApp(applicationContext, appParameters);
+    return tvCastingApp.initApp(applicationContext, appParameters);
   }
 
   private void showFragment(Fragment fragment, boolean showOnBack) {
diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/TvCastingApp.java b/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/TvCastingApp.java
index c34bb12..68b98fc 100644
--- a/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/TvCastingApp.java
+++ b/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/TvCastingApp.java
@@ -65,15 +65,32 @@
             new ChipMdnsCallbackImpl(),
             new DiagnosticDataProviderImpl(applicationContext));
 
-    chipPlatform.updateCommissionableDataProviderData(
-        appParameters.getSpake2pVerifierBase64(),
-        appParameters.getSpake2pSaltBase64(),
-        appParameters.getSpake2pIterationCount(),
-        appParameters.getSetupPasscode(),
-        appParameters.getDiscriminator());
+    boolean ret =
+        chipPlatform.updateCommissionableDataProviderData(
+            appParameters.getSpake2pVerifierBase64(),
+            appParameters.getSpake2pSaltBase64(),
+            appParameters.getSpake2pIterationCount(),
+            appParameters.getSetupPasscode(),
+            appParameters.getDiscriminator());
+    if (!ret) {
+      Log.e(
+          TAG,
+          "TvCastingApp.initApp failed to updateCommissionableDataProviderData on chipPlatform");
+      return ret;
+    }
+
+    ret = preInitJni(appParameters);
+    if (!ret) {
+      Log.e(TAG, "TvCastingApp.initApp failed in preInitJni");
+      return ret;
+    }
 
     chipAppServer = new ChipAppServer();
-    chipAppServer.startApp();
+    ret = chipAppServer.startApp();
+    if (!ret) {
+      Log.e(TAG, "TvCastingApp.initApp failed in start chipAppServer");
+      return ret;
+    }
 
     setDACProvider(appParameters.getDacProvider());
     return initJni(appParameters);
@@ -81,6 +98,8 @@
 
   private native void setDACProvider(DACProvider provider);
 
+  private native boolean preInitJni(AppParameters appParameters);
+
   private native boolean initJni(AppParameters appParameters);
 
   public void discoverVideoPlayerCommissioners(
diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/TvCastingApp-JNI.cpp b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/TvCastingApp-JNI.cpp
index d702764..bb50207 100644
--- a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/TvCastingApp-JNI.cpp
+++ b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/TvCastingApp-JNI.cpp
@@ -52,6 +52,32 @@
     return AndroidAppServerJNI_OnUnload(jvm, reserved);
 }
 
+JNI_METHOD(jboolean, preInitJni)(JNIEnv *, jobject, jobject jAppParameters)
+{
+    chip::DeviceLayer::StackLock lock;
+    ChipLogProgress(AppServer, "JNI_METHOD preInitJni called");
+
+    CHIP_ERROR err = CHIP_NO_ERROR;
+    if (jAppParameters == nullptr)
+    {
+        err = CastingServer::GetInstance()->PreInit();
+    }
+    else
+    {
+        AppParams appParams;
+        err = convertJAppParametersToCppAppParams(jAppParameters, appParams);
+        VerifyOrExit(err == CHIP_NO_ERROR,
+                     ChipLogError(AppServer, "Conversion of AppParameters from jobject to Cpp type failed: %" CHIP_ERROR_FORMAT,
+                                  err.Format()));
+        err = CastingServer::GetInstance()->PreInit(&appParams);
+    }
+    VerifyOrExit(
+        err == CHIP_NO_ERROR,
+        ChipLogError(AppServer, "Call to CastingServer::GetInstance()->PreInit() failed: %" CHIP_ERROR_FORMAT, err.Format()));
+exit:
+    return (err == CHIP_NO_ERROR);
+}
+
 JNI_METHOD(jboolean, initJni)(JNIEnv *, jobject, jobject jAppParameters)
 {
     chip::DeviceLayer::StackLock lock;
@@ -74,12 +100,7 @@
     VerifyOrExit(err == CHIP_NO_ERROR,
                  ChipLogError(AppServer, "Call to CastingServer::GetInstance()->Init() failed: %" CHIP_ERROR_FORMAT, err.Format()));
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(void, setDACProvider)(JNIEnv *, jobject, jobject provider)
@@ -123,12 +144,7 @@
                  ChipLogError(AppServer, "CastingServer::OpenBasicCommissioningWindow failed: %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jobject, readCachedVideoPlayers)(JNIEnv * env, jobject)
@@ -196,12 +212,7 @@
                  ChipLogError(AppServer, "CastingServer::OpenBasicCommissioningWindow failed: %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(void, shutdownAllSubscriptions)(JNIEnv * env, jobject)
@@ -321,12 +332,7 @@
     env->ReleaseStringUTFChars(contentDisplayStr, nativeContentDisplayStr);
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 CHIP_ERROR CreateParameter(JNIEnv * env, jobject jParameter,
@@ -429,12 +435,7 @@
     env->ReleaseStringUTFChars(jData, nativeData);
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, contentLauncher_1subscribeToSupportedStreamingProtocols)
@@ -486,12 +487,7 @@
                               err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, levelControl_1step)
@@ -520,12 +516,7 @@
                  ChipLogError(AppServer, "CastingServer.LevelControl_Step failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, levelControl_1moveToLevel)
@@ -554,12 +545,7 @@
                  ChipLogError(AppServer, "CastingServer.LevelControl_MoveToLevel failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, levelControl_1subscribeToCurrentLevel)
@@ -605,12 +591,7 @@
         ChipLogError(AppServer, "CastingServer.LevelControl_SubscribeToCurrentLevel failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, levelControl_1subscribeToMinLevel)
@@ -654,12 +635,7 @@
         ChipLogError(AppServer, "CastingServer.LevelControl_SubscribeToMinLevel failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, levelControl_1subscribeToMaxLevel)
@@ -703,12 +679,7 @@
         ChipLogError(AppServer, "CastingServer.LevelControl_SubscribeToMaxLevel failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, onOff_1on)
@@ -733,12 +704,7 @@
     VerifyOrExit(CHIP_NO_ERROR == err, ChipLogError(AppServer, "CastingServer.OnOff_On failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, onOff_1off)
@@ -763,12 +729,7 @@
     VerifyOrExit(CHIP_NO_ERROR == err, ChipLogError(AppServer, "CastingServer.OnOff_Off failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, onOff_1toggle)
@@ -794,12 +755,7 @@
                  ChipLogError(AppServer, "CastingServer.OnOff_Toggle failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, mediaPlayback_1play)
@@ -825,12 +781,7 @@
                  ChipLogError(AppServer, "CastingServer.MediaPlayback_Play failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, mediaPlayback_1pause)
@@ -856,12 +807,7 @@
                  ChipLogError(AppServer, "CastingServer.MediaPlayback_Pause failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, mediaPlayback_1stopPlayback)
@@ -888,12 +834,7 @@
                  ChipLogError(AppServer, "CastingServer.MediaPlayback_StopPlayback failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, mediaPlayback_1next)
@@ -919,12 +860,7 @@
                  ChipLogError(AppServer, "CastingServer.MediaPlayback_Next failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, mediaPlayback_1seek)
@@ -951,12 +887,7 @@
                  ChipLogError(AppServer, "CastingServer.MediaPlayback_Seek failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, mediaPlayback_1skipForward)
@@ -983,12 +914,7 @@
                  ChipLogError(AppServer, "CastingServer.MediaPlayback_SkipForward failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, mediaPlayback_1skipBackward)
@@ -1015,12 +941,7 @@
                  ChipLogError(AppServer, "CastingServer.MediaPlayback_SkipBackward failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, mediaPlayback_1subscribeToCurrentState)
@@ -1066,12 +987,7 @@
         ChipLogError(AppServer, "CastingServer.MediaPlayback_SubscribeToCurrentState failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, mediaPlayback_1subscribeToDuration)
@@ -1116,12 +1032,7 @@
         ChipLogError(AppServer, "CastingServer.mediaPlayback_subscribeToDuration failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, mediaPlayback_1subscribeToSampledPosition)
@@ -1168,12 +1079,7 @@
         ChipLogError(AppServer, "CastingServer.mediaPlayback_subscribeToSampledPosition failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, mediaPlayback_1subscribeToPlaybackSpeed)
@@ -1219,12 +1125,7 @@
         ChipLogError(AppServer, "CastingServer.mediaPlayback_subscribeToPlaybackSpeed failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, mediaPlayback_1subscribeToSeekRangeEnd)
@@ -1270,12 +1171,7 @@
         ChipLogError(AppServer, "CastingServer.mediaPlayback_subscribeToSeekRangeEnd failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, mediaPlayback_1subscribeToSeekRangeStart)
@@ -1322,12 +1218,7 @@
         ChipLogError(AppServer, "CastingServer.mediaPlayback_subscribeToSeekRangeStart failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, applicationLauncher_1launchApp)
@@ -1362,12 +1253,7 @@
 
     env->ReleaseStringUTFChars(applicationId, nativeApplicationId);
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, applicationLauncher_1stopApp)
@@ -1400,12 +1286,7 @@
 
     env->ReleaseStringUTFChars(applicationId, nativeApplicationId);
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, applicationLauncher_1hideApp)
@@ -1438,12 +1319,7 @@
 
     env->ReleaseStringUTFChars(applicationId, nativeApplicationId);
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, targetNavigator_1navigateTarget)
@@ -1477,12 +1353,7 @@
         env->ReleaseStringUTFChars(data, nativeData);
     }
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, targetNavigator_1subscribeToCurrentTarget)
@@ -1529,12 +1400,7 @@
         ChipLogError(AppServer, "CastingServer.targetNavigator_subscribeToCurrentTarget failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, targetNavigator_1subscribeToTargetList)
@@ -1580,12 +1446,7 @@
         ChipLogError(AppServer, "CastingServer.targetNavigator_subscribeToTargetList failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, keypadInput_1sendKey)
@@ -1612,12 +1473,7 @@
                  ChipLogError(AppServer, "CastingServer.KeypadInput_SendKey failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 // APPLICATION BASIC
@@ -1664,12 +1520,7 @@
         ChipLogError(AppServer, "CastingServer.applicationBasic_subscribeToVendorName failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, applicationBasic_1subscribeToVendorID)
@@ -1715,12 +1566,7 @@
         ChipLogError(AppServer, "CastingServer.applicationBasic_subscribeToVendorID failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, applicationBasic_1subscribeToApplicationName)
@@ -1767,12 +1613,7 @@
                               err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, applicationBasic_1subscribeToProductID)
@@ -1818,12 +1659,7 @@
         ChipLogError(AppServer, "CastingServer.applicationBasic_subscribeToProductID failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, applicationBasic_1subscribeToApplicationVersion)
@@ -1873,12 +1709,7 @@
                               err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, applicationBasic_1readVendorName)
@@ -1915,12 +1746,7 @@
         ChipLogError(AppServer, "CastingServer.applicationBasic_1readVendorName failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, applicationBasic_1readVendorID)
@@ -1954,12 +1780,7 @@
                  ChipLogError(AppServer, "CastingServer.applicationBasic_ReadVendorID failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, applicationBasic_1readApplicationName)
@@ -1997,12 +1818,7 @@
         ChipLogError(AppServer, "CastingServer.applicationBasic_ReadApplicationName failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, applicationBasic_1readProductID)
@@ -2036,12 +1852,7 @@
                  ChipLogError(AppServer, "CastingServer.applicationBasic_ReadProductID failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
 
 JNI_METHOD(jboolean, applicationBasic_1readApplicationVersion)
@@ -2079,10 +1890,5 @@
         ChipLogError(AppServer, "CastingServer.applicationBasic_ReadApplicationVersion failed %" CHIP_ERROR_FORMAT, err.Format()));
 
 exit:
-    if (err != CHIP_NO_ERROR)
-    {
-        return false;
-    }
-
-    return true;
+    return (err == CHIP_NO_ERROR);
 }
diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h
index 2e1b980..1dc7e34 100644
--- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h
+++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h
@@ -33,9 +33,9 @@
 
 + (CastingServerBridge * _Nullable)getSharedInstance;
 
-- (void)initApp:(AppParameters * _Nullable)appParameters
-             clientQueue:(dispatch_queue_t _Nonnull)clientQueue
-    initAppStatusHandler:(nullable void (^)(bool))initAppStatusHandler;
+- (MatterError * _Nonnull)initializeApp:(AppParameters * _Nullable)appParameters
+                            clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                   initAppStatusHandler:(nullable void (^)(bool))initAppStatusHandler;
 
 /*!
  @brief Browse for on-network commissioner TVs
diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.mm
index 6e64a99..c8cfd5f 100644
--- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.mm
+++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.mm
@@ -108,9 +108,9 @@
     return self;
 }
 
-- (void)initApp:(AppParameters * _Nullable)appParameters
-             clientQueue:(dispatch_queue_t _Nonnull)clientQueue
-    initAppStatusHandler:(nullable void (^)(bool))initAppStatusHandler
+- (MatterError *)initializeApp:(AppParameters * _Nullable)appParameters
+                   clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+          initAppStatusHandler:(nullable void (^)(bool))initAppStatusHandler
 {
     ChipLogProgress(AppServer, "CastingServerBridge().initApp() called");
 
@@ -128,7 +128,7 @@
         err = [ConversionUtils convertToCppAppParamsInfoFrom:_appParameters outAppParams:cppAppParams];
         if (err != CHIP_NO_ERROR) {
             ChipLogError(AppServer, "AppParameters conversion failed: %s", ErrorStr(err));
-            return;
+            return [[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]];
         }
 
         // set fields in commissionableDataProvider
@@ -156,7 +156,7 @@
             setupDiscriminator);
         if (err != CHIP_NO_ERROR) {
             ChipLogError(AppServer, "Failed to initialize CommissionableDataProvider: %s", ErrorStr(err));
-            return;
+            return [[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]];
         }
 
         if (_appParameters.deviceAttestationCredentials != nil) {
@@ -219,13 +219,24 @@
     err = _serverInitParams->InitializeStaticResourcesBeforeServerInit();
     if (err != CHIP_NO_ERROR) {
         ChipLogError(AppServer, "InitializeStaticResourcesBeforeServerInit failed: %s", ErrorStr(err));
-        return;
+        return [[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]];
+    }
+
+    AppParams appParam;
+    if (appParameters == nil) {
+        err = CastingServer::GetInstance()->PreInit();
+    } else if ((err = [ConversionUtils convertToCppAppParamsInfoFrom:appParameters outAppParams:appParam]) == CHIP_NO_ERROR) {
+        err = CastingServer::GetInstance()->PreInit(&appParam);
+    }
+    if (err != CHIP_NO_ERROR) {
+        ChipLogError(AppServer, "CastingServer PreInit failed: %s", ErrorStr(err));
+        return [[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]];
     }
 
     err = chip::Server::GetInstance().Init(*_serverInitParams);
     if (err != CHIP_NO_ERROR) {
         ChipLogError(AppServer, "chip::Server init failed: %s", ErrorStr(err));
-        return;
+        return [[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]];
     }
 
     _chipWorkQueue = chip::DeviceLayer::PlatformMgrImpl().GetWorkQueue();
@@ -251,6 +262,9 @@
             initAppStatusHandler(initAppStatus);
         });
     });
+
+    return [[MatterError alloc] initWithCode:CHIP_NO_ERROR.AsInteger()
+                                     message:[NSString stringWithUTF8String:CHIP_NO_ERROR.AsString()]];
 }
 
 - (void)discoverCommissioners:(dispatch_queue_t _Nonnull)clientQueue
@@ -527,6 +541,17 @@
             return;
         }
 
+        // Initialize binding handlers
+        err = CastingServer::GetInstance()->InitBindingHandlers();
+        if (err != CHIP_NO_ERROR) {
+            ChipLogError(AppServer, "Binding init failed: %s", ErrorStr(err));
+            dispatch_async(clientQueue, ^{
+                startMatterServerCompletionCallback(
+                    [[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            });
+            return;
+        }
+
         // Now reconnect to the VideoPlayer the casting app was previously connected to (if any)
         if (self->_previouslyConnectedVideoPlayer != nil) {
             ChipLogProgress(
diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/TvCastingApp.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/TvCastingApp.swift
index 73c4eb1..f0d67ca 100644
--- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/TvCastingApp.swift
+++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/TvCastingApp.swift
@@ -46,9 +46,10 @@
                         
                         appParameters.onboardingPayload = onboardingParameters
                         
-                        castingServerBridge.initApp(appParameters, clientQueue: DispatchQueue.main, initAppStatusHandler: { (result: Bool) -> () in
-                            self.Log.info("initApp result \(result)")
+                        let err = castingServerBridge.initializeApp(appParameters, clientQueue: DispatchQueue.main, initAppStatusHandler: { (result: Bool) -> () in
+                            self.Log.info("initializeApp result \(result)")
                         })
+                        self.Log.info("initializeApp return value \(err)")
                     }
                 })
                 .onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
diff --git a/examples/tv-casting-app/linux/main.cpp b/examples/tv-casting-app/linux/main.cpp
index d6d674e..7558425 100644
--- a/examples/tv-casting-app/linux/main.cpp
+++ b/examples/tv-casting-app/linux/main.cpp
@@ -134,6 +134,8 @@
         SetDeviceAttestationVerifier(GetDefaultDACVerifier(testingRootStore));
     }
 
+    SuccessOrExit(err = CastingServer::GetInstance()->PreInit());
+
     // Enter commissioning mode, open commissioning window
     static chip::CommonCaseDeviceServerInitParams initParams;
     VerifyOrDie(CHIP_NO_ERROR == initParams.InitializeStaticResourcesBeforeServerInit());
diff --git a/examples/tv-casting-app/tv-casting-common/include/CastingServer.h b/examples/tv-casting-app/tv-casting-common/include/CastingServer.h
index fc0c495..ad12467 100644
--- a/examples/tv-casting-app/tv-casting-common/include/CastingServer.h
+++ b/examples/tv-casting-app/tv-casting-common/include/CastingServer.h
@@ -53,7 +53,9 @@
     void operator=(const CastingServer &) = delete;
     static CastingServer * GetInstance();
 
+    CHIP_ERROR PreInit(AppParams * AppParams = nullptr);
     CHIP_ERROR Init(AppParams * AppParams = nullptr);
+    CHIP_ERROR InitBindingHandlers();
 
     CHIP_ERROR DiscoverCommissioners();
     const chip::Dnssd::DiscoveredNodeData *
@@ -418,7 +420,8 @@
     static CastingServer * castingServer_;
     CastingServer();
 
-    CHIP_ERROR InitBindingHandlers();
+    CHIP_ERROR SetRotatingDeviceIdUniqueId(chip::Optional<chip::ByteSpan> rotatingDeviceIdUniqueId);
+
     static void DeviceEventCallback(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg);
     void ReadServerClusters(chip::EndpointId endpointId);
 
diff --git a/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp b/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp
index 786a62b..adba7ff 100644
--- a/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp
+++ b/examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp
@@ -36,6 +36,15 @@
     return castingServer_;
 }
 
+CHIP_ERROR CastingServer::PreInit(AppParams * appParams)
+{
+#if CHIP_ENABLE_ROTATING_DEVICE_ID
+    return SetRotatingDeviceIdUniqueId(appParams != nullptr ? appParams->GetRotatingDeviceIdUniqueId() : chip::NullOptional);
+#else
+    return CHIP_ERROR_NOT_IMPLEMENTED;
+#endif // CHIP_ENABLE_ROTATING_DEVICE_ID
+}
+
 CHIP_ERROR CastingServer::Init(AppParams * AppParams)
 {
     if (mInited)
@@ -43,29 +52,6 @@
         return CHIP_NO_ERROR;
     }
 
-#if CHIP_ENABLE_ROTATING_DEVICE_ID
-    // if this class's client provided a RotatingDeviceIdUniqueId, use that
-    if (AppParams != nullptr && AppParams->GetRotatingDeviceIdUniqueId().HasValue())
-    {
-        ByteSpan rotatingDeviceIdUniqueId(AppParams->GetRotatingDeviceIdUniqueId().Value());
-        chip::DeviceLayer::ConfigurationMgr().SetRotatingDeviceIdUniqueId(rotatingDeviceIdUniqueId);
-    }
-#ifdef CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID
-    else
-    {
-        // otherwise, generate and set a random uniqueId for generating rotatingId
-        uint8_t rotatingDeviceIdUniqueId[chip::DeviceLayer::ConfigurationManager::kRotatingDeviceIDUniqueIDLength];
-        for (size_t i = 0; i < sizeof(rotatingDeviceIdUniqueId); i++)
-        {
-            rotatingDeviceIdUniqueId[i] = chip::Crypto::GetRandU8();
-        }
-
-        // ByteSpan rotatingDeviceIdUniqueIdSpan(rotatingDeviceIdUniqueId);
-        chip::DeviceLayer::ConfigurationMgr().SetRotatingDeviceIdUniqueId(ByteSpan(rotatingDeviceIdUniqueId));
-    }
-#endif // CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID
-#endif // CHIP_ENABLE_ROTATING_DEVICE_ID
-
     // Initialize binding handlers
     ReturnErrorOnFailure(InitBindingHandlers());
 
@@ -76,6 +62,33 @@
     return CHIP_NO_ERROR;
 }
 
+CHIP_ERROR CastingServer::SetRotatingDeviceIdUniqueId(chip::Optional<chip::ByteSpan> rotatingDeviceIdUniqueIdOptional)
+{
+#if CHIP_ENABLE_ROTATING_DEVICE_ID
+    // if this class's client provided a RotatingDeviceIdUniqueId, use that
+    if (rotatingDeviceIdUniqueIdOptional.HasValue())
+    {
+        ChipLogProgress(AppServer, "Setting rotatingDeviceIdUniqueId received from client app");
+        return chip::DeviceLayer::ConfigurationMgr().SetRotatingDeviceIdUniqueId(rotatingDeviceIdUniqueIdOptional.Value());
+    }
+#ifdef CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID
+    else
+    {
+        // otherwise, generate and set a random uniqueId for generating rotatingId
+        ChipLogProgress(AppServer, "Setting random rotatingDeviceIdUniqueId");
+        uint8_t rotatingDeviceIdUniqueId[chip::DeviceLayer::ConfigurationManager::kRotatingDeviceIDUniqueIDLength];
+        for (size_t i = 0; i < sizeof(rotatingDeviceIdUniqueId); i++)
+        {
+            rotatingDeviceIdUniqueId[i] = chip::Crypto::GetRandU8();
+        }
+
+        return chip::DeviceLayer::ConfigurationMgr().SetRotatingDeviceIdUniqueId(ByteSpan(rotatingDeviceIdUniqueId));
+    }
+#endif // CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID
+#endif // CHIP_ENABLE_ROTATING_DEVICE_ID
+    return CHIP_NO_ERROR;
+}
+
 CHIP_ERROR CastingServer::InitBindingHandlers()
 {
     auto & server = chip::Server::GetInstance();
@@ -289,16 +302,17 @@
     mOnConnectionFailureClientCallback = onConnectionFailure;
     mOnNewOrUpdatedEndpoint            = onNewOrUpdatedEndpoint;
 
+    chip::OperationalDeviceProxy * prevDeviceProxy =
+        CastingServer::GetInstance()->mActiveTargetVideoPlayerInfo.GetOperationalDeviceProxy();
+    if (prevDeviceProxy != nullptr)
+    {
+        ChipLogProgress(AppServer, "CastingServer::VerifyOrEstablishConnection Disconnecting previous deviceProxy");
+        prevDeviceProxy->Disconnect();
+    }
+
     return targetVideoPlayerInfo.FindOrEstablishCASESession(
         [](TargetVideoPlayerInfo * videoPlayer) {
             ChipLogProgress(AppServer, "CastingServer::OnConnectionSuccess lambda called");
-            chip::OperationalDeviceProxy * prevDeviceProxy =
-                CastingServer::GetInstance()->mActiveTargetVideoPlayerInfo.GetOperationalDeviceProxy();
-            if (prevDeviceProxy != nullptr)
-            {
-                ChipLogProgress(AppServer, "CastingServer::OnConnectionSuccess lambda Disconnecting deviceProxy");
-                prevDeviceProxy->Disconnect();
-            }
             CastingServer::GetInstance()->mActiveTargetVideoPlayerInfo = *videoPlayer;
             CastingServer::GetInstance()->mOnConnectionSuccessClientCallback(videoPlayer);
         },