Fixes concurrency issue in Session's toString

Currently, there is the possibility of Log.endSession() running at the
same time as Session.toString() in a different thread (for example, when
Log.i(...) is called). This can rarely cause the parent of a subsession
to be set to null after getFullSessionId has checked to see if the
parent is null, leading to a NPE.

We now cache the parentSession locally in getFullSessionId to ensure
that another thread does not unlink the parent and the child during
cleanup while toString is running.

Bug: 26693271
Change-Id: Ife7bcd5bb4db295c9b46898306119932dd24a508
diff --git a/src/com/android/server/telecom/Session.java b/src/com/android/server/telecom/Session.java
index 25a2189..51ef0fa 100644
--- a/src/com/android/server/telecom/Session.java
+++ b/src/com/android/server/telecom/Session.java
@@ -162,10 +162,15 @@
 
     // Builds full session id recursively
     private String getFullSessionId() {
-        if(mParentSession == null) {
+        // Cache mParentSession locally to prevent a concurrency problem where
+        // Log.endParentSessions() is called while a logging statement is running (Log.i, for
+        // example) and setting mParentSession to null in a different thread after the null check
+        // occurred.
+        Session parentSession = mParentSession;
+        if(parentSession == null) {
             return mSessionId;
         } else {
-            return mParentSession.getFullSessionId() + "_" + mSessionId;
+            return parentSession.getFullSessionId() + "_" + mSessionId;
         }
     }