Remove Recursion from Telecom Session Management/Traversal

Update tests and add new flag for logging session improvements.

Bug: 370349160
Flag: com.android.server.telecom.flags.end_session_improvements
Test: atest TelecomUnitTests; manual calling
Change-Id: Iab7fb082051332dca82db70c561cdf97193225eb
diff --git a/flags/Android.bp b/flags/Android.bp
index 501eba4..54b1443 100644
--- a/flags/Android.bp
+++ b/flags/Android.bp
@@ -44,6 +44,7 @@
         "telecom_bluetoothdevicemanager_flags.aconfig",
         "telecom_non_critical_security_flags.aconfig",
         "telecom_headless_system_user_mode.aconfig",
+        "telecom_session_flags.aconfig",
         "telecom_metrics_flags.aconfig",
     ],
 }
diff --git a/flags/telecom_session_flags.aconfig b/flags/telecom_session_flags.aconfig
new file mode 100644
index 0000000..5b8075c
--- /dev/null
+++ b/flags/telecom_session_flags.aconfig
@@ -0,0 +1,13 @@
+package: "com.android.server.telecom.flags"
+container: "system"
+
+# OWNER=breadley TARGET=25Q1
+flag {
+  name: "end_session_improvements"
+  namespace: "telecom"
+  description: "Ensure that ending a session doesnt cause a stack overflow"
+  bug: "370349160"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
\ No newline at end of file
diff --git a/tests/src/com/android/server/telecom/tests/SessionManagerTest.java b/tests/src/com/android/server/telecom/tests/SessionManagerTest.java
index 3e82eac..fd33afa 100644
--- a/tests/src/com/android/server/telecom/tests/SessionManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/SessionManagerTest.java
@@ -21,10 +21,14 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
+import android.telecom.Log;
 import android.telecom.Logging.Session;
 import android.telecom.Logging.SessionManager;
 
+import com.android.server.telecom.flags.Flags;
+
 import androidx.test.filters.SmallTest;
 
 import org.junit.After;
@@ -411,4 +415,33 @@
         assertTrue(mTestSessionManager.mSessionMapper.isEmpty());
         assertNull(sessionRef.get());
     }
+
+    /**
+     * If Telecom gets into a situation where there are MANY sub-sessions created in a deep tree,
+     * ensure that cleanup still happens properly.
+     */
+    @SmallTest
+    @Test
+    public void testManySubsessionCleanupStress() {
+        // This test will mostly likely fail with recursion due to stack overflow
+        if (!Flags.endSessionImprovements()) return;
+        Log.setIsExtendedLoggingEnabled(false);
+        mTestSessionManager.mCurrentThreadId = () -> TEST_PARENT_THREAD_ID;
+        mTestSessionManager.startSession(TEST_PARENT_NAME, null);
+        Session parentSession = mTestSessionManager.mSessionMapper.get(TEST_PARENT_THREAD_ID);
+        Session subsession;
+        try {
+            for (int i = 0; i < 10000; i++) {
+                subsession = mTestSessionManager.createSubsession();
+                mTestSessionManager.endSession();
+                mTestSessionManager.continueSession(subsession, TEST_CHILD_NAME + i);
+            }
+            mTestSessionManager.endSession();
+        } catch (Exception e) {
+            fail("Exception: " + e);
+        }
+        assertTrue(mTestSessionManager.mSessionMapper.isEmpty());
+        assertTrue(parentSession.isSessionCompleted());
+        assertTrue(parentSession.getChildSessions().isEmpty());
+    }
 }
diff --git a/tests/src/com/android/server/telecom/tests/SessionTest.java b/tests/src/com/android/server/telecom/tests/SessionTest.java
index 5378596..4cddc89 100644
--- a/tests/src/com/android/server/telecom/tests/SessionTest.java
+++ b/tests/src/com/android/server/telecom/tests/SessionTest.java
@@ -269,6 +269,6 @@
     }
 
     private Session createTestSession(String name, String methodName) {
-        return new Session(name, methodName, 0, false, null);
+        return new Session(name, methodName, 0, false, false ,null);
     }
 }