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

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

Merge "[SM10] Adopt helper class to monitor RAT type change per sub"

parents c522d895 219faff0
Loading
Loading
Loading
Loading
+37 −49
Original line number Diff line number Diff line
@@ -46,7 +46,6 @@ import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStatsHistory.FIELD_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
import static android.net.NetworkTemplate.getCollapsedRatType;
import static android.net.TrafficStats.KB_IN_BYTES;
import static android.net.TrafficStats.MB_IN_BYTES;
import static android.os.Trace.TRACE_TAG_NETWORK;
@@ -67,9 +66,6 @@ import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
import static android.telephony.PhoneStateListener.LISTEN_NONE;
import static android.telephony.PhoneStateListener.LISTEN_SERVICE_STATE;
import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
@@ -133,9 +129,7 @@ import android.provider.Settings.Global;
import android.service.NetworkInterfaceProto;
import android.service.NetworkStatsServiceDumpProto;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SubscriptionPlan;
import android.telephony.TelephonyManager;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -206,7 +200,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
    private final NetworkStatsFactory mStatsFactory;
    private final AlarmManager mAlarmManager;
    private final Clock mClock;
    private final TelephonyManager mTeleManager;
    private final NetworkStatsSettings mSettings;
    private final NetworkStatsObservers mStatsObservers;

@@ -352,6 +345,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
    @NonNull
    private final Dependencies mDeps;

    @NonNull
    private final NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;

    private static @NonNull File getDefaultSystemDir() {
        return new File(Environment.getDataDirectory(), "system");
    }
@@ -401,8 +397,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
        PowerManager.WakeLock wakeLock =
                powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);

        NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
                wakeLock, getDefaultClock(), context.getSystemService(TelephonyManager.class),
        final NetworkStatsService service = new NetworkStatsService(context, networkManager,
                alarmManager, wakeLock, getDefaultClock(),
                new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(),
                new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir(),
                new Dependencies());
@@ -416,16 +412,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
    @VisibleForTesting
    NetworkStatsService(Context context, INetworkManagementService networkManager,
            AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
            TelephonyManager teleManager, NetworkStatsSettings settings,
            NetworkStatsFactory factory, NetworkStatsObservers statsObservers, File systemDir,
            File baseDir, @NonNull Dependencies deps) {
            NetworkStatsSettings settings, NetworkStatsFactory factory,
            NetworkStatsObservers statsObservers, File systemDir, File baseDir,
            @NonNull Dependencies deps) {
        mContext = Objects.requireNonNull(context, "missing Context");
        mNetworkManager = Objects.requireNonNull(networkManager,
                "missing INetworkManagementService");
        mAlarmManager = Objects.requireNonNull(alarmManager, "missing AlarmManager");
        mClock = Objects.requireNonNull(clock, "missing Clock");
        mSettings = Objects.requireNonNull(settings, "missing NetworkStatsSettings");
        mTeleManager = Objects.requireNonNull(teleManager, "missing TelephonyManager");
        mWakeLock = Objects.requireNonNull(wakeLock, "missing WakeLock");
        mStatsFactory = Objects.requireNonNull(factory, "missing factory");
        mStatsObservers = Objects.requireNonNull(statsObservers, "missing NetworkStatsObservers");
@@ -437,7 +432,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
        final HandlerThread handlerThread = mDeps.makeHandlerThread();
        handlerThread.start();
        mHandler = new NetworkStatsHandler(handlerThread.getLooper());
        mPhoneListener = new NetworkTypeListener(new HandlerExecutor(mHandler));
        mNetworkStatsSubscriptionsMonitor = deps.makeSubscriptionsMonitor(mContext,
                new HandlerExecutor(mHandler), this);
    }

    /**
@@ -453,6 +449,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
        public HandlerThread makeHandlerThread() {
            return new HandlerThread(TAG);
        }

        /**
         * Create a {@link NetworkStatsSubscriptionsMonitor}, can be used to monitor RAT change
         * event in NetworkStatsService.
         */
        @NonNull
        public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor(@NonNull Context context,
                @NonNull Executor executor, @NonNull NetworkStatsService service) {
            // TODO: Update RatType passively in NSS, instead of querying into the monitor
            //  when forceUpdateIface.
            return new NetworkStatsSubscriptionsMonitor(context, executor, (subscriberId, type) ->
                    service.handleOnCollapsedRatTypeChanged());
        }
    }

    private void registerLocalService() {
@@ -517,11 +526,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
        mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
                mSettings.getPollInterval(), pollIntent);

        // TODO: 1. listen to changes from all subscriptions.
        //       2. listen to settings changed to support dynamically enable/disable.
        // TODO: listen to settings changed to support dynamically enable/disable.
        // watch for networkType changes
        if (!mSettings.getCombineSubtypeEnabled()) {
            mTeleManager.listen(mPhoneListener, LISTEN_SERVICE_STATE);
            mNetworkStatsSubscriptionsMonitor.start();
        }

        registerGlobalAlert();
