Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7f409aab authored by Junyu Lai's avatar Junyu Lai Committed by Android (Google) Code Review
Browse files

Merge "Skip RAT type listener registration if IMSI is not available"

parents b09f7770 80a8a630
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -100,11 +100,16 @@ public class NetworkStatsSubscriptionsMonitor extends
            if (match != null) continue;

            // Create listener for every newly added sub. Also store subscriberId into it to
            // prevent binder call to telephony when querying RAT.
            // prevent binder call to telephony when querying RAT. If the subscriberId is empty
            // for any reason, such as SIM PIN locked, skip registration.
            // SubscriberId will be unavailable again if 1. modem crashed 2. reboot
            // 3. re-insert SIM. If that happens, the listeners will be eventually synchronized
            // with active sub list once all subscriberIds are ready.
            final String subscriberId = mTeleManager.getSubscriberId(subId);
            if (TextUtils.isEmpty(subscriberId)) {
                Log.wtf(NetworkStatsService.TAG,
                        "Empty subscriberId for newly added sub: " + subId);
                Log.d(NetworkStatsService.TAG, "Empty subscriberId for newly added sub "
                        + subId + ", skip listener registration");
                continue;
            }
            final RatTypeListener listener =
                    new RatTypeListener(mExecutor, this, subId, subscriberId);
@@ -113,6 +118,7 @@ public class NetworkStatsSubscriptionsMonitor extends
            // Register listener to the telephony manager that associated with specific sub.
            mTeleManager.createForSubscriptionId(subId)
                    .listen(listener, PhoneStateListener.LISTEN_SERVICE_STATE);
            Log.d(NetworkStatsService.TAG, "RAT type listener registered for sub " + subId);
        }

        for (final RatTypeListener listener : new ArrayList<>(mRatListeners)) {
@@ -165,6 +171,7 @@ public class NetworkStatsSubscriptionsMonitor extends
    private void handleRemoveRatTypeListener(@NonNull RatTypeListener listener) {
        mTeleManager.createForSubscriptionId(listener.mSubId)
                .listen(listener, PhoneStateListener.LISTEN_NONE);
        Log.d(NetworkStatsService.TAG, "RAT type listener unregistered for sub " + listener.mSubId);
        mRatListeners.remove(listener);

        // Removal of subscriptions doesn't generate RAT changed event, fire it for every
+56 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.net.NetworkTemplate;
import android.os.test.TestLooper;
@@ -135,6 +136,11 @@ public final class NetworkStatsSubscriptionsMonitorTest {
        mMonitor.onSubscriptionsChanged();
    }

    private void updateSubscriberIdForTestSub(int subId, @Nullable final String subscriberId) {
        when(mTelephonyManager.getSubscriberId(subId)).thenReturn(subscriberId);
        mMonitor.onSubscriptionsChanged();
    }

    private void removeTestSub(int subId) {
        // Remove subId from TestSubList.
        mTestSubList.removeIf(it -> it == subId);
@@ -268,4 +274,54 @@ public final class NetworkStatsSubscriptionsMonitorTest {
        listener.onServiceStateChanged(serviceState);
        assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_NR);
    }

    @Test
    public void testSubscriberIdUnavailable() {
        final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor =
                ArgumentCaptor.forClass(RatTypeListener.class);

        mMonitor.start();
        // Insert sim1, set subscriberId to null which is normal in SIM PIN locked case.
        // Verify RAT type is NETWORK_TYPE_UNKNOWN and service will not perform listener
        // registration.
        addTestSub(TEST_SUBID1, null);
        verify(mTelephonyManager, never()).listen(any(), anyInt());
        assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN);

        // Set IMSI for sim1, verify the listener will be registered.
        updateSubscriberIdForTestSub(TEST_SUBID1, TEST_IMSI1);
        verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor.capture(),
                eq(PhoneStateListener.LISTEN_SERVICE_STATE));
        reset(mTelephonyManager);
        when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);

        // Set RAT type of sim1 to UMTS. Verify RAT type of sim1 is changed.
        setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1,
                TelephonyManager.NETWORK_TYPE_UMTS);
        assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS);
        reset(mDelegate);

        // Set IMSI to null again to simulate somehow IMSI is not available, such as
        // modem crash. Verify service should not unregister listener.
        updateSubscriberIdForTestSub(TEST_SUBID1, null);
        verify(mTelephonyManager, never()).listen(any(), anyInt());
        assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS);
        reset(mDelegate);

        // Set RAT type of sim1 to LTE. Verify RAT type of sim1 is still changed even if the IMSI
        // is not available. The monitor keeps the listener even if the IMSI disappears because
        // the IMSI can never change for any given subId, therefore even if the IMSI is updated
        // to null, the monitor should continue accepting updates of the RAT type. However,
        // telephony is never actually supposed to do this, if the IMSI disappears there should
        // not be updates, but it's still the right thing to do theoretically.
        setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1,
                TelephonyManager.NETWORK_TYPE_LTE);
        assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_LTE);
        reset(mDelegate);

        mMonitor.stop();
        verify(mTelephonyManager, times(1)).listen(eq(ratTypeListenerCaptor.getValue()),
                eq(PhoneStateListener.LISTEN_NONE));
        assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN);
    }
}