diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java
index f29c40f..e0cc8e1 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/services/core/java/com/android/server/vcn/Vcn.java
@@ -39,13 +39,10 @@
 import android.net.vcn.VcnGatewayConnectionConfig;
 import android.net.vcn.VcnManager.VcnErrorCode;
 import android.os.Handler;
-import android.os.HandlerExecutor;
 import android.os.Message;
 import android.os.ParcelUuid;
 import android.provider.Settings;
-import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyManager;
-import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
 
@@ -60,7 +57,6 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -152,10 +148,6 @@
     @NonNull private final VcnContentResolver mContentResolver;
     @NonNull private final ContentObserver mMobileDataSettingsObserver;
 
-    @NonNull
-    private final Map<Integer, VcnUserMobileDataStateListener> mMobileDataStateListeners =
-            new ArrayMap<>();
-
     /**
      * Map containing all VcnGatewayConnections and their VcnGatewayConnectionConfigs.
      *
@@ -229,9 +221,6 @@
         // Update mIsMobileDataEnabled before starting handling of NetworkRequests.
         mIsMobileDataEnabled = getMobileDataStatus();
 
-        // Register mobile data state listeners.
-        updateMobileDataStateListeners();
-
         // Register to receive cached and future NetworkRequests
         mVcnContext.getVcnNetworkProvider().registerListener(mRequestListener);
     }
@@ -359,12 +348,6 @@
             gatewayConnection.teardownAsynchronously();
         }
 
-        // Unregister MobileDataStateListeners
-        for (VcnUserMobileDataStateListener listener : mMobileDataStateListeners.values()) {
-            getTelephonyManager().unregisterTelephonyCallback(listener);
-        }
-        mMobileDataStateListeners.clear();
-
         mCurrentStatus = VCN_STATUS_CODE_INACTIVE;
     }
 
@@ -471,40 +454,11 @@
             gatewayConnection.updateSubscriptionSnapshot(mLastSnapshot);
         }
 
-        updateMobileDataStateListeners();
-
         // Update the mobile data state after updating the subscription snapshot as a change in
         // subIds for a subGroup may affect the mobile data state.
         handleMobileDataToggled();
     }
 
-    private void updateMobileDataStateListeners() {
-        final Set<Integer> subIdsInGroup = mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup);
-        final HandlerExecutor executor = new HandlerExecutor(this);
-
-        // Register new callbacks
-        for (int subId : subIdsInGroup) {
-            if (!mMobileDataStateListeners.containsKey(subId)) {
-                final VcnUserMobileDataStateListener listener =
-                        new VcnUserMobileDataStateListener();
-
-                getTelephonyManagerForSubid(subId).registerTelephonyCallback(executor, listener);
-                mMobileDataStateListeners.put(subId, listener);
-            }
-        }
-
-        // Unregister old callbacks
-        Iterator<Entry<Integer, VcnUserMobileDataStateListener>> iterator =
-                mMobileDataStateListeners.entrySet().iterator();
-        while (iterator.hasNext()) {
-            final Entry<Integer, VcnUserMobileDataStateListener> entry = iterator.next();
-            if (!subIdsInGroup.contains(entry.getKey())) {
-                getTelephonyManager().unregisterTelephonyCallback(entry.getValue());
-                iterator.remove();
-            }
-        }
-    }
-
     private void handleMobileDataToggled() {
         final boolean oldMobileDataEnabledStatus = mIsMobileDataEnabled;
         mIsMobileDataEnabled = getMobileDataStatus();
@@ -539,8 +493,11 @@
     }
 
     private boolean getMobileDataStatus() {
+        final TelephonyManager genericTelMan =
+                mVcnContext.getContext().getSystemService(TelephonyManager.class);
+
         for (int subId : mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup)) {
-            if (getTelephonyManagerForSubid(subId).isDataEnabled()) {
+            if (genericTelMan.createForSubscriptionId(subId).isDataEnabled()) {
                 return true;
             }
         }
@@ -560,14 +517,6 @@
         return request.canBeSatisfiedBy(builder.build());
     }
 
-    private TelephonyManager getTelephonyManager() {
-        return mVcnContext.getContext().getSystemService(TelephonyManager.class);
-    }
-
-    private TelephonyManager getTelephonyManagerForSubid(int subid) {
-        return getTelephonyManager().createForSubscriptionId(subid);
-    }
-
     private String getLogPrefix() {
         return "["
                 + LogUtils.getHashedSubscriptionGroup(mSubscriptionGroup)
@@ -721,16 +670,6 @@
         }
     }
 
-    @VisibleForTesting(visibility = Visibility.PRIVATE)
-    class VcnUserMobileDataStateListener extends TelephonyCallback
-            implements TelephonyCallback.UserMobileDataStateListener {
-
-        @Override
-        public void onUserMobileDataStateChanged(boolean enabled) {
-            sendMessage(obtainMessage(MSG_EVENT_MOBILE_DATA_TOGGLED));
-        }
-    }
-
     /** External dependencies used by Vcn, for injection in tests */
     @VisibleForTesting(visibility = Visibility.PRIVATE)
     public static class Dependencies {
diff --git a/tests/vcn/java/com/android/server/vcn/VcnTest.java b/tests/vcn/java/com/android/server/vcn/VcnTest.java
index 6d26968..5d2f9d7 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnTest.java
@@ -58,7 +58,6 @@
 import com.android.server.VcnManagementService.VcnCallback;
 import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
 import com.android.server.vcn.Vcn.VcnGatewayStatusCallback;
-import com.android.server.vcn.Vcn.VcnUserMobileDataStateListener;
 import com.android.server.vcn.VcnNetworkProvider.NetworkRequestListener;
 
 import org.junit.Before;
@@ -209,13 +208,6 @@
     }
 
     @Test