@@ -544,7 +552,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
        mContext.unregisterReceiver(mUserReceiver);
        mContext.unregisterReceiver(mShutdownReceiver);

        mTeleManager.listen(mPhoneListener, LISTEN_NONE);
        if (!mSettings.getCombineSubtypeEnabled()) {
            mNetworkStatsSubscriptionsMonitor.stop();
        }

        final long currentTime = mClock.millis();

@@ -1197,36 +1207,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
    };

    /**
     * Receiver that watches for {@link TelephonyManager} changes, such as
     * transitioning between Radio Access Technology(RAT) types.
     * Handle collapsed RAT type changed event.
     */
    @NonNull
    private final NetworkTypeListener mPhoneListener;

    class NetworkTypeListener extends PhoneStateListener {
        private volatile int mLastCollapsedRatType = NETWORK_TYPE_UNKNOWN;

        NetworkTypeListener(@NonNull Executor executor) {
            super(executor);
        }

        @Override
        public void onServiceStateChanged(@NonNull ServiceState ss) {
            final int networkType = ss.getDataNetworkType();
            final int collapsedRatType = getCollapsedRatType(networkType);
            if (collapsedRatType == mLastCollapsedRatType) return;

            if (LOGD) {
                Log.d(TAG, "subtype changed for mobile: "
                        + mLastCollapsedRatType + " -> " + collapsedRatType);
            }
    @VisibleForTesting
    public void handleOnCollapsedRatTypeChanged() {
        // Protect service from frequently updating. Remove pending messages if any.
        mHandler.removeMessages(MSG_UPDATE_IFACES);
            mLastCollapsedRatType = collapsedRatType;
        mHandler.sendMessageDelayed(
                mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay());
    }
    }

    private void updateIfaces(
            Network[] defaultNetworks,
@@ -1352,8 +1341,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
            return 0;
        }

        // TODO: return different subType for different subscriptions.
        return mPhoneListener.mLastCollapsedRatType;
        return mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(state.subscriberId);
    }

    private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
+17 −19
Original line number Diff line number Diff line
@@ -60,14 +60,13 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AlarmManager;
import android.app.usage.NetworkStatsManager;
import android.content.Context;
@@ -95,8 +94,6 @@ import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
import android.os.SimpleClock;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;

import androidx.test.InstrumentationRegistry;
@@ -126,6 +123,7 @@ import java.io.File;
import java.time.Clock;
import java.time.ZoneOffset;
import java.util.Objects;
import java.util.concurrent.Executor;

/**
 * Tests for {@link NetworkStatsService}.
@@ -168,14 +166,13 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
    private @Mock NetworkStatsSettings mSettings;
    private @Mock IBinder mBinder;
    private @Mock AlarmManager mAlarmManager;
    private @Mock TelephonyManager mTelephonyManager;
    @Mock
    private NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
    private HandlerThread mHandlerThread;

    private NetworkStatsService mService;
    private INetworkStatsSession mSession;
    private INetworkManagementEventObserver mNetworkObserver;
    @Nullable
    private PhoneStateListener mPhoneStateListener;

    private final Clock mClock = new SimpleClock(ZoneOffset.UTC) {
        @Override
@@ -203,8 +200,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
        mHandlerThread = new HandlerThread("HandlerThread");
        final NetworkStatsService.Dependencies deps = makeDependencies();
        mService = new NetworkStatsService(mServiceContext, mNetManager, mAlarmManager, wakeLock,
                mClock, mTelephonyManager, mSettings,
                mStatsFactory, new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir), deps);
                mClock, mSettings, mStatsFactory, new NetworkStatsObservers(), mStatsDir,
                getBaseDir(mStatsDir), deps);

        mElapsedRealtime = 0L;

@@ -224,12 +221,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
                ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
        verify(mNetManager).registerObserver(networkObserver.capture());
        mNetworkObserver = networkObserver.getValue();

        // Capture the phone state listener that created by service.
        final ArgumentCaptor<PhoneStateListener> phoneStateListenerCaptor =
                ArgumentCaptor.forClass(PhoneStateListener.class);
        verify(mTelephonyManager).listen(phoneStateListenerCaptor.capture(), anyInt());
        mPhoneStateListener = phoneStateListenerCaptor.getValue();
    }

    @NonNull
@@ -239,6 +230,14 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
            public HandlerThread makeHandlerThread() {
                return mHandlerThread;
            }

            @Override
            public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor(
                    @NonNull Context context, @NonNull Executor executor,
                    @NonNull NetworkStatsService service) {

                return mNetworkStatsSubscriptionsMonitor;
            }
        };
    }

@@ -678,10 +677,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {

    // TODO: support per IMSI state
    private void setMobileRatTypeAndWaitForIdle(int ratType) {
        final ServiceState mockSs = mock(ServiceState.class);
        when(mockSs.getDataNetworkType()).thenReturn(ratType);
        mPhoneStateListener.onServiceStateChanged(mockSs);

        when(mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(anyString()))
                .thenReturn(ratType);
        mService.handleOnCollapsedRatTypeChanged();
        HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
    }