diff --git a/flags/Android.bp b/flags/Android.bp
index 54b1443..6f9caae 100644
--- a/flags/Android.bp
+++ b/flags/Android.bp
@@ -46,5 +46,6 @@
         "telecom_headless_system_user_mode.aconfig",
         "telecom_session_flags.aconfig",
         "telecom_metrics_flags.aconfig",
+        "telecom_voip_flags.aconfig",
     ],
 }
diff --git a/flags/telecom_voip_flags.aconfig b/flags/telecom_voip_flags.aconfig
new file mode 100644
index 0000000..67635e9
--- /dev/null
+++ b/flags/telecom_voip_flags.aconfig
@@ -0,0 +1,13 @@
+package: "com.android.server.telecom.flags"
+container: "system"
+
+# OWNER=tjstuart TARGET=25Q2
+flag {
+  name: "voip_call_monitor_refactor"
+  namespace: "telecom"
+  description: "VoipCallMonitor reworked to handle multi calling scenarios for the same app"
+  bug: "381129034"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
\ No newline at end of file
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 9e566e2..75d8d7d 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -1883,7 +1883,6 @@
         return mTargetPhoneAccountHandle;
     }
 
-    @VisibleForTesting
     public PhoneAccountHandle getTargetPhoneAccount() {
         return mTargetPhoneAccountHandle;
     }
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index f78de5e..f6a1fd8 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -153,6 +153,7 @@
 import com.android.server.telecom.ui.ToastFactory;
 import com.android.server.telecom.callsequencing.voip.VoipCallMonitor;
 import com.android.server.telecom.callsequencing.TransactionManager;
+import com.android.server.telecom.callsequencing.voip.VoipCallMonitorLegacy;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -488,6 +489,7 @@
     private final EmergencyCallHelper mEmergencyCallHelper;
     private final RoleManagerAdapter mRoleManagerAdapter;
     private final VoipCallMonitor mVoipCallMonitor;
+    private final VoipCallMonitorLegacy mVoipCallMonitorLegacy;
     private final CallEndpointController mCallEndpointController;
     private final CallAnomalyWatchdog mCallAnomalyWatchdog;
 
@@ -763,12 +765,18 @@
         mClockProxy = clockProxy;
         mToastFactory = toastFactory;
         mRoleManagerAdapter = roleManagerAdapter;
-        mVoipCallMonitor = new VoipCallMonitor(mContext, mLock);
         mTransactionManager = transactionManager;
         mBlockedNumbersAdapter = blockedNumbersAdapter;
         mCallStreamingController = new CallStreamingController(mContext, mLock);
         mCallStreamingNotification = callStreamingNotification;
         mFeatureFlags = featureFlags;
+        if (mFeatureFlags.voipCallMonitorRefactor()) {
+            mVoipCallMonitor = new VoipCallMonitor(mContext, mLock);
+            mVoipCallMonitorLegacy = null;
+        } else {
+            mVoipCallMonitor = null;
+            mVoipCallMonitorLegacy = new VoipCallMonitorLegacy(mContext, mLock);
+        }
         mTelephonyFeatureFlags = telephonyFlags;
         mMetricsController = metricsController;
         mBlockedNumbersManager = mFeatureFlags.telecomMainlineBlockedNumbersManager()
@@ -804,13 +812,18 @@
 
         // this needs to be after the mCallAudioManager
         mListeners.add(mPhoneStateBroadcaster);
-        mListeners.add(mVoipCallMonitor);
         mListeners.add(mCallStreamingNotification);
         if (featureFlags.enableCallAudioWatchdog()) {
             mListeners.add(mCallAudioWatchDog);
         }
 
-        mVoipCallMonitor.startMonitor();
+        if (mFeatureFlags.voipCallMonitorRefactor()) {
+            mVoipCallMonitor.registerNotificationListener();
+            mListeners.add(mVoipCallMonitor);
+        } else {
+            mVoipCallMonitorLegacy.startMonitor();
+            mListeners.add(mVoipCallMonitorLegacy);
+        }
 
         // There is no USER_SWITCHED broadcast for user 0, handle it here explicitly.
         final UserManager userManager = mContext.getSystemService(UserManager.class);
diff --git a/src/com/android/server/telecom/LogUtils.java b/src/com/android/server/telecom/LogUtils.java
index a3502bd..6222601 100644
--- a/src/com/android/server/telecom/LogUtils.java
+++ b/src/com/android/server/telecom/LogUtils.java
@@ -226,6 +226,8 @@
         public static final String FLASH_NOTIFICATION_START = "FLASH_NOTIFICATION_START";
         public static final String FLASH_NOTIFICATION_STOP = "FLASH_NOTIFICATION_STOP";
         public static final String GAINED_FGS_DELEGATION = "GAINED_FGS_DELEGATION";
+        public static final String ALREADY_HAS_FGS_DELEGATION = "ALREADY_HAS_FGS_DELEGATION";
+        public static final String MAINTAINING_FGS_DELEGATION = "MAINTAINING_FGS_DELEGATION";
         public static final String GAIN_FGS_DELEGATION_FAILED = "GAIN_FGS_DELEGATION_FAILED";
         public static final String LOST_FGS_DELEGATION = "LOST_FGS_DELEGATION";
         public static final String START_STREAMING = "START_STREAMING";
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index edfbb1b..31be26e 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -80,6 +80,8 @@
 import com.android.internal.telecom.ICallEventCallback;
 import com.android.internal.telecom.ITelecomService;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.telecom.callsequencing.voip.OutgoingCallTransactionSequencing;
+import com.android.server.telecom.callsequencing.voip.VoipCallMonitor;
 import com.android.server.telecom.components.UserCallIntentProcessorFactory;
 import com.android.server.telecom.flags.FeatureFlags;
 import com.android.server.telecom.metrics.ApiStats;