-    public void testMobileDataStateListenersRegistered() {
-        // Validate state from setUp()
-        verify(mTelephonyManager, times(3))
-                .registerTelephonyCallback(any(), any(VcnUserMobileDataStateListener.class));
-    }
-
-    @Test
     public void testMobileDataStateCheckedOnInitialization_enabled() {
         // Validate state from setUp()
         assertTrue(mVcn.isMobileDataEnabled());
@@ -271,24 +263,6 @@
         assertFalse(mVcn.isMobileDataEnabled());
     }
 
-    @Test
-    public void testSubscriptionSnapshotUpdatesMobileDataStateListeners() {
-        final TelephonySubscriptionSnapshot updatedSnapshot =
-                mock(TelephonySubscriptionSnapshot.class);
-
-        doReturn(new ArraySet<>(Arrays.asList(2, 4)))
-                .when(updatedSnapshot)
-                .getAllSubIdsInGroup(any());
-
-        mVcn.updateSubscriptionSnapshot(updatedSnapshot);
-        mTestLooper.dispatchAll();
-
-        verify(mTelephonyManager, times(4))
-                .registerTelephonyCallback(any(), any(VcnUserMobileDataStateListener.class));
-        verify(mTelephonyManager, times(2))
-                .unregisterTelephonyCallback(any(VcnUserMobileDataStateListener.class));
-    }
-
     private void triggerVcnRequestListeners(NetworkRequestListener requestListener) {
         for (final int[] caps : TEST_CAPS) {
             startVcnGatewayWithCapabilities(requestListener, caps);
@@ -428,17 +402,24 @@
         verify(mVcnNetworkProvider).resendAllRequests(requestListener);
     }
 
-    private void setupForMobileDataTest(boolean startingToggleState) {
+    private void verifyMobileDataToggled(boolean startingToggleState, boolean endingToggleState) {
+        final ArgumentCaptor<ContentObserver> captor =
+                ArgumentCaptor.forClass(ContentObserver.class);
+        verify(mContentResolver).registerContentObserver(any(), anyBoolean(), captor.capture());
+        final ContentObserver contentObserver = captor.getValue();
+
         // Start VcnGatewayConnections
         final NetworkRequestListener requestListener = verifyAndGetRequestListener();
         mVcn.setMobileDataEnabled(startingToggleState);
         triggerVcnRequestListeners(requestListener);
-    }
+        final Map<VcnGatewayConnectionConfig, VcnGatewayConnection> gateways =
+                mVcn.getVcnGatewayConnectionConfigMap();
 
-    private void verifyMobileDataToggledUpdatesGatewayConnections(
-            boolean startingToggleState,
-            boolean endingToggleState,
-            Map<VcnGatewayConnectionConfig, VcnGatewayConnection> gateways) {
+        // Trigger data toggle change.
+        doReturn(endingToggleState).when(mTelephonyManager).isDataEnabled();
+        contentObserver.onChange(false /* selfChange, ignored */);
+        mTestLooper.dispatchAll();
+
         // Verify that data toggle changes restart ONLY INTERNET or DUN networks, and only if the
         // toggle state changed.
         for (Entry<VcnGatewayConnectionConfig, VcnGatewayConnection> entry : gateways.entrySet()) {
@@ -452,98 +433,29 @@
             }
         }
 
-        final NetworkRequestListener requestListener = verifyAndGetRequestListener();
         if (startingToggleState != endingToggleState) {
             verify(mVcnNetworkProvider).resendAllRequests(requestListener);
         }
         assertEquals(endingToggleState, mVcn.isMobileDataEnabled());
     }
 
-    private void verifyGlobalMobileDataToggled(
-            boolean startingToggleState, boolean endingToggleState) {
-        setupForMobileDataTest(startingToggleState);
-        final Map<VcnGatewayConnectionConfig, VcnGatewayConnection> gateways =
-                mVcn.getVcnGatewayConnectionConfigMap();
-
-        // Trigger data toggle change
-        final ArgumentCaptor<ContentObserver> captor =
-                ArgumentCaptor.forClass(ContentObserver.class);
-        verify(mContentResolver).registerContentObserver(any(), anyBoolean(), captor.capture());
-        final ContentObserver contentObserver = captor.getValue();
-
-        doReturn(endingToggleState).when(mTelephonyManager).isDataEnabled();
-        contentObserver.onChange(false /* selfChange, ignored */);
-        mTestLooper.dispatchAll();
-
-        // Verify resultant behavior
-        verifyMobileDataToggledUpdatesGatewayConnections(
-                startingToggleState, endingToggleState, gateways);
+    @Test
+    public void testMobileDataEnabled() {
+        verifyMobileDataToggled(false /* startingToggleState */, true /* endingToggleState */);
     }
 
     @Test
-    public void testGlobalMobileDataEnabled() {
-        verifyGlobalMobileDataToggled(
-                false /* startingToggleState */, true /* endingToggleState */);
+    public void testMobileDataDisabled() {
+        verifyMobileDataToggled(true /* startingToggleState */, false /* endingToggleState */);
     }
 
     @Test
-    public void testGlobalMobileDataDisabled() {
-        verifyGlobalMobileDataToggled(
-                true /* startingToggleState */, false /* endingToggleState */);
+    public void testMobileDataObserverFiredWithoutChanges_dataEnabled() {
+        verifyMobileDataToggled(false /* startingToggleState */, false /* endingToggleState */);
     }
 
     @Test
-    public void testGlobalMobileDataObserverFiredWithoutChanges_dataEnabled() {
-        verifyGlobalMobileDataToggled(
-                false /* startingToggleState */, false /* endingToggleState */);
-    }
-
-    @Test
-    public void testGlobalMobileDataObserverFiredWithoutChanges_dataDisabled() {
-        verifyGlobalMobileDataToggled(true /* startingToggleState */, true /* endingToggleState */);
-    }
-
-    private void verifySubscriptionMobileDataToggled(
-            boolean startingToggleState, boolean endingToggleState) {
-        setupForMobileDataTest(startingToggleState);
-        final Map<VcnGatewayConnectionConfig, VcnGatewayConnection> gateways =
-                mVcn.getVcnGatewayConnectionConfigMap();
-
-        // Trigger data toggle change.
-        final ArgumentCaptor<VcnUserMobileDataStateListener> captor =
-                ArgumentCaptor.forClass(VcnUserMobileDataStateListener.class);
-        verify(mTelephonyManager, times(3)).registerTelephonyCallback(any(), captor.capture());
-        final VcnUserMobileDataStateListener listener = captor.getValue();
-
-        doReturn(endingToggleState).when(mTelephonyManager).isDataEnabled();
-        listener.onUserMobileDataStateChanged(false /* enabled, ignored */);
-        mTestLooper.dispatchAll();
-
-        // Verify resultant behavior
-        verifyMobileDataToggledUpdatesGatewayConnections(
-                startingToggleState, endingToggleState, gateways);
-    }
-
-    @Test
-    public void testSubscriptionMobileDataEnabled() {
-        verifyGlobalMobileDataToggled(
-                false /* startingToggleState */, true /* endingToggleState */);
-    }
-
-    @Test
-    public void testSubscriptionMobileDataDisabled() {
-        verifyGlobalMobileDataToggled(
-                true /* startingToggleState */, false /* endingToggleState */);
-    }
-
-    @Test
-    public void testSubscriptionMobileDataListenerFiredWithoutChanges_dataEnabled() {
-        verifyGlobalMobileDataToggled(
-                false /* startingToggleState */, false /* endingToggleState */);
-    }
-
-    @Test
-    public void testSubscriptionMobileDataListenerFiredWithoutChanges_dataDisabled() {
-        verifyGlobalMobileDataToggled(true /* startingToggleState */, true /* endingToggleState */);
+    public void testMobileDataObserverFiredWithoutChanges_dataDisabled() {
+        verifyMobileDataToggled(true /* startingToggleState */, true /* endingToggleState */);
     }
 }