@@ -168,6 +170,23 @@
     private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() {
 
         @Override
+        public boolean hasForegroundServiceDelegation(
+                PhoneAccountHandle handle,
+                String packageName) {
+            enforceCallingPackage(packageName, "hasForegroundServiceDelegation");
+            long token = Binder.clearCallingIdentity();
+            try {
+                VoipCallMonitor vcm = mCallsManager.getVoipCallMonitor();
+                if (vcm != null) {
+                    return vcm.hasForegroundServiceDelegation(handle);
+                }
+                return false;
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
         public void addCall(CallAttributes callAttributes, ICallEventCallback callEventCallback,
                 String callId, String callingPackage) {
             ApiStats.ApiEvent event = new ApiStats.ApiEvent(ApiStats.API_ADDCALL,
diff --git a/src/com/android/server/telecom/callsequencing/voip/VoipCallMonitor.java b/src/com/android/server/telecom/callsequencing/voip/VoipCallMonitor.java
index 1d1a1a6..dc770e0 100644
--- a/src/com/android/server/telecom/callsequencing/voip/VoipCallMonitor.java
+++ b/src/com/android/server/telecom/callsequencing/voip/VoipCallMonitor.java
@@ -32,8 +32,8 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
+import android.os.Looper;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
 import android.telecom.Log;
@@ -42,106 +42,144 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.LocalServices;
 import com.android.server.telecom.Call;
-
 import com.android.server.telecom.CallsManagerListenerBase;
 import com.android.server.telecom.LogUtils;
-import com.android.server.telecom.LoggedHandlerExecutor;
 import com.android.server.telecom.TelecomSystem;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
-import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
 
 public class VoipCallMonitor extends CallsManagerListenerBase {
-
-    private final List<Call> mNotificationPendingCalls;
-    // Same notification may be passed as different object in onNotificationPosted and
-    // onNotificationRemoved. Use its string as key to cache ongoing notifications.
-    private final Map<NotificationInfo, Call> mNotificationInfoToCallMap;
-    private final Map<PhoneAccountHandle, Set<Call>> mAccountHandleToCallMap;
+    private static final long NOTIFICATION_NOT_POSTED_IN_TIME_TIMEOUT = 5000L;
+    private static final long NOTIFICATION_REMOVED_BUT_CALL_IS_STILL_ONGOING_TIMEOUT = 5000L;
+    private static final String DElIMITER = "#";
+    // This list caches calls that are added to the VoipCallMonitor and need an accompanying
+    // Call-Style Notification!
+    private final List<Call> mNewCallsMissingCallStyleNotification;
+    private final ConcurrentHashMap<String, Call> mNotificationIdToCall;
+    private final ConcurrentHashMap<PhoneAccountHandle, Set<Call>> mAccountHandleToCallMap;
+    private final ConcurrentHashMap<PhoneAccountHandle, ServiceConnection> mServices;
     private ActivityManagerInternal mActivityManagerInternal;
-    private final Map<PhoneAccountHandle, ServiceConnection> mServices;
-    private NotificationListenerService mNotificationListener;
-    private final Object mLock = new Object();
-    private final HandlerThread mHandlerThread;
-    private final Handler mHandler;
+    private final NotificationListenerService mNotificationListener;
+    private final Handler mHandlerForClass;
     private final Context mContext;
-    private List<NotificationInfo> mCachedNotifications;
-    private TelecomSystem.SyncRoot mSyncRoot;
+    private final TelecomSystem.SyncRoot mSyncRoot;
 
     public VoipCallMonitor(Context context, TelecomSystem.SyncRoot lock) {
         mSyncRoot = lock;
         mContext = context;
-        mHandlerThread = new HandlerThread(this.getClass().getSimpleName());
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper());
-        mNotificationPendingCalls = new ArrayList<>();
-        mCachedNotifications = new ArrayList<>();
-        mNotificationInfoToCallMap = new HashMap<>();
-        mServices = new HashMap<>();
-        mAccountHandleToCallMap = new HashMap<>();
+        mHandlerForClass = new Handler(Looper.getMainLooper());
+        mNewCallsMissingCallStyleNotification = new ArrayList<>();
+        mNotificationIdToCall = new ConcurrentHashMap<>();
+        mServices = new ConcurrentHashMap<>();
+        mAccountHandleToCallMap = new ConcurrentHashMap<>();
         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
-
         mNotificationListener = new NotificationListenerService() {
             @Override
             public void onNotificationPosted(StatusBarNotification sbn) {
-                synchronized (mLock) {
-                    if (sbn.getNotification().isStyle(Notification.CallStyle.class)) {
-                        NotificationInfo info = new NotificationInfo(sbn.getPackageName(),
-                                sbn.getUser());
-                        boolean sbnMatched = false;
-                        for (Call call : mNotificationPendingCalls) {
-                            if (info.matchesCall(call)) {
-                                Log.i(this, "onNotificationPosted: found a pending "
-                                                + "callId=[%s] for the call notification w/ "
-                                                + "id=[%s]",
-                                        call.getId(), sbn.getId());
-                                mNotificationPendingCalls.remove(call);
-                                mNotificationInfoToCallMap.put(info, call);
-                                sbnMatched = true;
-                                break;
-                            }
+                if (isCallStyleNotification(sbn)) {
+                    Log.i(this, "onNotificationPosted: sbn=[%s]", sbn);
+                    boolean foundCallForNotification = false;
+                    // Case 1: Call added to this class (via onCallAdded) BEFORE Call-Style
+                    //         Notification is posted by the app (only supported scenario)
+                    // --> remove the newly added call from
+                    //     mNewCallsMissingCallStyleNotification so FGS is not revoked.
+                    for (Call call : new ArrayList<>(mNewCallsMissingCallStyleNotification)) {
+                        if (isNotificationForCall(sbn, call)) {
+                            Log.i(this, "onNotificationPosted: found a pending "
+                                    + "call=[%s] for sbn.id=[%s]", call, sbn.getId());
+                            mNotificationIdToCall.put(
+                                    getNotificationIdToCallKey(sbn),
+                                    call);
+                            removeFromNotificationTracking(call);
+                            foundCallForNotification = true;
+                            break;
                         }
-                        if (!sbnMatched &&
-                                !mCachedNotifications.contains(info) /* don't re-add if update */) {
-                            Log.i(this, "onNotificationPosted: could not find a"
-                                            + "call for the call notification w/ id=[%s]",
-                                    sbn.getId());
-                            // notification may post before we started to monitor the call, cache
-                            // this notification and try to match it later with new added call.
-                            mCachedNotifications.add(info);
-                        }
+                    }
+                    // Case 2: Call-Style Notification was posted BEFORE the Call was added
+                    // --> Currently do not support this
+                    // Case 3: Call-Style Notification was updated (ex. incoming -> ongoing)
+                    // --> do nothing
+                    if (!foundCallForNotification) {
+                        Log.i(this, "onNotificationPosted: could not find a call for the"
+                                + " sbn.id=[%s]. This could mean the notification posted"
+                                + " BEFORE the call is added (error) or it's an update from"
+                                + " incoming to ongoing (ok).", sbn.getId());
                     }
                 }
             }
 
             @Override
             public void onNotificationRemoved(StatusBarNotification sbn) {
-                synchronized (mLock) {
-                    NotificationInfo info = new NotificationInfo(sbn.getPackageName(),
-                            sbn.getUser());
-                    mCachedNotifications.remove(info);
-                    if (mNotificationInfoToCallMap.isEmpty()) {
-                        return;
+                if (!isCallStyleNotification(sbn)) {
+                    return;
+                }
+                Log.i(this, "onNotificationRemoved: Call-Style notification=[%s] removed", sbn);
+                Call call = getCallFromStatusBarNotificationId(sbn);
+                if (call != null) {
+                    PhoneAccountHandle handle = getTargetPhoneAccount(call);
+                    if (!isCallDisconnected(call)) {
+                        mHandlerForClass.postDelayed(() -> {
+                            if (isCallStillBeingTracked(call)) {
+                                stopFGSDelegation(call, handle);
+                            }
+                        }, NOTIFICATION_REMOVED_BUT_CALL_IS_STILL_ONGOING_TIMEOUT);
                     }
-                    Call call = mNotificationInfoToCallMap.getOrDefault(info, null);
-                    if (call != null) {
-                        // TODO: fix potential bug for multiple calls of same voip app.
-                        mNotificationInfoToCallMap.remove(info, call);
-                        stopFGSDelegation(call);
+                    mNotificationIdToCall.remove(getNotificationIdToCallKey(sbn));
+                }
+            }
+
+            // TODO:: b/383403913 fix gap in matching notifications
+            private boolean isNotificationForCall(StatusBarNotification sbn, Call call) {
+                PhoneAccountHandle callHandle = getTargetPhoneAccount(call);
+                if (callHandle == null) {
+                    return false;
+                }
+                String callPackageName = VoipCallMonitor.this.getPackageName(call);
+                return Objects.equals(sbn.getUser(), callHandle.getUserHandle()) &&
+                        Objects.equals(sbn.getPackageName(), callPackageName);
+            }
+
+            private Call getCallFromStatusBarNotificationId(StatusBarNotification sbn) {
+                if (mNotificationIdToCall.size() == 0) {
+                    return null;
+                }
+                String targetKey = getNotificationIdToCallKey(sbn);
+                for (Map.Entry<String, Call> entry : mNotificationIdToCall.entrySet()) {
+                    if (targetKey.equals(entry.getKey())) {
+                        return entry.getValue();
                     }
                 }
+                return null;
+            }
+
+            private String getNotificationIdToCallKey(StatusBarNotification sbn) {
+                return sbn.getPackageName() + DElIMITER + sbn.getId();
+            }
+
+            private boolean isCallStyleNotification(StatusBarNotification sbn) {
+                return sbn.getNotification().isStyle(Notification.CallStyle.class);
+            }
+
+            private boolean isCallStillBeingTracked(Call call) {
+                PhoneAccountHandle handle = getTargetPhoneAccount(call);
+                if (call == null || handle == null) {
+                    return false;
+                }
+                return mAccountHandleToCallMap
+                        .computeIfAbsent(handle, k -> new HashSet<>())
+                        .contains(call);
             }
         };
 
     }
 
-    public void startMonitor() {
+    public void registerNotificationListener() {
         try {
             mNotificationListener.registerAsSystemService(mContext,
                     new ComponentName(this.getClass().getPackageName(),
@@ -151,7 +189,7 @@
         }
     }
 
-    public void stopMonitor() {
+    public void unregisterNotificationListener() {
         try {
             mNotificationListener.unregisterAsSystemService();
         } catch (RemoteException e) {
@@ -161,71 +199,70 @@
 
     @Override
     public void onCallAdded(Call call) {
-        if (!call.isTransactionalCall()) {
+        PhoneAccountHandle handle = getTargetPhoneAccount(call);
+        if (!isTransactional(call) || handle == null) {
             return;
         }
-
-        synchronized (mLock) {
-            PhoneAccountHandle phoneAccountHandle = call.getTargetPhoneAccount();
-            Set<Call> callList = mAccountHandleToCallMap.computeIfAbsent(phoneAccountHandle,
-                    k -> new HashSet<>());
-            callList.add(call);
-            CompletableFuture.completedFuture(null).thenComposeAsync(
-                    (x) -> {
-                        startFGSDelegation(call.getCallingPackageIdentity().mCallingPackagePid,
-                                call.getCallingPackageIdentity().mCallingPackageUid, call);
-                        return null;
-                    }, new LoggedHandlerExecutor(mHandler, "VCM.oCA", mSyncRoot));
-        }
+        int callingPid = getCallingPackagePid(call);
+        int callingUid = getCallingPackageUid(call);
+        mAccountHandleToCallMap
+                .computeIfAbsent(handle, k -> new HashSet<>())
+                .add(call);
+        maybeStartFGSDelegation(callingPid, callingUid, handle, call);
     }
 
     @Override
     public void onCallRemoved(Call call) {
-        if (!call.isTransactionalCall()) {
+        PhoneAccountHandle handle = getTargetPhoneAccount(call);
+        if (!isTransactional(call) || handle == null) {
             return;
         }
-
-        synchronized (mLock) {
-            stopMonitorWorks(call);
-            PhoneAccountHandle phoneAccountHandle = call.getTargetPhoneAccount();
-            Set<Call> callList = mAccountHandleToCallMap.computeIfAbsent(phoneAccountHandle,
-                    k -> new HashSet<>());
-            callList.remove(call);
-
-            if (callList.isEmpty()) {
-                stopFGSDelegation(call);
-            }
+        removeFromNotificationTracking(call);
+        Set<Call> ongoingCalls = mAccountHandleToCallMap
+                .computeIfAbsent(handle, k -> new HashSet<>());
+        ongoingCalls.remove(call);
+        Log.d(this, "onCallRemoved: callList.size=[%d]", ongoingCalls.size());
+        if (ongoingCalls.isEmpty()) {
+            stopFGSDelegation(call, handle);
+        } else {
+            Log.addEvent(call, LogUtils.Events.MAINTAINING_FGS_DELEGATION);
         }
     }
 
-    private void startFGSDelegation(int pid, int uid, Call call) {
-        Log.i(this, "startFGSDelegation for call %s", call.getId());
+    private void maybeStartFGSDelegation(int pid, int uid, PhoneAccountHandle handle, Call call) {
+        Log.i(this, "maybeStartFGSDelegation for call=[%s]", call);
         if (mActivityManagerInternal != null) {
-            PhoneAccountHandle handle = call.getTargetPhoneAccount();
+            if (mServices.containsKey(handle)) {
+                Log.addEvent(call, LogUtils.Events.ALREADY_HAS_FGS_DELEGATION);
+                startMonitoringNotification(call, handle);
+                return;
+            }
             ForegroundServiceDelegationOptions options = new ForegroundServiceDelegationOptions(pid,
                     uid, handle.getComponentName().getPackageName(), null /* clientAppThread */,
                     false /* isSticky */, String.valueOf(handle.hashCode()),
                     FOREGROUND_SERVICE_TYPE_PHONE_CALL |
-                    FOREGROUND_SERVICE_TYPE_MICROPHONE |
-                    FOREGROUND_SERVICE_TYPE_CAMERA |
-                    FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE /* foregroundServiceTypes */,
+                            FOREGROUND_SERVICE_TYPE_MICROPHONE |
+                            FOREGROUND_SERVICE_TYPE_CAMERA |
+                            FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE /* foregroundServiceTypes */,
                     DELEGATION_SERVICE_PHONE_CALL /* delegationService */);
             ServiceConnection fgsConnection = new ServiceConnection() {
                 @Override
                 public void onServiceConnected(ComponentName name, IBinder service) {
+                    Log.addEvent(call, LogUtils.Events.GAINED_FGS_DELEGATION);
                     mServices.put(handle, this);
-                    startMonitorWorks(call);
+                    startMonitoringNotification(call, handle);
                 }
 
                 @Override
                 public void onServiceDisconnected(ComponentName name) {
+                    Log.addEvent(call, LogUtils.Events.LOST_FGS_DELEGATION);
                     mServices.remove(handle);
                 }
             };
             try {
                 if (mActivityManagerInternal
                         .startForegroundServiceDelegate(options, fgsConnection)) {
-                    Log.addEvent(call, LogUtils.Events.GAINED_FGS_DELEGATION);
+                    Log.i(this, "maybeStartFGSDelegation: startForegroundServiceDelegate success");
                 } else {
                     Log.addEvent(call, LogUtils.Events.GAIN_FGS_DELEGATION_FAILED);
                 }
@@ -236,77 +273,136 @@
     }
 
     @VisibleForTesting
-    public void stopFGSDelegation(Call call) {
-        synchronized (mLock) {
-            Log.i(this, "stopFGSDelegation of call %s", call);
-            PhoneAccountHandle handle = call.getTargetPhoneAccount();
-            Set<Call> calls = mAccountHandleToCallMap.get(handle);
-
-            // Every call for the package that is losing foreground service delegation should be
-            // removed from tracking maps/contains in this class
-            if (calls != null) {
-                for (Call c : calls) {
-                    stopMonitorWorks(c); // remove the call from tacking in this class
-                }
+    public void stopFGSDelegation(Call call, PhoneAccountHandle handle) {
+        Log.i(this, "stopFGSDelegation of call=[%s]", call);
+        if (handle == null) {
+            return;
+        }
+        // In the event this class is waiting for any new calls to post a notification, cleanup
+        for (Call ongoingCall :  new ArrayList<>(mAccountHandleToCallMap.get(handle))) {
+            removeFromNotificationTracking(ongoingCall);
+        }
+        if (mActivityManagerInternal != null) {
+            ServiceConnection fgsConnection = mServices.get(handle);
+            if (fgsConnection != null) {
+                Log.i(this, "stopFGSDelegation: requesting stopForegroundServiceDelegate");
+                mActivityManagerInternal.stopForegroundServiceDelegate(fgsConnection);
             }
+        }
+        mAccountHandleToCallMap.remove(handle);
+    }
 
-            mAccountHandleToCallMap.remove(handle);
+    private void startMonitoringNotification(Call call, PhoneAccountHandle handle) {
+        String packageName = getPackageName(call);
+        String callId = getCallId(call);
+        // Wait 5 seconds for a CallStyle notification to be posted for the call.
+        // If the Call-Style Notification is not posted, FGS delegation needs to be revoked!
+        Log.i(this, "startMonitoringNotification: starting timeout for call.id=[%s]", callId);
+        addToNotificationTracking(call);
+        // If no notification is posted, stop foreground service delegation!
+        mHandlerForClass.postDelayed(() -> {
+            if (isStillMissingNotification(call)) {
+                Log.i(this, "startMonitoringNotification: A Call-Style-Notification"
+                        + " for voip-call=[%s] hasn't posted in time,"
+                        + " stopping delegation for app=[%s].", call, packageName);
+                stopFGSDelegation(call, handle);
+            } else {
+                Log.i(this, "startMonitoringNotification: found a call-style"
+                        + " notification for call.id[%s] at timeout", callId);
+            }
+        }, NOTIFICATION_NOT_POSTED_IN_TIME_TIMEOUT);
+    }
 
-            if (mActivityManagerInternal != null) {
-                ServiceConnection fgsConnection = mServices.get(handle);
-                if (fgsConnection != null) {
-                    mActivityManagerInternal.stopForegroundServiceDelegate(fgsConnection);
-                    Log.addEvent(call, LogUtils.Events.LOST_FGS_DELEGATION);
-                }
+    /**
+     * Helpers
+     */
+
+    private void addToNotificationTracking(Call call) {
+        synchronized (mNewCallsMissingCallStyleNotification) {
+            mNewCallsMissingCallStyleNotification.add(call);
+        }
+    }
+
+    private boolean isStillMissingNotification(Call call) {
+        synchronized (mNewCallsMissingCallStyleNotification) {
+           return mNewCallsMissingCallStyleNotification.contains(call);
+        }
+    }
+
+    private void removeFromNotificationTracking(Call call) {
+        synchronized (mNewCallsMissingCallStyleNotification) {
+            mNewCallsMissingCallStyleNotification.remove(call);
+        }
+    }
+
+    private PhoneAccountHandle getTargetPhoneAccount(Call call) {
+        synchronized (mSyncRoot) {
+            if (call == null) {
+                return null;
+            } else {
+                return call.getTargetPhoneAccount();
             }
         }
     }
 
-    private void startMonitorWorks(Call call) {
-        startMonitorNotification(call);
-    }
-
-    private void stopMonitorWorks(Call call) {
-        stopMonitorNotification(call);
-    }
-
-    private void startMonitorNotification(Call call) {
-        synchronized (mLock) {
-            boolean sbnMatched = false;
-            for (NotificationInfo info : mCachedNotifications) {
-                if (info.matchesCall(call)) {
-                    Log.i(this, "startMonitorNotification: found a cached call "
-                            + "notification for call=[%s]", call);
-                    mCachedNotifications.remove(info);
-                    mNotificationInfoToCallMap.put(info, call);
-                    sbnMatched = true;
-                    break;
-                }
-            }
-            if (!sbnMatched) {
-                // Only continue to
-                Log.i(this, "startMonitorNotification: could not find a call"
-                        + " notification for the call=[%s];", call);
-                mNotificationPendingCalls.add(call);
-                CompletableFuture<Void> future = new CompletableFuture<>();
-                mHandler.postDelayed(() -> future.complete(null), 5000L);
-                future.thenComposeAsync(
-                        (x) -> {
-                            if (mNotificationPendingCalls.contains(call)) {
-                                Log.i(this, "Notification for voip-call %s haven't "
-                                        + "posted in time, stop delegation.", call.getId());
-                                stopFGSDelegation(call);
-                                mNotificationPendingCalls.remove(call);
-                                return null;
-                            }
-                            return null;
-                        }, new LoggedHandlerExecutor(mHandler, "VCM.sMN", mSyncRoot));
+    private int getCallingPackageUid(Call call) {
+        synchronized (mSyncRoot) {
+            if (call == null) {
+                return -1;
+            } else {
+                return call.getCallingPackageIdentity().mCallingPackageUid;
             }
         }
     }
 
-    private void stopMonitorNotification(Call call) {
-        mNotificationPendingCalls.remove(call);
+    private int getCallingPackagePid(Call call) {
+        synchronized (mSyncRoot) {
+            if (call == null) {
+                return -1;
+            } else {
+                return call.getCallingPackageIdentity().mCallingPackagePid;
+            }
+        }
+    }
+
+    private String getCallId(Call call) {
+        synchronized (mSyncRoot) {
+            if (call == null) {
+                return "";
+            } else {
+                return call.getId();
+            }
+        }
+    }
+
+    private boolean isCallDisconnected(Call call) {
+        synchronized (mSyncRoot) {
+            if (call == null) {
+                return true;
+            } else {
+                return call.isDisconnected();
+            }
+        }
+    }
+
+    private boolean isTransactional(Call call) {
+        synchronized (mSyncRoot) {
+            if (call == null) {
+                return false;
+            } else {
+                return call.isTransactionalCall();
+            }
+        }
+    }
+
+    private String getPackageName(Call call) {
+        String pn = "";
+        try {
+            pn = getTargetPhoneAccount(call).getComponentName().getPackageName();
+        } catch (Exception e) {
+            // fall through
+        }
+        return pn;
     }
 
     @VisibleForTesting
@@ -314,49 +410,6 @@
         mActivityManagerInternal = ami;
     }
 
-    private static class NotificationInfo extends Object {
-        private String mPackageName;
-        private UserHandle mUserHandle;
-
-        NotificationInfo(String packageName, UserHandle userHandle) {
-            mPackageName = packageName;
-            mUserHandle = userHandle;
-        }
-
-        boolean matchesCall(Call call) {
-            PhoneAccountHandle accountHandle = call.getTargetPhoneAccount();
-            return mPackageName != null && mPackageName.equals(
-                    accountHandle.getComponentName().getPackageName())
-                    && mUserHandle != null && mUserHandle.equals(accountHandle.getUserHandle());
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (!(obj instanceof NotificationInfo)) {
-                return false;
-            }
-            NotificationInfo that = (NotificationInfo) obj;
-            return Objects.equals(this.mPackageName, that.mPackageName)
-                    && Objects.equals(this.mUserHandle, that.mUserHandle);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mPackageName, mUserHandle);
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            sb.append("{ NotificationInfo: [mPackageName: ")
-                    .append(mPackageName)
-                    .append("], [mUserHandle=")
-                    .append(mUserHandle)
-                    .append("]  }");
-            return sb.toString();
-        }
-    }
-
     @VisibleForTesting
     public void postNotification(StatusBarNotification statusBarNotification) {
         mNotificationListener.onNotificationPosted(statusBarNotification);
@@ -367,8 +420,9 @@
         mNotificationListener.onNotificationRemoved(statusBarNotification);
     }
 
-    @VisibleForTesting
-    public Set<Call> getCallsForHandle(PhoneAccountHandle handle){
-        return mAccountHandleToCallMap.get(handle);
+    public boolean hasForegroundServiceDelegation(PhoneAccountHandle handle) {
+        boolean hasFgs = mServices.containsKey(handle);
+        Log.i(this, "hasForegroundServiceDelegation: handle=[%s], hasFgs=[%b]", handle, hasFgs);
+        return hasFgs;
     }
 }
diff --git a/src/com/android/server/telecom/callsequencing/voip/VoipCallMonitorLegacy.java b/src/com/android/server/telecom/callsequencing/voip/VoipCallMonitorLegacy.java
new file mode 100644
index 0000000..78f5d52
--- /dev/null
+++ b/src/com/android/server/telecom/callsequencing/voip/VoipCallMonitorLegacy.java
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * 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.android.server.telecom.callsequencing.voip;
+
+import static android.app.ForegroundServiceDelegationOptions.DELEGATION_SERVICE_PHONE_CALL;
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE;
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE;
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL;
+
+import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
+import android.app.ForegroundServiceDelegationOptions;
+import android.app.Notification;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
+import android.telecom.Log;
+import android.telecom.PhoneAccountHandle;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.LocalServices;
+import com.android.server.telecom.Call;
+
+import com.android.server.telecom.CallsManagerListenerBase;
+import com.android.server.telecom.LogUtils;
+import com.android.server.telecom.LoggedHandlerExecutor;
+import com.android.server.telecom.TelecomSystem;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+
+public class VoipCallMonitorLegacy extends CallsManagerListenerBase {
+
+    private final List<Call> mNotificationPendingCalls;
+    // Same notification may be passed as different object in onNotificationPosted and
+    // onNotificationRemoved. Use its string as key to cache ongoing notifications.
+    private final Map<NotificationInfo, Call> mNotificationInfoToCallMap;
+    private final Map<PhoneAccountHandle, Set<Call>> mAccountHandleToCallMap;
+    private ActivityManagerInternal mActivityManagerInternal;
+    private final Map<PhoneAccountHandle, ServiceConnection> mServices;
+    private NotificationListenerService mNotificationListener;
+    private final Object mLock = new Object();
+    private final HandlerThread mHandlerThread;
+    private final Handler mHandler;
+    private final Context mContext;
+    private List<NotificationInfo> mCachedNotifications;
+    private TelecomSystem.SyncRoot mSyncRoot;
+
+    public VoipCallMonitorLegacy(Context context, TelecomSystem.SyncRoot lock) {
+        mSyncRoot = lock;
+        mContext = context;
+        mHandlerThread = new HandlerThread(this.getClass().getSimpleName());
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
+        mNotificationPendingCalls = new ArrayList<>();
+        mCachedNotifications = new ArrayList<>();
+        mNotificationInfoToCallMap = new HashMap<>();
+        mServices = new HashMap<>();
+        mAccountHandleToCallMap = new HashMap<>();
+        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
+
+        mNotificationListener = new NotificationListenerService() {
+            @Override
+            public void onNotificationPosted(StatusBarNotification sbn) {
+                synchronized (mLock) {
+                    if (sbn.getNotification().isStyle(Notification.CallStyle.class)) {
+                        NotificationInfo info = new NotificationInfo(sbn.getPackageName(),
+                                sbn.getUser());
+                        boolean sbnMatched = false;
+                        for (Call call : mNotificationPendingCalls) {
+                            if (info.matchesCall(call)) {
+                                Log.i(this, "onNotificationPosted: found a pending "
+                                                + "callId=[%s] for the call notification w/ "
+                                                + "id=[%s]",
+                                        call.getId(), sbn.getId());
+                                mNotificationPendingCalls.remove(call);
+                                mNotificationInfoToCallMap.put(info, call);
+                                sbnMatched = true;
+                                break;
+                            }
+                        }
+                        if (!sbnMatched &&
+                                !mCachedNotifications.contains(info) /* don't re-add if update */) {
+                            Log.i(this, "onNotificationPosted: could not find a"
+                                            + "call for the call notification w/ id=[%s]",
+                                    sbn.getId());
+                            // notification may post before we started to monitor the call, cache
+                            // this notification and try to match it later with new added call.
+                            mCachedNotifications.add(info);
+                        }
+                    }
+                }
+            }
+
+            @Override
+            public void onNotificationRemoved(StatusBarNotification sbn) {
+                synchronized (mLock) {
+                    NotificationInfo info = new NotificationInfo(sbn.getPackageName(),
+                            sbn.getUser());
+                    mCachedNotifications.remove(info);
+                    if (mNotificationInfoToCallMap.isEmpty()) {
+                        return;
+                    }
+                    Call call = mNotificationInfoToCallMap.getOrDefault(info, null);
+                    if (call != null) {
+                        mNotificationInfoToCallMap.remove(info, call);
+                        CompletableFuture<Void> future = new CompletableFuture<>();
+                        mHandler.postDelayed(() -> future.complete(null), 5000L);
+                        stopFGSDelegation(call);
+                    }
+                }
+            }
+        };
+
+    }
+
+    public void startMonitor() {
+        try {
+            mNotificationListener.registerAsSystemService(mContext,
+                    new ComponentName(this.getClass().getPackageName(),
+                            this.getClass().getCanonicalName()), ActivityManager.getCurrentUser());
+        } catch (RemoteException e) {
+            Log.e(this, e, "Cannot register notification listener");
+        }
+    }
+
+    public void stopMonitor() {
+        try {
+            mNotificationListener.unregisterAsSystemService();
+        } catch (RemoteException e) {
+            Log.e(this, e, "Cannot unregister notification listener");
+        }
+    }
+
+    @Override
+    public void onCallAdded(Call call) {
+        if (!call.isTransactionalCall()) {
+            return;
+        }
+
+        synchronized (mLock) {
+            PhoneAccountHandle phoneAccountHandle = call.getTargetPhoneAccount();
+            Set<Call> callList = mAccountHandleToCallMap.computeIfAbsent(phoneAccountHandle,
+                    k -> new HashSet<>());
+            callList.add(call);
+            CompletableFuture.completedFuture(null).thenComposeAsync(
+                    (x) -> {
+                        startFGSDelegation(call.getCallingPackageIdentity().mCallingPackagePid,
+                                call.getCallingPackageIdentity().mCallingPackageUid, call);
+                        return null;
+                    }, new LoggedHandlerExecutor(mHandler, "VCM.oCA", mSyncRoot));
+        }
+    }
+
+    @Override
+    public void onCallRemoved(Call call) {
+        if (!call.isTransactionalCall()) {
+            return;
+        }
+        synchronized (mLock) {
+            stopMonitorWorks(call);
+            PhoneAccountHandle phoneAccountHandle = call.getTargetPhoneAccount();
+            Set<Call> callList = mAccountHandleToCallMap.computeIfAbsent(phoneAccountHandle,
+                    k -> new HashSet<>());
+            callList.remove(call);
+            if (callList.isEmpty()) {
+                stopFGSDelegation(call);
+            }
+        }
+    }
+
+    private void startFGSDelegation(int pid, int uid, Call call) {
+        Log.i(this, "startFGSDelegation for call %s", call.getId());
+        if (mActivityManagerInternal != null) {
+            PhoneAccountHandle handle = call.getTargetPhoneAccount();
+            ForegroundServiceDelegationOptions options = new ForegroundServiceDelegationOptions(pid,
+                    uid, handle.getComponentName().getPackageName(), null /* clientAppThread */,
+                    false /* isSticky */, String.valueOf(handle.hashCode()),
+                    FOREGROUND_SERVICE_TYPE_PHONE_CALL |
+                    FOREGROUND_SERVICE_TYPE_MICROPHONE |
+                    FOREGROUND_SERVICE_TYPE_CAMERA |
+                    FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE /* foregroundServiceTypes */,
+                    DELEGATION_SERVICE_PHONE_CALL /* delegationService */);
+            ServiceConnection fgsConnection = new ServiceConnection() {
+                @Override
+                public void onServiceConnected(ComponentName name, IBinder service) {
+                    mServices.put(handle, this);
+                    startMonitorWorks(call);
+                }
+
+                @Override
+                public void onServiceDisconnected(ComponentName name) {
+                    mServices.remove(handle);
+                }
+            };
+            try {
+                if (mActivityManagerInternal
+                        .startForegroundServiceDelegate(options, fgsConnection)) {
+                    Log.addEvent(call, LogUtils.Events.GAINED_FGS_DELEGATION);
+                } else {
+                    Log.addEvent(call, LogUtils.Events.GAIN_FGS_DELEGATION_FAILED);
+                }
+            } catch (Exception e) {
+                Log.i(this, "startForegroundServiceDelegate failed due to: " + e);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    public void stopFGSDelegation(Call call) {
+        synchronized (mLock) {
+            Log.i(this, "stopFGSDelegation of call %s", call);
+            PhoneAccountHandle handle = call.getTargetPhoneAccount();
+            Set<Call> calls = mAccountHandleToCallMap.get(handle);
+
+            // Every call for the package that is losing foreground service delegation should be
+            // removed from tracking maps/contains in this class
+            if (calls != null) {
+                for (Call c : calls) {
+                    stopMonitorWorks(c); // remove the call from tacking in this class
+                }
+            }
+
+            mAccountHandleToCallMap.remove(handle);
+
+            if (mActivityManagerInternal != null) {
+                ServiceConnection fgsConnection = mServices.get(handle);
+                if (fgsConnection != null) {
+                    mActivityManagerInternal.stopForegroundServiceDelegate(fgsConnection);
+                    Log.addEvent(call, LogUtils.Events.LOST_FGS_DELEGATION);
+                }
+            }
+        }
+    }
+
+    private void startMonitorWorks(Call call) {
+        startMonitorNotification(call);
+    }
+
+    private void stopMonitorWorks(Call call) {
+        stopMonitorNotification(call);
+    }
+
+    private void startMonitorNotification(Call call) {
+        synchronized (mLock) {
+            boolean sbnMatched = false;
+            for (NotificationInfo info : mCachedNotifications) {
+                if (info.matchesCall(call)) {
+                    Log.i(this, "startMonitorNotification: found a cached call "
+                            + "notification for call=[%s]", call);
+                    mCachedNotifications.remove(info);
+                    mNotificationInfoToCallMap.put(info, call);
+                    sbnMatched = true;
+                    break;
+                }
+            }
+            if (!sbnMatched) {
+                // Only continue to
+                Log.i(this, "startMonitorNotification: could not find a call"
+                        + " notification for the call=[%s];", call);
+                mNotificationPendingCalls.add(call);
+                CompletableFuture<Void> future = new CompletableFuture<>();
+                mHandler.postDelayed(() -> future.complete(null), 5000L);
+                future.thenComposeAsync(
+                        (x) -> {
+                            if (mNotificationPendingCalls.contains(call)) {
+                                Log.i(this, "Notification for voip-call %s haven't "
+                                        + "posted in time, stop delegation.", call.getId());
+                                stopFGSDelegation(call);
+                                mNotificationPendingCalls.remove(call);
+                                return null;
+                            }
+                            return null;
+                        }, new LoggedHandlerExecutor(mHandler, "VCM.sMN", mSyncRoot));
+            }
+        }
+    }
+
+    private void stopMonitorNotification(Call call) {
+        mNotificationPendingCalls.remove(call);
+    }
+
+    @VisibleForTesting
+    public void setActivityManagerInternal(ActivityManagerInternal ami) {
+        mActivityManagerInternal = ami;
+    }
+
+    private static class NotificationInfo extends Object {
+        private String mPackageName;
+        private UserHandle mUserHandle;
+
+        NotificationInfo(String packageName, UserHandle userHandle) {
+            mPackageName = packageName;
+            mUserHandle = userHandle;
+        }
+
+        boolean matchesCall(Call call) {
+            PhoneAccountHandle accountHandle = call.getTargetPhoneAccount();
+            return mPackageName != null && mPackageName.equals(
+                    accountHandle.getComponentName().getPackageName())
+                    && mUserHandle != null && mUserHandle.equals(accountHandle.getUserHandle());
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof NotificationInfo)) {
+                return false;
+            }
+            NotificationInfo that = (NotificationInfo) obj;
+            return Objects.equals(this.mPackageName, that.mPackageName)
+                    && Objects.equals(this.mUserHandle, that.mUserHandle);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mPackageName, mUserHandle);
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append("{ NotificationInfo: [mPackageName: ")
+                    .append(mPackageName)
+                    .append("], [mUserHandle=")
+                    .append(mUserHandle)
+                    .append("]  }");
+            return sb.toString();
+        }
+    }
+
+    @VisibleForTesting
+    public void postNotification(StatusBarNotification statusBarNotification) {
+        mNotificationListener.onNotificationPosted(statusBarNotification);
+    }
+
+    @VisibleForTesting
+    public void removeNotification(StatusBarNotification statusBarNotification) {
+        mNotificationListener.onNotificationRemoved(statusBarNotification);
+    }
+
+    @VisibleForTesting
+    public Set<Call> getCallsForHandle(PhoneAccountHandle handle){
+        return mAccountHandleToCallMap.get(handle);
+    }
+}
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index 1e65011..447e5ab 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -99,6 +99,7 @@
 import com.android.server.telecom.WiredHeadsetManager;
 import com.android.server.telecom.bluetooth.BluetoothRouteManager;
 import com.android.server.telecom.callfiltering.BlockedNumbersAdapter;
+import com.android.server.telecom.callsequencing.voip.VoipCallMonitor;
 import com.android.server.telecom.components.UserCallIntentProcessor;
 import com.android.server.telecom.flags.FeatureFlags;
 import com.android.server.telecom.ui.IncomingCallNotifier;
@@ -418,7 +419,11 @@
                 handlerThread.quitSafely();
             }
             handlerThreads.clear();
-            mTelecomSystem.getCallsManager().getVoipCallMonitor().stopMonitor();
+
+            VoipCallMonitor vcm = mTelecomSystem.getCallsManager().getVoipCallMonitor();
+            if (vcm != null) {
+                vcm.unregisterNotificationListener();
+            }
         }
         waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
         waitForHandlerAction(mHandlerThread.getThreadHandler(), TEST_TIMEOUT);
diff --git a/tests/src/com/android/server/telecom/tests/VoipCallMonitorTest.java b/tests/src/com/android/server/telecom/tests/VoipCallMonitorTest.java
index bf68f8c..e6d1bc9 100644
--- a/tests/src/com/android/server/telecom/tests/VoipCallMonitorTest.java
+++ b/tests/src/com/android/server/telecom/tests/VoipCallMonitorTest.java
@@ -25,7 +25,6 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -51,6 +50,7 @@
 import com.android.server.telecom.TelecomSystem;
 import com.android.server.telecom.callsequencing.voip.VoipCallMonitor;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -68,7 +68,7 @@
     private static final String ID_1 = "id1";
     public static final String CHANNEL_ID = "TelecomVoipAppChannelId";
     private static final UserHandle USER_HANDLE_1 = new UserHandle(1);
-    private static final long TIMEOUT = 5000L;
+    private static final long TIMEOUT = 6000L;
 
     @Mock private TelecomSystem.SyncRoot mLock;
     @Mock private ActivityManagerInternal mActivityManagerInternal;
@@ -86,12 +86,19 @@
         mMonitor = new VoipCallMonitor(mContext, mLock);
         mActivityManagerInternal = mock(ActivityManagerInternal.class);
         mMonitor.setActivityManagerInternal(mActivityManagerInternal);
-        mMonitor.startMonitor();
+        mMonitor.registerNotificationListener();
         when(mActivityManagerInternal.startForegroundServiceDelegate(any(
                 ForegroundServiceDelegationOptions.class), any(ServiceConnection.class)))
                 .thenReturn(true);
     }
 
+    @Override
+    @After
+    public void tearDown() throws Exception {
+        mMonitor.unregisterNotificationListener();
+        super.tearDown();
+    }
+
     /**
      * This test ensures VoipCallMonitor is passing the correct foregroundServiceTypes when starting
      * foreground service delegation on behalf of a client.
@@ -106,12 +113,12 @@
         mMonitor.onCallAdded(call);
 
         verify(mActivityManagerInternal, timeout(TIMEOUT)).startForegroundServiceDelegate(
-                 optionsCaptor.capture(), any(ServiceConnection.class));
+                optionsCaptor.capture(), any(ServiceConnection.class));
 
-        assertEquals( FOREGROUND_SERVICE_TYPE_PHONE_CALL |
-                FOREGROUND_SERVICE_TYPE_MICROPHONE |
-                FOREGROUND_SERVICE_TYPE_CAMERA |
-                FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE,
+        assertEquals(FOREGROUND_SERVICE_TYPE_PHONE_CALL |
+                        FOREGROUND_SERVICE_TYPE_MICROPHONE |
+                        FOREGROUND_SERVICE_TYPE_CAMERA |
+                        FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE,
                 optionsCaptor.getValue().mForegroundServiceTypes);
 
         mMonitor.onCallRemoved(call);
@@ -120,51 +127,49 @@
     @SmallTest
     @Test
     public void testStartMonitorForOneCall() {
+        // GIVEN - a single call and notification for a voip app
         Call call = createTestCall("testCall", mHandle1User1);
-        IBinder service = mock(IBinder.class);
+        StatusBarNotification sbn = createStatusBarNotificationFromHandle(mHandle1User1);
 
-        ArgumentCaptor<ServiceConnection> captor = ArgumentCaptor.forClass(ServiceConnection.class);
-        mMonitor.onCallAdded(call);
-        verify(mActivityManagerInternal, timeout(TIMEOUT)).startForegroundServiceDelegate(any(
-                ForegroundServiceDelegationOptions.class), captor.capture());
-        ServiceConnection conn = captor.getValue();
-        conn.onServiceConnected(mHandle1User1.getComponentName(), service);
+        // WHEN - the Voip call is added and a notification is posted, verify FGS is gained
+        addCallAndVerifyFgsIsGained(call);
+        mMonitor.postNotification(sbn);
 
+        // THEN - when the Voip call is removed, verify that FGS is revoked for the app
         mMonitor.onCallRemoved(call);
-        verify(mActivityManagerInternal, timeout(TIMEOUT)).stopForegroundServiceDelegate(eq(conn));
+        mMonitor.removeNotification(sbn);
+        verify(mActivityManagerInternal, timeout(TIMEOUT))
+                .stopForegroundServiceDelegate(any(ServiceConnection.class));
     }
 
+    /**
+     * Verify FGS is not lost if another call is ongoing for a Voip app
+     */
     @SmallTest
     @Test
-    public void testMonitorForTwoCallsOnSameHandle() {
+    public void testStopDelegation_SameApp() {
+        // GIVEN - 2 consecutive calls for a single Voip app
         Call call1 = createTestCall("testCall1", mHandle1User1);
+        StatusBarNotification sbn1 = createStatusBarNotificationFromHandle(mHandle1User1);
         Call call2 = createTestCall("testCall2", mHandle1User1);
-        IBinder service = mock(IBinder.class);
+        StatusBarNotification sbn2 = createStatusBarNotificationFromHandle(mHandle1User1);
 
-        ArgumentCaptor<ServiceConnection> captor1 =
-                ArgumentCaptor.forClass(ServiceConnection.class);
-        mMonitor.onCallAdded(call1);
-        verify(mActivityManagerInternal, timeout(TIMEOUT).times(1))
-                .startForegroundServiceDelegate(any(ForegroundServiceDelegationOptions.class),
-                        captor1.capture());
-        ServiceConnection conn1 = captor1.getValue();
-        conn1.onServiceConnected(mHandle1User1.getComponentName(), service);
-
-        ArgumentCaptor<ServiceConnection> captor2 =
-                ArgumentCaptor.forClass(ServiceConnection.class);
+        // WHEN - the second call is added and the first is disconnected
+        mMonitor.postNotification(sbn1);
+        addCallAndVerifyFgsIsGained(call1);
+        mMonitor.postNotification(sbn2);
         mMonitor.onCallAdded(call2);
-        verify(mActivityManagerInternal, timeout(TIMEOUT).times(2))
-                .startForegroundServiceDelegate(any(ForegroundServiceDelegationOptions.class),
-                        captor2.capture());
-        ServiceConnection conn2 = captor2.getValue();
-        conn2.onServiceConnected(mHandle1User1.getComponentName(), service);
-
         mMonitor.onCallRemoved(call1);
-        verify(mActivityManagerInternal, never()).stopForegroundServiceDelegate(
-                any(ServiceConnection.class));
+
+        // THEN - assert FGS is maintained for the process since there is still an ongoing call
+        verify(mActivityManagerInternal, timeout(TIMEOUT).times(0))
+                .stopForegroundServiceDelegate(any(ServiceConnection.class));
+        mMonitor.removeNotification(sbn1);
+        // once all calls are removed, verify FGS is stopped
         mMonitor.onCallRemoved(call2);
+        mMonitor.removeNotification(sbn2);
         verify(mActivityManagerInternal, timeout(TIMEOUT).times(1))
-                .stopForegroundServiceDelegate(eq(conn2));
+                .stopForegroundServiceDelegate(any(ServiceConnection.class));
     }
 
     @SmallTest
@@ -204,40 +209,6 @@
         verify(mActivityManagerInternal).stopForegroundServiceDelegate(eq(conn1));
     }
 
-    @SmallTest
-    @Test
-    public void testStopDelegation() {
-        Call call1 = createTestCall("testCall1", mHandle1User1);
-        Call call2 = createTestCall("testCall2", mHandle1User1);
-        IBinder service = mock(IBinder.class);
-
-        ArgumentCaptor<ServiceConnection> captor1 =
-                ArgumentCaptor.forClass(ServiceConnection.class);
-        mMonitor.onCallAdded(call1);
-        verify(mActivityManagerInternal, timeout(TIMEOUT).times(1))
-                .startForegroundServiceDelegate(any(ForegroundServiceDelegationOptions.class),
-                        captor1.capture());
-        ServiceConnection conn1 = captor1.getValue();
-        conn1.onServiceConnected(mHandle1User1.getComponentName(), service);
-
-        ArgumentCaptor<ServiceConnection> captor2 =
-                ArgumentCaptor.forClass(ServiceConnection.class);
-        mMonitor.onCallAdded(call2);
-        verify(mActivityManagerInternal, timeout(TIMEOUT).times(2))
-                .startForegroundServiceDelegate(any(ForegroundServiceDelegationOptions.class),
-                        captor2.capture());
-        ServiceConnection conn2 = captor2.getValue();
-        conn2.onServiceConnected(mHandle1User1.getComponentName(), service);
-
-        mMonitor.stopFGSDelegation(call1);
-        verify(mActivityManagerInternal, timeout(TIMEOUT).times(1))
-                .stopForegroundServiceDelegate(eq(conn2));
-        conn2.onServiceDisconnected(mHandle1User1.getComponentName());
-        mMonitor.onCallRemoved(call1);
-        verify(mActivityManagerInternal, timeout(TIMEOUT).times(1))
-                .stopForegroundServiceDelegate(any(ServiceConnection.class));
-    }
-
     /**
      * Ensure an app loses foreground service delegation if the user dismisses the call style
      * notification or the app removes the notification.
@@ -263,28 +234,8 @@
     }
 
     /**
-     * Ensure an app loses foreground service delegation if the user dismisses the call style
-     * notification or the app removes the notification.
-     * Note: post the notification BEFORE foreground service delegation is gained
+     * Helpers for testing
      */
-    @SmallTest
-    @Test
-    public void testStopFgsIfCallNotificationIsRemoved_PostedBeforeFgsIsGained() {
-        // GIVEN
-        StatusBarNotification sbn = createStatusBarNotificationFromHandle(mHandle1User1);
-
-        // WHEN
-        //  an app posts a call style notification before FGS is gained
-        mMonitor.postNotification(sbn);
-        // FGS is gained after the call is added to VoipCallMonitor
-        ServiceConnection c = addCallAndVerifyFgsIsGained(createTestCall("1", mHandle1User1));
-
-        // THEN
-        // shortly after posting the notification, simulate the user dismissing it
-        mMonitor.removeNotification(sbn);
-        // FGS should be removed once the notification is removed
-        verify(mActivityManagerInternal, timeout(TIMEOUT)).stopForegroundServiceDelegate(c);
-    }
 
     private Call createTestCall(String id, PhoneAccountHandle handle) {
         Call call = mock(Call.class);
@@ -329,7 +280,9 @@
         // onServiceConnected must be called in order for VoipCallMonitor to start monitoring for
         // a notification before the timeout expires
         ServiceConnection serviceConnection = captor.getValue();
-        serviceConnection.onServiceConnected(mHandle1User1.getComponentName(), mServiceConnection);
+        serviceConnection.onServiceConnected(
+                call.getTargetPhoneAccount().getComponentName(),
+                mServiceConnection);
         return serviceConnection;
     }
 }
